blob: 7514820721e0406a0d375cee68d6c1e6c836e0ed [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>
51
52#include "vat/json_format.h"
53
54#include <inttypes.h>
55#include <sys/stat.h>
56
57#define vl_typedefs /* define message structures */
58#include <vpp/api/vpe_all_api_h.h>
59#undef vl_typedefs
60
61/* declare message handlers for each api */
62
63#define vl_endianfun /* define message structures */
64#include <vpp/api/vpe_all_api_h.h>
65#undef vl_endianfun
66
67/* instantiate all the print functions we know about */
68#define vl_print(handle, ...)
69#define vl_printfun
70#include <vpp/api/vpe_all_api_h.h>
71#undef vl_printfun
72
73static uword
74api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
75{
76 vat_main_t *vam = va_arg (*args, vat_main_t *);
77 u32 *result = va_arg (*args, u32 *);
78 u8 *if_name;
79 uword *p;
80
81 if (!unformat (input, "%s", &if_name))
82 return 0;
83
84 p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85 if (p == 0)
86 return 0;
87 *result = p[0];
88 return 1;
89}
90
91void vat_suspend (vlib_main_t * vm, f64 interval);
92
93#if VPP_API_TEST_BUILTIN == 0
94/* Parse an IP4 address %d.%d.%d.%d. */
95uword
96unformat_ip4_address (unformat_input_t * input, va_list * args)
97{
98 u8 *result = va_arg (*args, u8 *);
99 unsigned a[4];
100
101 if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
102 return 0;
103
104 if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
105 return 0;
106
107 result[0] = a[0];
108 result[1] = a[1];
109 result[2] = a[2];
110 result[3] = a[3];
111
112 return 1;
113}
114
115uword
116unformat_ethernet_address (unformat_input_t * input, va_list * args)
117{
118 u8 *result = va_arg (*args, u8 *);
119 u32 i, a[6];
120
121 if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
122 &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
123 return 0;
124
125 /* Check range. */
126 for (i = 0; i < 6; i++)
127 if (a[i] >= (1 << 8))
128 return 0;
129
130 for (i = 0; i < 6; i++)
131 result[i] = a[i];
132
133 return 1;
134}
135
136/* Returns ethernet type as an int in host byte order. */
137uword
138unformat_ethernet_type_host_byte_order (unformat_input_t * input,
139 va_list * args)
140{
141 u16 *result = va_arg (*args, u16 *);
142 int type;
143
144 /* Numeric type. */
145 if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
146 {
147 if (type >= (1 << 16))
148 return 0;
149 *result = type;
150 return 1;
151 }
152 return 0;
153}
154
155/* Parse an IP6 address. */
156uword
157unformat_ip6_address (unformat_input_t * input, va_list * args)
158{
159 ip6_address_t *result = va_arg (*args, ip6_address_t *);
160 u16 hex_quads[8];
161 uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
162 uword c, n_colon, double_colon_index;
163
164 n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
165 double_colon_index = ARRAY_LEN (hex_quads);
166 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
167 {
168 hex_digit = 16;
169 if (c >= '0' && c <= '9')
170 hex_digit = c - '0';
171 else if (c >= 'a' && c <= 'f')
172 hex_digit = c + 10 - 'a';
173 else if (c >= 'A' && c <= 'F')
174 hex_digit = c + 10 - 'A';
175 else if (c == ':' && n_colon < 2)
176 n_colon++;
177 else
178 {
179 unformat_put_input (input);
180 break;
181 }
182
183 /* Too many hex quads. */
184 if (n_hex_quads >= ARRAY_LEN (hex_quads))
185 return 0;
186
187 if (hex_digit < 16)
188 {
189 hex_quad = (hex_quad << 4) | hex_digit;
190
191 /* Hex quad must fit in 16 bits. */
192 if (n_hex_digits >= 4)
193 return 0;
194
195 n_colon = 0;
196 n_hex_digits++;
197 }
198
199 /* Save position of :: */
200 if (n_colon == 2)
201 {
202 /* More than one :: ? */
203 if (double_colon_index < ARRAY_LEN (hex_quads))
204 return 0;
205 double_colon_index = n_hex_quads;
206 }
207
208 if (n_colon > 0 && n_hex_digits > 0)
209 {
210 hex_quads[n_hex_quads++] = hex_quad;
211 hex_quad = 0;
212 n_hex_digits = 0;
213 }
214 }
215
216 if (n_hex_digits > 0)
217 hex_quads[n_hex_quads++] = hex_quad;
218
219 {
220 word i;
221
222 /* Expand :: to appropriate number of zero hex quads. */
223 if (double_colon_index < ARRAY_LEN (hex_quads))
224 {
225 word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
226
227 for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
228 hex_quads[n_zero + i] = hex_quads[i];
229
230 for (i = 0; i < n_zero; i++)
231 hex_quads[double_colon_index + i] = 0;
232
233 n_hex_quads = ARRAY_LEN (hex_quads);
234 }
235
236 /* Too few hex quads given. */
237 if (n_hex_quads < ARRAY_LEN (hex_quads))
238 return 0;
239
240 for (i = 0; i < ARRAY_LEN (hex_quads); i++)
241 result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
242
243 return 1;
244 }
245}
246
247uword
248unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
249{
250 u32 *r = va_arg (*args, u32 *);
251
252 if (0);
253#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
254 foreach_ipsec_policy_action
255#undef _
256 else
257 return 0;
258 return 1;
259}
260
261uword
262unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
263{
264 u32 *r = va_arg (*args, u32 *);
265
266 if (0);
267#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
268 foreach_ipsec_crypto_alg
269#undef _
270 else
271 return 0;
272 return 1;
273}
274
275u8 *
276format_ipsec_crypto_alg (u8 * s, va_list * args)
277{
278 u32 i = va_arg (*args, u32);
279 u8 *t = 0;
280
281 switch (i)
282 {
283#define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
284 foreach_ipsec_crypto_alg
285#undef _
286 default:
287 return format (s, "unknown");
288 }
289 return format (s, "%s", t);
290}
291
292uword
293unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
294{
295 u32 *r = va_arg (*args, u32 *);
296
297 if (0);
298#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
299 foreach_ipsec_integ_alg
300#undef _
301 else
302 return 0;
303 return 1;
304}
305
306u8 *
307format_ipsec_integ_alg (u8 * s, va_list * args)
308{
309 u32 i = va_arg (*args, u32);
310 u8 *t = 0;
311
312 switch (i)
313 {
314#define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
315 foreach_ipsec_integ_alg
316#undef _
317 default:
318 return format (s, "unknown");
319 }
320 return format (s, "%s", t);
321}
322
323uword
324unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
325{
326 u32 *r = va_arg (*args, u32 *);
327
328 if (0);
329#define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
330 foreach_ikev2_auth_method
331#undef _
332 else
333 return 0;
334 return 1;
335}
336
337uword
338unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
339{
340 u32 *r = va_arg (*args, u32 *);
341
342 if (0);
343#define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
344 foreach_ikev2_id_type
345#undef _
346 else
347 return 0;
348 return 1;
349}
350#endif /* VPP_API_TEST_BUILTIN */
351
352static uword
353unformat_policer_rate_type (unformat_input_t * input, va_list * args)
354{
355 u8 *r = va_arg (*args, u8 *);
356
357 if (unformat (input, "kbps"))
358 *r = SSE2_QOS_RATE_KBPS;
359 else if (unformat (input, "pps"))
360 *r = SSE2_QOS_RATE_PPS;
361 else
362 return 0;
363 return 1;
364}
365
366static uword
367unformat_policer_round_type (unformat_input_t * input, va_list * args)
368{
369 u8 *r = va_arg (*args, u8 *);
370
371 if (unformat (input, "closest"))
372 *r = SSE2_QOS_ROUND_TO_CLOSEST;
373 else if (unformat (input, "up"))
374 *r = SSE2_QOS_ROUND_TO_UP;
375 else if (unformat (input, "down"))
376 *r = SSE2_QOS_ROUND_TO_DOWN;
377 else
378 return 0;
379 return 1;
380}
381
382static uword
383unformat_policer_type (unformat_input_t * input, va_list * args)
384{
385 u8 *r = va_arg (*args, u8 *);
386
387 if (unformat (input, "1r2c"))
388 *r = SSE2_QOS_POLICER_TYPE_1R2C;
389 else if (unformat (input, "1r3c"))
390 *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
391 else if (unformat (input, "2r3c-2698"))
392 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
393 else if (unformat (input, "2r3c-4115"))
394 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
395 else if (unformat (input, "2r3c-mef5cf1"))
396 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
397 else
398 return 0;
399 return 1;
400}
401
402static uword
403unformat_dscp (unformat_input_t * input, va_list * va)
404{
405 u8 *r = va_arg (*va, u8 *);
406
407 if (0);
408#define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
409 foreach_vnet_dscp
410#undef _
411 else
412 return 0;
413 return 1;
414}
415
416static uword
417unformat_policer_action_type (unformat_input_t * input, va_list * va)
418{
419 sse2_qos_pol_action_params_st *a
420 = va_arg (*va, sse2_qos_pol_action_params_st *);
421
422 if (unformat (input, "drop"))
423 a->action_type = SSE2_QOS_ACTION_DROP;
424 else if (unformat (input, "transmit"))
425 a->action_type = SSE2_QOS_ACTION_TRANSMIT;
426 else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
427 a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
428 else
429 return 0;
430 return 1;
431}
432
433static uword
434unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
435{
436 u32 *r = va_arg (*va, u32 *);
437 u32 tid;
438
439 if (unformat (input, "ip4"))
440 tid = POLICER_CLASSIFY_TABLE_IP4;
441 else if (unformat (input, "ip6"))
442 tid = POLICER_CLASSIFY_TABLE_IP6;
443 else if (unformat (input, "l2"))
444 tid = POLICER_CLASSIFY_TABLE_L2;
445 else
446 return 0;
447
448 *r = tid;
449 return 1;
450}
451
452static uword
453unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
454{
455 u32 *r = va_arg (*va, u32 *);
456 u32 tid;
457
458 if (unformat (input, "ip4"))
459 tid = FLOW_CLASSIFY_TABLE_IP4;
460 else if (unformat (input, "ip6"))
461 tid = FLOW_CLASSIFY_TABLE_IP6;
462 else
463 return 0;
464
465 *r = tid;
466 return 1;
467}
468
469#if (VPP_API_TEST_BUILTIN==0)
470u8 *
471format_ip4_address (u8 * s, va_list * args)
472{
473 u8 *a = va_arg (*args, u8 *);
474 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
475}
476
477u8 *
478format_ip6_address (u8 * s, va_list * args)
479{
480 ip6_address_t *a = va_arg (*args, ip6_address_t *);
481 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
482
483 i_max_n_zero = ARRAY_LEN (a->as_u16);
484 max_n_zeros = 0;
485 i_first_zero = i_max_n_zero;
486 n_zeros = 0;
487 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
488 {
489 u32 is_zero = a->as_u16[i] == 0;
490 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
491 {
492 i_first_zero = i;
493 n_zeros = 0;
494 }
495 n_zeros += is_zero;
496 if ((!is_zero && n_zeros > max_n_zeros)
497 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
498 {
499 i_max_n_zero = i_first_zero;
500 max_n_zeros = n_zeros;
501 i_first_zero = ARRAY_LEN (a->as_u16);
502 n_zeros = 0;
503 }
504 }
505
506 last_double_colon = 0;
507 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
508 {
509 if (i == i_max_n_zero && max_n_zeros > 1)
510 {
511 s = format (s, "::");
512 i += max_n_zeros - 1;
513 last_double_colon = 1;
514 }
515 else
516 {
517 s = format (s, "%s%x",
518 (last_double_colon || i == 0) ? "" : ":",
519 clib_net_to_host_u16 (a->as_u16[i]));
520 last_double_colon = 0;
521 }
522 }
523
524 return s;
525}
526
527/* Format an IP46 address. */
528u8 *
529format_ip46_address (u8 * s, va_list * args)
530{
531 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
532 ip46_type_t type = va_arg (*args, ip46_type_t);
533 int is_ip4 = 1;
534
535 switch (type)
536 {
537 case IP46_TYPE_ANY:
538 is_ip4 = ip46_address_is_ip4 (ip46);
539 break;
540 case IP46_TYPE_IP4:
541 is_ip4 = 1;
542 break;
543 case IP46_TYPE_IP6:
544 is_ip4 = 0;
545 break;
546 }
547
548 return is_ip4 ?
549 format (s, "%U", format_ip4_address, &ip46->ip4) :
550 format (s, "%U", format_ip6_address, &ip46->ip6);
551}
552
553u8 *
554format_ethernet_address (u8 * s, va_list * args)
555{
556 u8 *a = va_arg (*args, u8 *);
557
558 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
559 a[0], a[1], a[2], a[3], a[4], a[5]);
560}
561#endif
562
563static void
564increment_v4_address (ip4_address_t * a)
565{
566 u32 v;
567
568 v = ntohl (a->as_u32) + 1;
569 a->as_u32 = ntohl (v);
570}
571
572static void
573increment_v6_address (ip6_address_t * a)
574{
575 u64 v0, v1;
576
577 v0 = clib_net_to_host_u64 (a->as_u64[0]);
578 v1 = clib_net_to_host_u64 (a->as_u64[1]);
579
580 v1 += 1;
581 if (v1 == 0)
582 v0 += 1;
583 a->as_u64[0] = clib_net_to_host_u64 (v0);
584 a->as_u64[1] = clib_net_to_host_u64 (v1);
585}
586
587static void
588increment_mac_address (u64 * mac)
589{
590 u64 tmp = *mac;
591
592 tmp = clib_net_to_host_u64 (tmp);
593 tmp += 1 << 16; /* skip unused (least significant) octets */
594 tmp = clib_host_to_net_u64 (tmp);
595 *mac = tmp;
596}
597
598static void vl_api_create_loopback_reply_t_handler
599 (vl_api_create_loopback_reply_t * mp)
600{
601 vat_main_t *vam = &vat_main;
602 i32 retval = ntohl (mp->retval);
603
604 vam->retval = retval;
605 vam->regenerate_interface_table = 1;
606 vam->sw_if_index = ntohl (mp->sw_if_index);
607 vam->result_ready = 1;
608}
609
610static void vl_api_create_loopback_reply_t_handler_json
611 (vl_api_create_loopback_reply_t * mp)
612{
613 vat_main_t *vam = &vat_main;
614 vat_json_node_t node;
615
616 vat_json_init_object (&node);
617 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
618 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
619
620 vat_json_print (vam->ofp, &node);
621 vat_json_free (&node);
622 vam->retval = ntohl (mp->retval);
623 vam->result_ready = 1;
624}
625
626static void vl_api_af_packet_create_reply_t_handler
627 (vl_api_af_packet_create_reply_t * mp)
628{
629 vat_main_t *vam = &vat_main;
630 i32 retval = ntohl (mp->retval);
631
632 vam->retval = retval;
633 vam->regenerate_interface_table = 1;
634 vam->sw_if_index = ntohl (mp->sw_if_index);
635 vam->result_ready = 1;
636}
637
638static void vl_api_af_packet_create_reply_t_handler_json
639 (vl_api_af_packet_create_reply_t * mp)
640{
641 vat_main_t *vam = &vat_main;
642 vat_json_node_t node;
643
644 vat_json_init_object (&node);
645 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
646 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
647
648 vat_json_print (vam->ofp, &node);
649 vat_json_free (&node);
650
651 vam->retval = ntohl (mp->retval);
652 vam->result_ready = 1;
653}
654
655static void vl_api_create_vlan_subif_reply_t_handler
656 (vl_api_create_vlan_subif_reply_t * mp)
657{
658 vat_main_t *vam = &vat_main;
659 i32 retval = ntohl (mp->retval);
660
661 vam->retval = retval;
662 vam->regenerate_interface_table = 1;
663 vam->sw_if_index = ntohl (mp->sw_if_index);
664 vam->result_ready = 1;
665}
666
667static void vl_api_create_vlan_subif_reply_t_handler_json
668 (vl_api_create_vlan_subif_reply_t * mp)
669{
670 vat_main_t *vam = &vat_main;
671 vat_json_node_t node;
672
673 vat_json_init_object (&node);
674 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
675 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
676
677 vat_json_print (vam->ofp, &node);
678 vat_json_free (&node);
679
680 vam->retval = ntohl (mp->retval);
681 vam->result_ready = 1;
682}
683
684static void vl_api_create_subif_reply_t_handler
685 (vl_api_create_subif_reply_t * mp)
686{
687 vat_main_t *vam = &vat_main;
688 i32 retval = ntohl (mp->retval);
689
690 vam->retval = retval;
691 vam->regenerate_interface_table = 1;
692 vam->sw_if_index = ntohl (mp->sw_if_index);
693 vam->result_ready = 1;
694}
695
696static void vl_api_create_subif_reply_t_handler_json
697 (vl_api_create_subif_reply_t * mp)
698{
699 vat_main_t *vam = &vat_main;
700 vat_json_node_t node;
701
702 vat_json_init_object (&node);
703 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
704 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
705
706 vat_json_print (vam->ofp, &node);
707 vat_json_free (&node);
708
709 vam->retval = ntohl (mp->retval);
710 vam->result_ready = 1;
711}
712
713static void vl_api_interface_name_renumber_reply_t_handler
714 (vl_api_interface_name_renumber_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->result_ready = 1;
722}
723
724static void vl_api_interface_name_renumber_reply_t_handler_json
725 (vl_api_interface_name_renumber_reply_t * mp)
726{
727 vat_main_t *vam = &vat_main;
728 vat_json_node_t node;
729
730 vat_json_init_object (&node);
731 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
732
733 vat_json_print (vam->ofp, &node);
734 vat_json_free (&node);
735
736 vam->retval = ntohl (mp->retval);
737 vam->result_ready = 1;
738}
739
740/*
741 * Special-case: build the interface table, maintain
742 * the next loopback sw_if_index vbl.
743 */
744static void vl_api_sw_interface_details_t_handler
745 (vl_api_sw_interface_details_t * mp)
746{
747 vat_main_t *vam = &vat_main;
748 u8 *s = format (0, "%s%c", mp->interface_name, 0);
749
750 hash_set_mem (vam->sw_if_index_by_interface_name, s,
751 ntohl (mp->sw_if_index));
752
753 /* In sub interface case, fill the sub interface table entry */
754 if (mp->sw_if_index != mp->sup_sw_if_index)
755 {
756 sw_interface_subif_t *sub = NULL;
757
758 vec_add2 (vam->sw_if_subif_table, sub, 1);
759
760 vec_validate (sub->interface_name, strlen ((char *) s) + 1);
761 strncpy ((char *) sub->interface_name, (char *) s,
762 vec_len (sub->interface_name));
763 sub->sw_if_index = ntohl (mp->sw_if_index);
764 sub->sub_id = ntohl (mp->sub_id);
765
766 sub->sub_dot1ad = mp->sub_dot1ad;
767 sub->sub_number_of_tags = mp->sub_number_of_tags;
768 sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
769 sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
770 sub->sub_exact_match = mp->sub_exact_match;
771 sub->sub_default = mp->sub_default;
772 sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
773 sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
774
775 /* vlan tag rewrite */
776 sub->vtr_op = ntohl (mp->vtr_op);
777 sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
778 sub->vtr_tag1 = ntohl (mp->vtr_tag1);
779 sub->vtr_tag2 = ntohl (mp->vtr_tag2);
780 }
781}
782
783static void vl_api_sw_interface_details_t_handler_json
784 (vl_api_sw_interface_details_t * mp)
785{
786 vat_main_t *vam = &vat_main;
787 vat_json_node_t *node = NULL;
788
789 if (VAT_JSON_ARRAY != vam->json_tree.type)
790 {
791 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
792 vat_json_init_array (&vam->json_tree);
793 }
794 node = vat_json_array_add (&vam->json_tree);
795
796 vat_json_init_object (node);
797 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
798 vat_json_object_add_uint (node, "sup_sw_if_index",
799 ntohl (mp->sup_sw_if_index));
800 vat_json_object_add_uint (node, "l2_address_length",
801 ntohl (mp->l2_address_length));
802 vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
803 sizeof (mp->l2_address));
804 vat_json_object_add_string_copy (node, "interface_name",
805 mp->interface_name);
806 vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
807 vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
808 vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
809 vat_json_object_add_uint (node, "link_speed", mp->link_speed);
810 vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
811 vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
812 vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
813 vat_json_object_add_uint (node, "sub_number_of_tags",
814 mp->sub_number_of_tags);
815 vat_json_object_add_uint (node, "sub_outer_vlan_id",
816 ntohs (mp->sub_outer_vlan_id));
817 vat_json_object_add_uint (node, "sub_inner_vlan_id",
818 ntohs (mp->sub_inner_vlan_id));
819 vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
820 vat_json_object_add_uint (node, "sub_default", mp->sub_default);
821 vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
822 mp->sub_outer_vlan_id_any);
823 vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
824 mp->sub_inner_vlan_id_any);
825 vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
826 vat_json_object_add_uint (node, "vtr_push_dot1q",
827 ntohl (mp->vtr_push_dot1q));
828 vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
829 vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
830}
831
832static void vl_api_sw_interface_set_flags_t_handler
833 (vl_api_sw_interface_set_flags_t * mp)
834{
835 vat_main_t *vam = &vat_main;
836 if (vam->interface_event_display)
837 errmsg ("interface flags: sw_if_index %d %s %s",
838 ntohl (mp->sw_if_index),
839 mp->admin_up_down ? "admin-up" : "admin-down",
840 mp->link_up_down ? "link-up" : "link-down");
841}
842
843static void vl_api_sw_interface_set_flags_t_handler_json
844 (vl_api_sw_interface_set_flags_t * mp)
845{
846 /* JSON output not supported */
847}
848
849static void
850vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
851{
852 vat_main_t *vam = &vat_main;
853 i32 retval = ntohl (mp->retval);
854
855 vam->retval = retval;
856 vam->shmem_result = (u8 *) mp->reply_in_shmem;
857 vam->result_ready = 1;
858}
859
860static void
861vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
862{
863 vat_main_t *vam = &vat_main;
864 vat_json_node_t node;
865 api_main_t *am = &api_main;
866 void *oldheap;
867 u8 *reply;
868
869 vat_json_init_object (&node);
870 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
871 vat_json_object_add_uint (&node, "reply_in_shmem",
872 ntohl (mp->reply_in_shmem));
873 /* Toss the shared-memory original... */
874 pthread_mutex_lock (&am->vlib_rp->mutex);
875 oldheap = svm_push_data_heap (am->vlib_rp);
876
877 reply = (u8 *) (mp->reply_in_shmem);
878 vec_free (reply);
879
880 svm_pop_heap (oldheap);
881 pthread_mutex_unlock (&am->vlib_rp->mutex);
882
883 vat_json_print (vam->ofp, &node);
884 vat_json_free (&node);
885
886 vam->retval = ntohl (mp->retval);
887 vam->result_ready = 1;
888}
889
890static void
891vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
892{
893 vat_main_t *vam = &vat_main;
894 i32 retval = ntohl (mp->retval);
895
896 vam->retval = retval;
897 vam->cmd_reply = mp->reply;
898 vam->result_ready = 1;
899}
900
901static void
902vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
903{
904 vat_main_t *vam = &vat_main;
905 vat_json_node_t node;
906
907 vat_json_init_object (&node);
908 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
909 vat_json_object_add_string_copy (&node, "reply", mp->reply);
910
911 vat_json_print (vam->ofp, &node);
912 vat_json_free (&node);
913
914 vam->retval = ntohl (mp->retval);
915 vam->result_ready = 1;
916}
917
918static void vl_api_classify_add_del_table_reply_t_handler
919 (vl_api_classify_add_del_table_reply_t * mp)
920{
921 vat_main_t *vam = &vat_main;
922 i32 retval = ntohl (mp->retval);
923 if (vam->async_mode)
924 {
925 vam->async_errors += (retval < 0);
926 }
927 else
928 {
929 vam->retval = retval;
930 if (retval == 0 &&
931 ((mp->new_table_index != 0xFFFFFFFF) ||
932 (mp->skip_n_vectors != 0xFFFFFFFF) ||
933 (mp->match_n_vectors != 0xFFFFFFFF)))
934 /*
935 * Note: this is just barely thread-safe, depends on
936 * the main thread spinning waiting for an answer...
937 */
938 errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
939 ntohl (mp->new_table_index),
940 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
941 vam->result_ready = 1;
942 }
943}
944
945static void vl_api_classify_add_del_table_reply_t_handler_json
946 (vl_api_classify_add_del_table_reply_t * mp)
947{
948 vat_main_t *vam = &vat_main;
949 vat_json_node_t node;
950
951 vat_json_init_object (&node);
952 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
953 vat_json_object_add_uint (&node, "new_table_index",
954 ntohl (mp->new_table_index));
955 vat_json_object_add_uint (&node, "skip_n_vectors",
956 ntohl (mp->skip_n_vectors));
957 vat_json_object_add_uint (&node, "match_n_vectors",
958 ntohl (mp->match_n_vectors));
959
960 vat_json_print (vam->ofp, &node);
961 vat_json_free (&node);
962
963 vam->retval = ntohl (mp->retval);
964 vam->result_ready = 1;
965}
966
967static void vl_api_get_node_index_reply_t_handler
968 (vl_api_get_node_index_reply_t * mp)
969{
970 vat_main_t *vam = &vat_main;
971 i32 retval = ntohl (mp->retval);
972 if (vam->async_mode)
973 {
974 vam->async_errors += (retval < 0);
975 }
976 else
977 {
978 vam->retval = retval;
979 if (retval == 0)
980 errmsg ("node index %d", ntohl (mp->node_index));
981 vam->result_ready = 1;
982 }
983}
984
985static void vl_api_get_node_index_reply_t_handler_json
986 (vl_api_get_node_index_reply_t * mp)
987{
988 vat_main_t *vam = &vat_main;
989 vat_json_node_t node;
990
991 vat_json_init_object (&node);
992 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
993 vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
994
995 vat_json_print (vam->ofp, &node);
996 vat_json_free (&node);
997
998 vam->retval = ntohl (mp->retval);
999 vam->result_ready = 1;
1000}
1001
1002static void vl_api_get_next_index_reply_t_handler
1003 (vl_api_get_next_index_reply_t * mp)
1004{
1005 vat_main_t *vam = &vat_main;
1006 i32 retval = ntohl (mp->retval);
1007 if (vam->async_mode)
1008 {
1009 vam->async_errors += (retval < 0);
1010 }
1011 else
1012 {
1013 vam->retval = retval;
1014 if (retval == 0)
1015 errmsg ("next node index %d", ntohl (mp->next_index));
1016 vam->result_ready = 1;
1017 }
1018}
1019
1020static void vl_api_get_next_index_reply_t_handler_json
1021 (vl_api_get_next_index_reply_t * mp)
1022{
1023 vat_main_t *vam = &vat_main;
1024 vat_json_node_t node;
1025
1026 vat_json_init_object (&node);
1027 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1028 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1029
1030 vat_json_print (vam->ofp, &node);
1031 vat_json_free (&node);
1032
1033 vam->retval = ntohl (mp->retval);
1034 vam->result_ready = 1;
1035}
1036
1037static void vl_api_add_node_next_reply_t_handler
1038 (vl_api_add_node_next_reply_t * mp)
1039{
1040 vat_main_t *vam = &vat_main;
1041 i32 retval = ntohl (mp->retval);
1042 if (vam->async_mode)
1043 {
1044 vam->async_errors += (retval < 0);
1045 }
1046 else
1047 {
1048 vam->retval = retval;
1049 if (retval == 0)
1050 errmsg ("next index %d", ntohl (mp->next_index));
1051 vam->result_ready = 1;
1052 }
1053}
1054
1055static void vl_api_add_node_next_reply_t_handler_json
1056 (vl_api_add_node_next_reply_t * mp)
1057{
1058 vat_main_t *vam = &vat_main;
1059 vat_json_node_t node;
1060
1061 vat_json_init_object (&node);
1062 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1063 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1064
1065 vat_json_print (vam->ofp, &node);
1066 vat_json_free (&node);
1067
1068 vam->retval = ntohl (mp->retval);
1069 vam->result_ready = 1;
1070}
1071
1072static void vl_api_show_version_reply_t_handler
1073 (vl_api_show_version_reply_t * mp)
1074{
1075 vat_main_t *vam = &vat_main;
1076 i32 retval = ntohl (mp->retval);
1077
1078 if (retval >= 0)
1079 {
1080 errmsg (" program: %s", mp->program);
1081 errmsg (" version: %s", mp->version);
1082 errmsg (" build date: %s", mp->build_date);
1083 errmsg ("build directory: %s", mp->build_directory);
1084 }
1085 vam->retval = retval;
1086 vam->result_ready = 1;
1087}
1088
1089static void vl_api_show_version_reply_t_handler_json
1090 (vl_api_show_version_reply_t * mp)
1091{
1092 vat_main_t *vam = &vat_main;
1093 vat_json_node_t node;
1094
1095 vat_json_init_object (&node);
1096 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1097 vat_json_object_add_string_copy (&node, "program", mp->program);
1098 vat_json_object_add_string_copy (&node, "version", mp->version);
1099 vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1100 vat_json_object_add_string_copy (&node, "build_directory",
1101 mp->build_directory);
1102
1103 vat_json_print (vam->ofp, &node);
1104 vat_json_free (&node);
1105
1106 vam->retval = ntohl (mp->retval);
1107 vam->result_ready = 1;
1108}
1109
1110static void
1111vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1112{
1113 errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1114 mp->mac_ip ? "mac/ip binding" : "address resolution",
1115 format_ip4_address, &mp->address,
1116 format_ethernet_address, mp->new_mac, mp->sw_if_index);
1117}
1118
1119static void
1120vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1121{
1122 /* JSON output not supported */
1123}
1124
1125static void
1126vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1127{
1128 errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1129 mp->mac_ip ? "mac/ip binding" : "address resolution",
1130 format_ip6_address, mp->address,
1131 format_ethernet_address, mp->new_mac, mp->sw_if_index);
1132}
1133
1134static void
1135vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1136{
1137 /* JSON output not supported */
1138}
1139
1140/*
1141 * Special-case: build the bridge domain table, maintain
1142 * the next bd id vbl.
1143 */
1144static void vl_api_bridge_domain_details_t_handler
1145 (vl_api_bridge_domain_details_t * mp)
1146{
1147 vat_main_t *vam = &vat_main;
1148 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1149
1150 print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1151 " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1152
1153 print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1154 ntohl (mp->bd_id), mp->learn, mp->forward,
1155 mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1156
1157 if (n_sw_ifs)
1158 print (vam->ofp, "\n\n%s %s %s", "sw_if_index", "SHG", "Interface Name");
1159}
1160
1161static void vl_api_bridge_domain_details_t_handler_json
1162 (vl_api_bridge_domain_details_t * mp)
1163{
1164 vat_main_t *vam = &vat_main;
1165 vat_json_node_t *node, *array = NULL;
1166
1167 if (VAT_JSON_ARRAY != vam->json_tree.type)
1168 {
1169 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1170 vat_json_init_array (&vam->json_tree);
1171 }
1172 node = vat_json_array_add (&vam->json_tree);
1173
1174 vat_json_init_object (node);
1175 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1176 vat_json_object_add_uint (node, "flood", mp->flood);
1177 vat_json_object_add_uint (node, "forward", mp->forward);
1178 vat_json_object_add_uint (node, "learn", mp->learn);
1179 vat_json_object_add_uint (node, "bvi_sw_if_index",
1180 ntohl (mp->bvi_sw_if_index));
1181 vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1182 array = vat_json_object_add (node, "sw_if");
1183 vat_json_init_array (array);
1184}
1185
1186/*
1187 * Special-case: build the bridge domain sw if table.
1188 */
1189static void vl_api_bridge_domain_sw_if_details_t_handler
1190 (vl_api_bridge_domain_sw_if_details_t * mp)
1191{
1192 vat_main_t *vam = &vat_main;
1193 hash_pair_t *p;
1194 u8 *sw_if_name = 0;
1195 u32 sw_if_index;
1196
1197 sw_if_index = ntohl (mp->sw_if_index);
1198 /* *INDENT-OFF* */
1199 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1200 ({
1201 if ((u32) p->value[0] == sw_if_index)
1202 {
1203 sw_if_name = (u8 *)(p->key);
1204 break;
1205 }
1206 }));
1207 /* *INDENT-ON* */
1208
1209 print (vam->ofp, "%7d %3d %s", sw_if_index,
1210 mp->shg, sw_if_name ? (char *) sw_if_name :
1211 "sw_if_index not found!");
1212}
1213
1214static void vl_api_bridge_domain_sw_if_details_t_handler_json
1215 (vl_api_bridge_domain_sw_if_details_t * mp)
1216{
1217 vat_main_t *vam = &vat_main;
1218 vat_json_node_t *node = NULL;
1219 uword last_index = 0;
1220
1221 ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1222 ASSERT (vec_len (vam->json_tree.array) >= 1);
1223 last_index = vec_len (vam->json_tree.array) - 1;
1224 node = &vam->json_tree.array[last_index];
1225 node = vat_json_object_get_element (node, "sw_if");
1226 ASSERT (NULL != node);
1227 node = vat_json_array_add (node);
1228
1229 vat_json_init_object (node);
1230 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1231 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1232 vat_json_object_add_uint (node, "shg", mp->shg);
1233}
1234
1235static void vl_api_control_ping_reply_t_handler
1236 (vl_api_control_ping_reply_t * mp)
1237{
1238 vat_main_t *vam = &vat_main;
1239 i32 retval = ntohl (mp->retval);
1240 if (vam->async_mode)
1241 {
1242 vam->async_errors += (retval < 0);
1243 }
1244 else
1245 {
1246 vam->retval = retval;
1247 vam->result_ready = 1;
1248 }
1249}
1250
1251static void vl_api_control_ping_reply_t_handler_json
1252 (vl_api_control_ping_reply_t * mp)
1253{
1254 vat_main_t *vam = &vat_main;
1255 i32 retval = ntohl (mp->retval);
1256
1257 if (VAT_JSON_NONE != vam->json_tree.type)
1258 {
1259 vat_json_print (vam->ofp, &vam->json_tree);
1260 vat_json_free (&vam->json_tree);
1261 vam->json_tree.type = VAT_JSON_NONE;
1262 }
1263 else
1264 {
1265 /* just print [] */
1266 vat_json_init_array (&vam->json_tree);
1267 vat_json_print (vam->ofp, &vam->json_tree);
1268 vam->json_tree.type = VAT_JSON_NONE;
1269 }
1270
1271 vam->retval = retval;
1272 vam->result_ready = 1;
1273}
1274
1275static void
1276vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1277{
1278 vat_main_t *vam = &vat_main;
1279 i32 retval = ntohl (mp->retval);
1280 if (vam->async_mode)
1281 {
1282 vam->async_errors += (retval < 0);
1283 }
1284 else
1285 {
1286 vam->retval = retval;
1287 vam->result_ready = 1;
1288 }
1289}
1290
1291static void vl_api_l2_flags_reply_t_handler_json
1292 (vl_api_l2_flags_reply_t * mp)
1293{
1294 vat_main_t *vam = &vat_main;
1295 vat_json_node_t node;
1296
1297 vat_json_init_object (&node);
1298 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1299 vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1300 ntohl (mp->resulting_feature_bitmap));
1301
1302 vat_json_print (vam->ofp, &node);
1303 vat_json_free (&node);
1304
1305 vam->retval = ntohl (mp->retval);
1306 vam->result_ready = 1;
1307}
1308
1309static void vl_api_bridge_flags_reply_t_handler
1310 (vl_api_bridge_flags_reply_t * mp)
1311{
1312 vat_main_t *vam = &vat_main;
1313 i32 retval = ntohl (mp->retval);
1314 if (vam->async_mode)
1315 {
1316 vam->async_errors += (retval < 0);
1317 }
1318 else
1319 {
1320 vam->retval = retval;
1321 vam->result_ready = 1;
1322 }
1323}
1324
1325static void vl_api_bridge_flags_reply_t_handler_json
1326 (vl_api_bridge_flags_reply_t * mp)
1327{
1328 vat_main_t *vam = &vat_main;
1329 vat_json_node_t node;
1330
1331 vat_json_init_object (&node);
1332 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1333 vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1334 ntohl (mp->resulting_feature_bitmap));
1335
1336 vat_json_print (vam->ofp, &node);
1337 vat_json_free (&node);
1338
1339 vam->retval = ntohl (mp->retval);
1340 vam->result_ready = 1;
1341}
1342
1343static void vl_api_tap_connect_reply_t_handler
1344 (vl_api_tap_connect_reply_t * mp)
1345{
1346 vat_main_t *vam = &vat_main;
1347 i32 retval = ntohl (mp->retval);
1348 if (vam->async_mode)
1349 {
1350 vam->async_errors += (retval < 0);
1351 }
1352 else
1353 {
1354 vam->retval = retval;
1355 vam->sw_if_index = ntohl (mp->sw_if_index);
1356 vam->result_ready = 1;
1357 }
1358
1359}
1360
1361static void vl_api_tap_connect_reply_t_handler_json
1362 (vl_api_tap_connect_reply_t * mp)
1363{
1364 vat_main_t *vam = &vat_main;
1365 vat_json_node_t node;
1366
1367 vat_json_init_object (&node);
1368 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1369 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1370
1371 vat_json_print (vam->ofp, &node);
1372 vat_json_free (&node);
1373
1374 vam->retval = ntohl (mp->retval);
1375 vam->result_ready = 1;
1376
1377}
1378
1379static void
1380vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1381{
1382 vat_main_t *vam = &vat_main;
1383 i32 retval = ntohl (mp->retval);
1384 if (vam->async_mode)
1385 {
1386 vam->async_errors += (retval < 0);
1387 }
1388 else
1389 {
1390 vam->retval = retval;
1391 vam->sw_if_index = ntohl (mp->sw_if_index);
1392 vam->result_ready = 1;
1393 }
1394}
1395
1396static void vl_api_tap_modify_reply_t_handler_json
1397 (vl_api_tap_modify_reply_t * mp)
1398{
1399 vat_main_t *vam = &vat_main;
1400 vat_json_node_t node;
1401
1402 vat_json_init_object (&node);
1403 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1404 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1405
1406 vat_json_print (vam->ofp, &node);
1407 vat_json_free (&node);
1408
1409 vam->retval = ntohl (mp->retval);
1410 vam->result_ready = 1;
1411}
1412
1413static void
1414vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1415{
1416 vat_main_t *vam = &vat_main;
1417 i32 retval = ntohl (mp->retval);
1418 if (vam->async_mode)
1419 {
1420 vam->async_errors += (retval < 0);
1421 }
1422 else
1423 {
1424 vam->retval = retval;
1425 vam->result_ready = 1;
1426 }
1427}
1428
1429static void vl_api_tap_delete_reply_t_handler_json
1430 (vl_api_tap_delete_reply_t * mp)
1431{
1432 vat_main_t *vam = &vat_main;
1433 vat_json_node_t node;
1434
1435 vat_json_init_object (&node);
1436 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1437
1438 vat_json_print (vam->ofp, &node);
1439 vat_json_free (&node);
1440
1441 vam->retval = ntohl (mp->retval);
1442 vam->result_ready = 1;
1443}
1444
1445static void vl_api_mpls_tunnel_add_del_reply_t_handler
1446 (vl_api_mpls_tunnel_add_del_reply_t * mp)
1447{
1448 vat_main_t *vam = &vat_main;
1449 i32 retval = ntohl (mp->retval);
1450 if (vam->async_mode)
1451 {
1452 vam->async_errors += (retval < 0);
1453 }
1454 else
1455 {
1456 vam->retval = retval;
1457 vam->result_ready = 1;
1458 }
1459}
1460
1461static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1462 (vl_api_mpls_tunnel_add_del_reply_t * mp)
1463{
1464 vat_main_t *vam = &vat_main;
1465 vat_json_node_t node;
1466
1467 vat_json_init_object (&node);
1468 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1469 vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1470 ntohl (mp->sw_if_index));
1471
1472 vat_json_print (vam->ofp, &node);
1473 vat_json_free (&node);
1474
1475 vam->retval = ntohl (mp->retval);
1476 vam->result_ready = 1;
1477}
1478
1479static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1480 (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1481{
1482 vat_main_t *vam = &vat_main;
1483 i32 retval = ntohl (mp->retval);
1484 if (vam->async_mode)
1485 {
1486 vam->async_errors += (retval < 0);
1487 }
1488 else
1489 {
1490 vam->retval = retval;
1491 vam->sw_if_index = ntohl (mp->sw_if_index);
1492 vam->result_ready = 1;
1493 }
1494}
1495
1496static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1497 (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1498{
1499 vat_main_t *vam = &vat_main;
1500 vat_json_node_t node;
1501
1502 vat_json_init_object (&node);
1503 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1504 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1505
1506 vat_json_print (vam->ofp, &node);
1507 vat_json_free (&node);
1508
1509 vam->retval = ntohl (mp->retval);
1510 vam->result_ready = 1;
1511}
1512
1513
1514static void vl_api_lisp_add_del_locator_set_reply_t_handler
1515 (vl_api_lisp_add_del_locator_set_reply_t * mp)
1516{
1517 vat_main_t *vam = &vat_main;
1518 i32 retval = ntohl (mp->retval);
1519 if (vam->async_mode)
1520 {
1521 vam->async_errors += (retval < 0);
1522 }
1523 else
1524 {
1525 vam->retval = retval;
1526 vam->result_ready = 1;
1527 }
1528}
1529
1530static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1531 (vl_api_lisp_add_del_locator_set_reply_t * mp)
1532{
1533 vat_main_t *vam = &vat_main;
1534 vat_json_node_t node;
1535
1536 vat_json_init_object (&node);
1537 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1538 vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1539
1540 vat_json_print (vam->ofp, &node);
1541 vat_json_free (&node);
1542
1543 vam->retval = ntohl (mp->retval);
1544 vam->result_ready = 1;
1545}
1546
1547static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1548 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1549{
1550 vat_main_t *vam = &vat_main;
1551 i32 retval = ntohl (mp->retval);
1552 if (vam->async_mode)
1553 {
1554 vam->async_errors += (retval < 0);
1555 }
1556 else
1557 {
1558 vam->retval = retval;
1559 vam->sw_if_index = ntohl (mp->sw_if_index);
1560 vam->result_ready = 1;
1561 }
1562}
1563
1564static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1565 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1566{
1567 vat_main_t *vam = &vat_main;
1568 vat_json_node_t node;
1569
1570 vat_json_init_object (&node);
1571 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1572 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1573
1574 vat_json_print (vam->ofp, &node);
1575 vat_json_free (&node);
1576
1577 vam->retval = ntohl (mp->retval);
1578 vam->result_ready = 1;
1579}
1580
1581static void vl_api_gre_add_del_tunnel_reply_t_handler
1582 (vl_api_gre_add_del_tunnel_reply_t * mp)
1583{
1584 vat_main_t *vam = &vat_main;
1585 i32 retval = ntohl (mp->retval);
1586 if (vam->async_mode)
1587 {
1588 vam->async_errors += (retval < 0);
1589 }
1590 else
1591 {
1592 vam->retval = retval;
1593 vam->sw_if_index = ntohl (mp->sw_if_index);
1594 vam->result_ready = 1;
1595 }
1596}
1597
1598static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1599 (vl_api_gre_add_del_tunnel_reply_t * mp)
1600{
1601 vat_main_t *vam = &vat_main;
1602 vat_json_node_t node;
1603
1604 vat_json_init_object (&node);
1605 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1606 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1607
1608 vat_json_print (vam->ofp, &node);
1609 vat_json_free (&node);
1610
1611 vam->retval = ntohl (mp->retval);
1612 vam->result_ready = 1;
1613}
1614
1615static void vl_api_create_vhost_user_if_reply_t_handler
1616 (vl_api_create_vhost_user_if_reply_t * mp)
1617{
1618 vat_main_t *vam = &vat_main;
1619 i32 retval = ntohl (mp->retval);
1620 if (vam->async_mode)
1621 {
1622 vam->async_errors += (retval < 0);
1623 }
1624 else
1625 {
1626 vam->retval = retval;
1627 vam->sw_if_index = ntohl (mp->sw_if_index);
1628 vam->result_ready = 1;
1629 }
1630}
1631
1632static void vl_api_create_vhost_user_if_reply_t_handler_json
1633 (vl_api_create_vhost_user_if_reply_t * mp)
1634{
1635 vat_main_t *vam = &vat_main;
1636 vat_json_node_t node;
1637
1638 vat_json_init_object (&node);
1639 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1640 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1641
1642 vat_json_print (vam->ofp, &node);
1643 vat_json_free (&node);
1644
1645 vam->retval = ntohl (mp->retval);
1646 vam->result_ready = 1;
1647}
1648
1649static void vl_api_ip_address_details_t_handler
1650 (vl_api_ip_address_details_t * mp)
1651{
1652 vat_main_t *vam = &vat_main;
1653 static ip_address_details_t empty_ip_address_details = { {0} };
1654 ip_address_details_t *address = NULL;
1655 ip_details_t *current_ip_details = NULL;
1656 ip_details_t *details = NULL;
1657
1658 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1659
1660 if (!details || vam->current_sw_if_index >= vec_len (details)
1661 || !details[vam->current_sw_if_index].present)
1662 {
1663 errmsg ("ip address details arrived but not stored");
1664 errmsg ("ip_dump should be called first");
1665 return;
1666 }
1667
1668 current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1669
1670#define addresses (current_ip_details->addr)
1671
1672 vec_validate_init_empty (addresses, vec_len (addresses),
1673 empty_ip_address_details);
1674
1675 address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1676
1677 clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1678 address->prefix_length = mp->prefix_length;
1679#undef addresses
1680}
1681
1682static void vl_api_ip_address_details_t_handler_json
1683 (vl_api_ip_address_details_t * mp)
1684{
1685 vat_main_t *vam = &vat_main;
1686 vat_json_node_t *node = NULL;
1687 struct in6_addr ip6;
1688 struct in_addr ip4;
1689
1690 if (VAT_JSON_ARRAY != vam->json_tree.type)
1691 {
1692 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1693 vat_json_init_array (&vam->json_tree);
1694 }
1695 node = vat_json_array_add (&vam->json_tree);
1696
1697 vat_json_init_object (node);
1698 if (vam->is_ipv6)
1699 {
1700 clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1701 vat_json_object_add_ip6 (node, "ip", ip6);
1702 }
1703 else
1704 {
1705 clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1706 vat_json_object_add_ip4 (node, "ip", ip4);
1707 }
1708 vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1709}
1710
1711static void
1712vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1713{
1714 vat_main_t *vam = &vat_main;
1715 static ip_details_t empty_ip_details = { 0 };
1716 ip_details_t *ip = NULL;
1717 u32 sw_if_index = ~0;
1718
1719 sw_if_index = ntohl (mp->sw_if_index);
1720
1721 vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1722 sw_if_index, empty_ip_details);
1723
1724 ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1725 sw_if_index);
1726
1727 ip->present = 1;
1728}
1729
1730static void
1731vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1732{
1733 vat_main_t *vam = &vat_main;
1734
1735 if (VAT_JSON_ARRAY != vam->json_tree.type)
1736 {
1737 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1738 vat_json_init_array (&vam->json_tree);
1739 }
1740 vat_json_array_add_uint (&vam->json_tree,
1741 clib_net_to_host_u32 (mp->sw_if_index));
1742}
1743
1744static void vl_api_map_domain_details_t_handler_json
1745 (vl_api_map_domain_details_t * mp)
1746{
1747 vat_json_node_t *node = NULL;
1748 vat_main_t *vam = &vat_main;
1749 struct in6_addr ip6;
1750 struct in_addr ip4;
1751
1752 if (VAT_JSON_ARRAY != vam->json_tree.type)
1753 {
1754 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1755 vat_json_init_array (&vam->json_tree);
1756 }
1757
1758 node = vat_json_array_add (&vam->json_tree);
1759 vat_json_init_object (node);
1760
1761 vat_json_object_add_uint (node, "domain_index",
1762 clib_net_to_host_u32 (mp->domain_index));
1763 clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1764 vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1765 clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1766 vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1767 clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1768 vat_json_object_add_ip6 (node, "ip6_src", ip6);
1769 vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1770 vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1771 vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1772 vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1773 vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1774 vat_json_object_add_int (node, "psid_length", mp->psid_length);
1775 vat_json_object_add_uint (node, "flags", mp->flags);
1776 vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1777 vat_json_object_add_int (node, "is_translation", mp->is_translation);
1778}
1779
1780static void vl_api_map_domain_details_t_handler
1781 (vl_api_map_domain_details_t * mp)
1782{
1783 vat_main_t *vam = &vat_main;
1784
1785 if (mp->is_translation)
1786 {
1787 print (vam->ofp,
1788 "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1789 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1790 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1791 format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1792 clib_net_to_host_u32 (mp->domain_index));
1793 }
1794 else
1795 {
1796 print (vam->ofp,
1797 "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1798 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1799 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1800 format_ip6_address, mp->ip6_src,
1801 clib_net_to_host_u32 (mp->domain_index));
1802 }
1803 print (vam->ofp, " ea-len %d psid-offset %d psid-len %d mtu %d %s",
1804 mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1805 mp->is_translation ? "map-t" : "");
1806}
1807
1808static void vl_api_map_rule_details_t_handler_json
1809 (vl_api_map_rule_details_t * mp)
1810{
1811 struct in6_addr ip6;
1812 vat_json_node_t *node = NULL;
1813 vat_main_t *vam = &vat_main;
1814
1815 if (VAT_JSON_ARRAY != vam->json_tree.type)
1816 {
1817 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1818 vat_json_init_array (&vam->json_tree);
1819 }
1820
1821 node = vat_json_array_add (&vam->json_tree);
1822 vat_json_init_object (node);
1823
1824 vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1825 clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1826 vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1827}
1828
1829static void
1830vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1831{
1832 vat_main_t *vam = &vat_main;
1833 print (vam->ofp, " %d (psid) %U (ip6-dst)",
1834 clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1835}
1836
1837static void
1838vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1839{
1840 errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1841 "router_addr %U host_mac %U",
1842 mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1843 format_ip4_address, &mp->host_address,
1844 format_ip4_address, &mp->router_address,
1845 format_ethernet_address, mp->host_mac);
1846}
1847
1848static void vl_api_dhcp_compl_event_t_handler_json
1849 (vl_api_dhcp_compl_event_t * mp)
1850{
1851 /* JSON output not supported */
1852}
1853
1854static void
1855set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1856 u32 counter)
1857{
1858 vat_main_t *vam = &vat_main;
1859 static u64 default_counter = 0;
1860
1861 vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1862 NULL);
1863 vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1864 sw_if_index, default_counter);
1865 vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1866}
1867
1868static void
1869set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1870 interface_counter_t counter)
1871{
1872 vat_main_t *vam = &vat_main;
1873 static interface_counter_t default_counter = { 0, };
1874
1875 vec_validate_init_empty (vam->combined_interface_counters,
1876 vnet_counter_type, NULL);
1877 vec_validate_init_empty (vam->combined_interface_counters
1878 [vnet_counter_type], sw_if_index, default_counter);
1879 vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1880}
1881
1882static void vl_api_vnet_interface_counters_t_handler
1883 (vl_api_vnet_interface_counters_t * mp)
1884{
1885 /* not supported */
1886}
1887
1888static void vl_api_vnet_interface_counters_t_handler_json
1889 (vl_api_vnet_interface_counters_t * mp)
1890{
1891 interface_counter_t counter;
1892 vlib_counter_t *v;
1893 u64 *v_packets;
1894 u64 packets;
1895 u32 count;
1896 u32 first_sw_if_index;
1897 int i;
1898
1899 count = ntohl (mp->count);
1900 first_sw_if_index = ntohl (mp->first_sw_if_index);
1901
1902 if (!mp->is_combined)
1903 {
1904 v_packets = (u64 *) & mp->data;
1905 for (i = 0; i < count; i++)
1906 {
1907 packets =
1908 clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1909 set_simple_interface_counter (mp->vnet_counter_type,
1910 first_sw_if_index + i, packets);
1911 v_packets++;
1912 }
1913 }
1914 else
1915 {
1916 v = (vlib_counter_t *) & mp->data;
1917 for (i = 0; i < count; i++)
1918 {
1919 counter.packets =
1920 clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1921 counter.bytes =
1922 clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1923 set_combined_interface_counter (mp->vnet_counter_type,
1924 first_sw_if_index + i, counter);
1925 v++;
1926 }
1927 }
1928}
1929
1930static u32
1931ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1932{
1933 vat_main_t *vam = &vat_main;
1934 u32 i;
1935
1936 for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1937 {
1938 if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1939 {
1940 return i;
1941 }
1942 }
1943 return ~0;
1944}
1945
1946static u32
1947ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1948{
1949 vat_main_t *vam = &vat_main;
1950 u32 i;
1951
1952 for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1953 {
1954 if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1955 {
1956 return i;
1957 }
1958 }
1959 return ~0;
1960}
1961
1962static void vl_api_vnet_ip4_fib_counters_t_handler
1963 (vl_api_vnet_ip4_fib_counters_t * mp)
1964{
1965 /* not supported */
1966}
1967
1968static void vl_api_vnet_ip4_fib_counters_t_handler_json
1969 (vl_api_vnet_ip4_fib_counters_t * mp)
1970{
1971 vat_main_t *vam = &vat_main;
1972 vl_api_ip4_fib_counter_t *v;
1973 ip4_fib_counter_t *counter;
1974 struct in_addr ip4;
1975 u32 vrf_id;
1976 u32 vrf_index;
1977 u32 count;
1978 int i;
1979
1980 vrf_id = ntohl (mp->vrf_id);
1981 vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
1982 if (~0 == vrf_index)
1983 {
1984 vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
1985 vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1986 vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1987 vec_validate (vam->ip4_fib_counters, vrf_index);
1988 vam->ip4_fib_counters[vrf_index] = NULL;
1989 }
1990
1991 vec_free (vam->ip4_fib_counters[vrf_index]);
1992 v = (vl_api_ip4_fib_counter_t *) & mp->c;
1993 count = ntohl (mp->count);
1994 for (i = 0; i < count; i++)
1995 {
1996 vec_validate (vam->ip4_fib_counters[vrf_index], i);
1997 counter = &vam->ip4_fib_counters[vrf_index][i];
1998 clib_memcpy (&ip4, &v->address, sizeof (ip4));
1999 counter->address = ip4;
2000 counter->address_length = v->address_length;
2001 counter->packets = clib_net_to_host_u64 (v->packets);
2002 counter->bytes = clib_net_to_host_u64 (v->bytes);
2003 v++;
2004 }
2005}
2006
2007static void vl_api_vnet_ip6_fib_counters_t_handler
2008 (vl_api_vnet_ip6_fib_counters_t * mp)
2009{
2010 /* not supported */
2011}
2012
2013static void vl_api_vnet_ip6_fib_counters_t_handler_json
2014 (vl_api_vnet_ip6_fib_counters_t * mp)
2015{
2016 vat_main_t *vam = &vat_main;
2017 vl_api_ip6_fib_counter_t *v;
2018 ip6_fib_counter_t *counter;
2019 struct in6_addr ip6;
2020 u32 vrf_id;
2021 u32 vrf_index;
2022 u32 count;
2023 int i;
2024
2025 vrf_id = ntohl (mp->vrf_id);
2026 vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2027 if (~0 == vrf_index)
2028 {
2029 vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2030 vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2031 vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2032 vec_validate (vam->ip6_fib_counters, vrf_index);
2033 vam->ip6_fib_counters[vrf_index] = NULL;
2034 }
2035
2036 vec_free (vam->ip6_fib_counters[vrf_index]);
2037 v = (vl_api_ip6_fib_counter_t *) & mp->c;
2038 count = ntohl (mp->count);
2039 for (i = 0; i < count; i++)
2040 {
2041 vec_validate (vam->ip6_fib_counters[vrf_index], i);
2042 counter = &vam->ip6_fib_counters[vrf_index][i];
2043 clib_memcpy (&ip6, &v->address, sizeof (ip6));
2044 counter->address = ip6;
2045 counter->address_length = v->address_length;
2046 counter->packets = clib_net_to_host_u64 (v->packets);
2047 counter->bytes = clib_net_to_host_u64 (v->bytes);
2048 v++;
2049 }
2050}
2051
2052static void vl_api_get_first_msg_id_reply_t_handler
2053 (vl_api_get_first_msg_id_reply_t * mp)
2054{
2055 vat_main_t *vam = &vat_main;
2056 i32 retval = ntohl (mp->retval);
2057
2058 if (vam->async_mode)
2059 {
2060 vam->async_errors += (retval < 0);
2061 }
2062 else
2063 {
2064 vam->retval = retval;
2065 vam->result_ready = 1;
2066 }
2067 if (retval >= 0)
2068 {
2069 errmsg ("first message id %d", ntohs (mp->first_msg_id));
2070 }
2071}
2072
2073static void vl_api_get_first_msg_id_reply_t_handler_json
2074 (vl_api_get_first_msg_id_reply_t * mp)
2075{
2076 vat_main_t *vam = &vat_main;
2077 vat_json_node_t node;
2078
2079 vat_json_init_object (&node);
2080 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2081 vat_json_object_add_uint (&node, "first_msg_id",
2082 (uint) ntohs (mp->first_msg_id));
2083
2084 vat_json_print (vam->ofp, &node);
2085 vat_json_free (&node);
2086
2087 vam->retval = ntohl (mp->retval);
2088 vam->result_ready = 1;
2089}
2090
2091static void vl_api_get_node_graph_reply_t_handler
2092 (vl_api_get_node_graph_reply_t * mp)
2093{
2094 vat_main_t *vam = &vat_main;
2095 api_main_t *am = &api_main;
2096 i32 retval = ntohl (mp->retval);
2097 u8 *pvt_copy, *reply;
2098 void *oldheap;
2099 vlib_node_t *node;
2100 int i;
2101
2102 if (vam->async_mode)
2103 {
2104 vam->async_errors += (retval < 0);
2105 }
2106 else
2107 {
2108 vam->retval = retval;
2109 vam->result_ready = 1;
2110 }
2111
2112 /* "Should never happen..." */
2113 if (retval != 0)
2114 return;
2115
2116 reply = (u8 *) (mp->reply_in_shmem);
2117 pvt_copy = vec_dup (reply);
2118
2119 /* Toss the shared-memory original... */
2120 pthread_mutex_lock (&am->vlib_rp->mutex);
2121 oldheap = svm_push_data_heap (am->vlib_rp);
2122
2123 vec_free (reply);
2124
2125 svm_pop_heap (oldheap);
2126 pthread_mutex_unlock (&am->vlib_rp->mutex);
2127
2128 if (vam->graph_nodes)
2129 {
2130 hash_free (vam->graph_node_index_by_name);
2131
2132 for (i = 0; i < vec_len (vam->graph_nodes); i++)
2133 {
2134 node = vam->graph_nodes[i];
2135 vec_free (node->name);
2136 vec_free (node->next_nodes);
2137 vec_free (node);
2138 }
2139 vec_free (vam->graph_nodes);
2140 }
2141
2142 vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2143 vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2144 vec_free (pvt_copy);
2145
2146 for (i = 0; i < vec_len (vam->graph_nodes); i++)
2147 {
2148 node = vam->graph_nodes[i];
2149 hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2150 }
2151}
2152
2153static void vl_api_get_node_graph_reply_t_handler_json
2154 (vl_api_get_node_graph_reply_t * mp)
2155{
2156 vat_main_t *vam = &vat_main;
2157 api_main_t *am = &api_main;
2158 void *oldheap;
2159 vat_json_node_t node;
2160 u8 *reply;
2161
2162 /* $$$$ make this real? */
2163 vat_json_init_object (&node);
2164 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2165 vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2166
2167 reply = (u8 *) (mp->reply_in_shmem);
2168
2169 /* Toss the shared-memory original... */
2170 pthread_mutex_lock (&am->vlib_rp->mutex);
2171 oldheap = svm_push_data_heap (am->vlib_rp);
2172
2173 vec_free (reply);
2174
2175 svm_pop_heap (oldheap);
2176 pthread_mutex_unlock (&am->vlib_rp->mutex);
2177
2178 vat_json_print (vam->ofp, &node);
2179 vat_json_free (&node);
2180
2181 vam->retval = ntohl (mp->retval);
2182 vam->result_ready = 1;
2183}
2184
2185static void
2186vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2187{
2188 vat_main_t *vam = &vat_main;
2189 u8 *s = 0;
2190
2191 if (mp->local)
2192 {
2193 s = format (s, "%=16d%=16d%=16d",
2194 ntohl (mp->sw_if_index), mp->priority, mp->weight);
2195 }
2196 else
2197 {
2198 s = format (s, "%=16U%=16d%=16d",
2199 mp->is_ipv6 ? format_ip6_address :
2200 format_ip4_address,
2201 mp->ip_address, mp->priority, mp->weight);
2202 }
2203
2204 print (vam->ofp, "%v", s);
2205 vec_free (s);
2206}
2207
2208static void
2209vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2210 mp)
2211{
2212 vat_main_t *vam = &vat_main;
2213 vat_json_node_t *node = NULL;
2214 struct in6_addr ip6;
2215 struct in_addr ip4;
2216
2217 if (VAT_JSON_ARRAY != vam->json_tree.type)
2218 {
2219 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2220 vat_json_init_array (&vam->json_tree);
2221 }
2222 node = vat_json_array_add (&vam->json_tree);
2223 vat_json_init_object (node);
2224
2225 vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2226 vat_json_object_add_uint (node, "priority", mp->priority);
2227 vat_json_object_add_uint (node, "weight", mp->weight);
2228
2229 if (mp->local)
2230 vat_json_object_add_uint (node, "sw_if_index",
2231 clib_net_to_host_u32 (mp->sw_if_index));
2232 else
2233 {
2234 if (mp->is_ipv6)
2235 {
2236 clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2237 vat_json_object_add_ip6 (node, "address", ip6);
2238 }
2239 else
2240 {
2241 clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2242 vat_json_object_add_ip4 (node, "address", ip4);
2243 }
2244 }
2245}
2246
2247static void
2248vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2249 mp)
2250{
2251 vat_main_t *vam = &vat_main;
2252 u8 *ls_name = 0;
2253
2254 ls_name = format (0, "%s", mp->ls_name);
2255
2256 print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2257 ls_name);
2258 vec_free (ls_name);
2259}
2260
2261static void
2262 vl_api_lisp_locator_set_details_t_handler_json
2263 (vl_api_lisp_locator_set_details_t * mp)
2264{
2265 vat_main_t *vam = &vat_main;
2266 vat_json_node_t *node = 0;
2267 u8 *ls_name = 0;
2268
2269 ls_name = format (0, "%s", mp->ls_name);
2270 vec_add1 (ls_name, 0);
2271
2272 if (VAT_JSON_ARRAY != vam->json_tree.type)
2273 {
2274 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2275 vat_json_init_array (&vam->json_tree);
2276 }
2277 node = vat_json_array_add (&vam->json_tree);
2278
2279 vat_json_init_object (node);
2280 vat_json_object_add_string_copy (node, "ls_name", ls_name);
2281 vat_json_object_add_uint (node, "ls_index",
2282 clib_net_to_host_u32 (mp->ls_index));
2283 vec_free (ls_name);
2284}
2285
2286static u8 *
2287format_lisp_flat_eid (u8 * s, va_list * args)
2288{
2289 u32 type = va_arg (*args, u32);
2290 u8 *eid = va_arg (*args, u8 *);
2291 u32 eid_len = va_arg (*args, u32);
2292
2293 switch (type)
2294 {
2295 case 0:
2296 return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2297 case 1:
2298 return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2299 case 2:
2300 return format (s, "%U", format_ethernet_address, eid);
2301 }
2302 return 0;
2303}
2304
2305static u8 *
2306format_lisp_eid_vat (u8 * s, va_list * args)
2307{
2308 u32 type = va_arg (*args, u32);
2309 u8 *eid = va_arg (*args, u8 *);
2310 u32 eid_len = va_arg (*args, u32);
2311 u8 *seid = va_arg (*args, u8 *);
2312 u32 seid_len = va_arg (*args, u32);
2313 u32 is_src_dst = va_arg (*args, u32);
2314
2315 if (is_src_dst)
2316 s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2317
2318 s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2319
2320 return s;
2321}
2322
2323static void
2324vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2325{
2326 vat_main_t *vam = &vat_main;
2327 u8 *s = 0, *eid = 0;
2328
2329 if (~0 == mp->locator_set_index)
2330 s = format (0, "action: %d", mp->action);
2331 else
2332 s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2333
2334 eid = format (0, "%U", format_lisp_eid_vat,
2335 mp->eid_type,
2336 mp->eid,
2337 mp->eid_prefix_len,
2338 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2339 vec_add1 (eid, 0);
2340
2341 print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2342 clib_net_to_host_u32 (mp->vni),
2343 eid,
2344 mp->is_local ? "local" : "remote",
2345 s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2346 clib_net_to_host_u16 (mp->key_id), mp->key);
2347
2348 vec_free (s);
2349 vec_free (eid);
2350}
2351
2352static void
2353vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2354 * mp)
2355{
2356 vat_main_t *vam = &vat_main;
2357 vat_json_node_t *node = 0;
2358 u8 *eid = 0;
2359
2360 if (VAT_JSON_ARRAY != vam->json_tree.type)
2361 {
2362 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2363 vat_json_init_array (&vam->json_tree);
2364 }
2365 node = vat_json_array_add (&vam->json_tree);
2366
2367 vat_json_init_object (node);
2368 if (~0 == mp->locator_set_index)
2369 vat_json_object_add_uint (node, "action", mp->action);
2370 else
2371 vat_json_object_add_uint (node, "locator_set_index",
2372 clib_net_to_host_u32 (mp->locator_set_index));
2373
2374 vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2375 eid = format (0, "%U", format_lisp_eid_vat,
2376 mp->eid_type,
2377 mp->eid,
2378 mp->eid_prefix_len,
2379 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2380 vec_add1 (eid, 0);
2381 vat_json_object_add_string_copy (node, "eid", eid);
2382 vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2383 vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2384 vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2385
2386 if (mp->key_id)
2387 {
2388 vat_json_object_add_uint (node, "key_id",
2389 clib_net_to_host_u16 (mp->key_id));
2390 vat_json_object_add_string_copy (node, "key", mp->key);
2391 }
2392 vec_free (eid);
2393}
2394
2395static void
2396 vl_api_lisp_eid_table_map_details_t_handler
2397 (vl_api_lisp_eid_table_map_details_t * mp)
2398{
2399 vat_main_t *vam = &vat_main;
2400
2401 u8 *line = format (0, "%=10d%=10d",
2402 clib_net_to_host_u32 (mp->vni),
2403 clib_net_to_host_u32 (mp->dp_table));
2404 print (vam->ofp, "%v", line);
2405 vec_free (line);
2406}
2407
2408static void
2409 vl_api_lisp_eid_table_map_details_t_handler_json
2410 (vl_api_lisp_eid_table_map_details_t * mp)
2411{
2412 vat_main_t *vam = &vat_main;
2413 vat_json_node_t *node = NULL;
2414
2415 if (VAT_JSON_ARRAY != vam->json_tree.type)
2416 {
2417 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2418 vat_json_init_array (&vam->json_tree);
2419 }
2420 node = vat_json_array_add (&vam->json_tree);
2421 vat_json_init_object (node);
2422 vat_json_object_add_uint (node, "dp_table",
2423 clib_net_to_host_u32 (mp->dp_table));
2424 vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2425}
2426
2427static void
2428 vl_api_lisp_eid_table_vni_details_t_handler
2429 (vl_api_lisp_eid_table_vni_details_t * mp)
2430{
2431 vat_main_t *vam = &vat_main;
2432
2433 u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2434 print (vam->ofp, "%v", line);
2435 vec_free (line);
2436}
2437
2438static void
2439 vl_api_lisp_eid_table_vni_details_t_handler_json
2440 (vl_api_lisp_eid_table_vni_details_t * mp)
2441{
2442 vat_main_t *vam = &vat_main;
2443 vat_json_node_t *node = NULL;
2444
2445 if (VAT_JSON_ARRAY != vam->json_tree.type)
2446 {
2447 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2448 vat_json_init_array (&vam->json_tree);
2449 }
2450 node = vat_json_array_add (&vam->json_tree);
2451 vat_json_init_object (node);
2452 vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2453}
2454
2455static u8 *
2456format_decap_next (u8 * s, va_list * args)
2457{
2458 u32 next_index = va_arg (*args, u32);
2459
2460 switch (next_index)
2461 {
2462 case LISP_GPE_INPUT_NEXT_DROP:
2463 return format (s, "drop");
2464 case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2465 return format (s, "ip4");
2466 case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2467 return format (s, "ip6");
2468 default:
2469 return format (s, "unknown %d", next_index);
2470 }
2471 return s;
2472}
2473
2474static void
2475vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2476 mp)
2477{
2478 vat_main_t *vam = &vat_main;
2479 u8 *iid_str;
2480 u8 *flag_str = NULL;
2481
2482 iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2483
2484#define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2485 foreach_lisp_gpe_flag_bit;
2486#undef _
2487
2488 print (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2489 "%=16d%=16d%=16sd=16d%=16s%=16s",
2490 mp->tunnels,
2491 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2492 mp->source_ip,
2493 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2494 mp->destination_ip,
2495 ntohl (mp->encap_fib_id),
2496 ntohl (mp->decap_fib_id),
2497 format_decap_next, ntohl (mp->dcap_next),
2498 mp->ver_res >> 6,
2499 flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2500
2501 vec_free (iid_str);
2502}
2503
2504static void
2505 vl_api_lisp_gpe_tunnel_details_t_handler_json
2506 (vl_api_lisp_gpe_tunnel_details_t * mp)
2507{
2508 vat_main_t *vam = &vat_main;
2509 vat_json_node_t *node = NULL;
2510 struct in6_addr ip6;
2511 struct in_addr ip4;
2512 u8 *next_decap_str;
2513
2514 next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2515
2516 if (VAT_JSON_ARRAY != vam->json_tree.type)
2517 {
2518 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2519 vat_json_init_array (&vam->json_tree);
2520 }
2521 node = vat_json_array_add (&vam->json_tree);
2522
2523 vat_json_init_object (node);
2524 vat_json_object_add_uint (node, "tunel", mp->tunnels);
2525 if (mp->is_ipv6)
2526 {
2527 clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2528 vat_json_object_add_ip6 (node, "source address", ip6);
2529 clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2530 vat_json_object_add_ip6 (node, "destination address", ip6);
2531 }
2532 else
2533 {
2534 clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2535 vat_json_object_add_ip4 (node, "source address", ip4);
2536 clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2537 vat_json_object_add_ip4 (node, "destination address", ip4);
2538 }
2539 vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2540 vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2541 vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2542 vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2543 vat_json_object_add_uint (node, "flags", mp->flags);
2544 vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2545 vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2546 vat_json_object_add_uint (node, "res", mp->res);
2547 vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2548
2549 vec_free (next_decap_str);
2550}
2551
2552static void
2553 vl_api_show_lisp_map_register_state_reply_t_handler
2554 (vl_api_show_lisp_map_register_state_reply_t * mp)
2555{
2556 vat_main_t *vam = &vat_main;
2557 int retval = clib_net_to_host_u32 (mp->retval);
2558
2559 print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2560
2561 vam->retval = retval;
2562 vam->result_ready = 1;
2563}
2564
2565static void
2566 vl_api_show_lisp_map_register_state_reply_t_handler_json
2567 (vl_api_show_lisp_map_register_state_reply_t * mp)
2568{
2569 vat_main_t *vam = &vat_main;
2570 vat_json_node_t _node, *node = &_node;
2571 int retval = clib_net_to_host_u32 (mp->retval);
2572
2573 u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2574
2575 vat_json_init_object (node);
2576 vat_json_object_add_string_copy (node, "state", s);
2577
2578 vat_json_print (vam->ofp, node);
2579 vat_json_free (node);
2580
2581 vam->retval = retval;
2582 vam->result_ready = 1;
2583 vec_free (s);
2584}
2585
2586static void
2587 vl_api_show_lisp_rloc_probe_state_reply_t_handler
2588 (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2589{
2590 vat_main_t *vam = &vat_main;
2591 int retval = clib_net_to_host_u32 (mp->retval);
2592
2593 if (retval)
2594 goto end;
2595
2596 print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2597end:
2598 vam->retval = retval;
2599 vam->result_ready = 1;
2600}
2601
2602static void
2603 vl_api_show_lisp_rloc_probe_state_reply_t_handler_json
2604 (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2605{
2606 vat_main_t *vam = &vat_main;
2607 vat_json_node_t _node, *node = &_node;
2608 int retval = clib_net_to_host_u32 (mp->retval);
2609
2610 u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2611 vat_json_init_object (node);
2612 vat_json_object_add_string_copy (node, "state", s);
2613
2614 vat_json_print (vam->ofp, node);
2615 vat_json_free (node);
2616
2617 vam->retval = retval;
2618 vam->result_ready = 1;
2619 vec_free (s);
2620}
2621
2622static void
2623 vl_api_lisp_adjacencies_get_reply_t_handler
2624 (vl_api_lisp_adjacencies_get_reply_t * mp)
2625{
2626 vat_main_t *vam = &vat_main;
2627 u32 i, n;
2628 int retval = clib_net_to_host_u32 (mp->retval);
2629 vl_api_lisp_adjacency_t *a;
2630
2631 if (retval)
2632 goto end;
2633
2634 n = clib_net_to_host_u32 (mp->count);
2635
2636 for (i = 0; i < n; i++)
2637 {
2638 a = &mp->adjacencies[i];
2639 print (vam->ofp, "%U %40U",
2640 format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2641 format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2642 }
2643
2644end:
2645 vam->retval = retval;
2646 vam->result_ready = 1;
2647}
2648
2649static void
2650 vl_api_lisp_adjacencies_get_reply_t_handler_json
2651 (vl_api_lisp_adjacencies_get_reply_t * mp)
2652{
2653 u8 *s = 0;
2654 vat_main_t *vam = &vat_main;
2655 vat_json_node_t *e = 0, root;
2656 u32 i, n;
2657 int retval = clib_net_to_host_u32 (mp->retval);
2658 vl_api_lisp_adjacency_t *a;
2659
2660 if (retval)
2661 goto end;
2662
2663 n = clib_net_to_host_u32 (mp->count);
2664 vat_json_init_array (&root);
2665
2666 for (i = 0; i < n; i++)
2667 {
2668 e = vat_json_array_add (&root);
2669 a = &mp->adjacencies[i];
2670
2671 vat_json_init_object (e);
2672 s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2673 a->leid_prefix_len);
2674 vec_add1 (s, 0);
2675 vat_json_object_add_string_copy (e, "leid", s);
2676 vec_free (s);
2677
2678 s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2679 a->reid_prefix_len);
2680 vec_add1 (s, 0);
2681 vat_json_object_add_string_copy (e, "reid", s);
2682 vec_free (s);
2683 }
2684
2685 vat_json_print (vam->ofp, &root);
2686 vat_json_free (&root);
2687
2688end:
2689 vam->retval = retval;
2690 vam->result_ready = 1;
2691}
2692
2693static void
2694vl_api_lisp_map_server_details_t_handler (vl_api_lisp_map_server_details_t
2695 * mp)
2696{
2697 vat_main_t *vam = &vat_main;
2698
2699 print (vam->ofp, "%=20U",
2700 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2701 mp->ip_address);
2702}
2703
2704static void
2705 vl_api_lisp_map_server_details_t_handler_json
2706 (vl_api_lisp_map_server_details_t * mp)
2707{
2708 vat_main_t *vam = &vat_main;
2709 vat_json_node_t *node = NULL;
2710 struct in6_addr ip6;
2711 struct in_addr ip4;
2712
2713 if (VAT_JSON_ARRAY != vam->json_tree.type)
2714 {
2715 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2716 vat_json_init_array (&vam->json_tree);
2717 }
2718 node = vat_json_array_add (&vam->json_tree);
2719
2720 vat_json_init_object (node);
2721 if (mp->is_ipv6)
2722 {
2723 clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2724 vat_json_object_add_ip6 (node, "map-server", ip6);
2725 }
2726 else
2727 {
2728 clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2729 vat_json_object_add_ip4 (node, "map-server", ip4);
2730 }
2731}
2732
2733static void
2734vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2735 * mp)
2736{
2737 vat_main_t *vam = &vat_main;
2738
2739 print (vam->ofp, "%=20U",
2740 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2741 mp->ip_address);
2742}
2743
2744static void
2745 vl_api_lisp_map_resolver_details_t_handler_json
2746 (vl_api_lisp_map_resolver_details_t * mp)
2747{
2748 vat_main_t *vam = &vat_main;
2749 vat_json_node_t *node = NULL;
2750 struct in6_addr ip6;
2751 struct in_addr ip4;
2752
2753 if (VAT_JSON_ARRAY != vam->json_tree.type)
2754 {
2755 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2756 vat_json_init_array (&vam->json_tree);
2757 }
2758 node = vat_json_array_add (&vam->json_tree);
2759
2760 vat_json_init_object (node);
2761 if (mp->is_ipv6)
2762 {
2763 clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2764 vat_json_object_add_ip6 (node, "map resolver", ip6);
2765 }
2766 else
2767 {
2768 clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2769 vat_json_object_add_ip4 (node, "map resolver", ip4);
2770 }
2771}
2772
2773static void
2774 vl_api_show_lisp_status_reply_t_handler
2775 (vl_api_show_lisp_status_reply_t * mp)
2776{
2777 vat_main_t *vam = &vat_main;
2778 i32 retval = ntohl (mp->retval);
2779
2780 if (0 <= retval)
2781 {
2782 print (vam->ofp, "feature: %s\ngpe: %s",
2783 mp->feature_status ? "enabled" : "disabled",
2784 mp->gpe_status ? "enabled" : "disabled");
2785 }
2786
2787 vam->retval = retval;
2788 vam->result_ready = 1;
2789}
2790
2791static void
2792 vl_api_show_lisp_status_reply_t_handler_json
2793 (vl_api_show_lisp_status_reply_t * mp)
2794{
2795 vat_main_t *vam = &vat_main;
2796 vat_json_node_t node;
2797 u8 *gpe_status = NULL;
2798 u8 *feature_status = NULL;
2799
2800 gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2801 feature_status = format (0, "%s",
2802 mp->feature_status ? "enabled" : "disabled");
2803 vec_add1 (gpe_status, 0);
2804 vec_add1 (feature_status, 0);
2805
2806 vat_json_init_object (&node);
2807 vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2808 vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2809
2810 vec_free (gpe_status);
2811 vec_free (feature_status);
2812
2813 vat_json_print (vam->ofp, &node);
2814 vat_json_free (&node);
2815
2816 vam->retval = ntohl (mp->retval);
2817 vam->result_ready = 1;
2818}
2819
2820static void
2821 vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2822 (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2823{
2824 vat_main_t *vam = &vat_main;
2825 i32 retval = ntohl (mp->retval);
2826
2827 if (retval >= 0)
2828 {
2829 print (vam->ofp, "%=20s", mp->locator_set_name);
2830 }
2831
2832 vam->retval = retval;
2833 vam->result_ready = 1;
2834}
2835
2836static void
2837 vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2838 (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2839{
2840 vat_main_t *vam = &vat_main;
2841 vat_json_node_t *node = NULL;
2842
2843 if (VAT_JSON_ARRAY != vam->json_tree.type)
2844 {
2845 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2846 vat_json_init_array (&vam->json_tree);
2847 }
2848 node = vat_json_array_add (&vam->json_tree);
2849
2850 vat_json_init_object (node);
2851 vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2852
2853 vat_json_print (vam->ofp, node);
2854 vat_json_free (node);
2855
2856 vam->retval = ntohl (mp->retval);
2857 vam->result_ready = 1;
2858}
2859
2860static u8 *
2861format_lisp_map_request_mode (u8 * s, va_list * args)
2862{
2863 u32 mode = va_arg (*args, u32);
2864
2865 switch (mode)
2866 {
2867 case 0:
2868 return format (0, "dst-only");
2869 case 1:
2870 return format (0, "src-dst");
2871 }
2872 return 0;
2873}
2874
2875static void
2876 vl_api_show_lisp_map_request_mode_reply_t_handler
2877 (vl_api_show_lisp_map_request_mode_reply_t * mp)
2878{
2879 vat_main_t *vam = &vat_main;
2880 i32 retval = ntohl (mp->retval);
2881
2882 if (0 <= retval)
2883 {
2884 u32 mode = mp->mode;
2885 print (vam->ofp, "map_request_mode: %U",
2886 format_lisp_map_request_mode, mode);
2887 }
2888
2889 vam->retval = retval;
2890 vam->result_ready = 1;
2891}
2892
2893static void
2894 vl_api_show_lisp_map_request_mode_reply_t_handler_json
2895 (vl_api_show_lisp_map_request_mode_reply_t * mp)
2896{
2897 vat_main_t *vam = &vat_main;
2898 vat_json_node_t node;
2899 u8 *s = 0;
2900 u32 mode;
2901
2902 mode = mp->mode;
2903 s = format (0, "%U", format_lisp_map_request_mode, mode);
2904 vec_add1 (s, 0);
2905
2906 vat_json_init_object (&node);
2907 vat_json_object_add_string_copy (&node, "map_request_mode", s);
2908 vat_json_print (vam->ofp, &node);
2909 vat_json_free (&node);
2910
2911 vec_free (s);
2912 vam->retval = ntohl (mp->retval);
2913 vam->result_ready = 1;
2914}
2915
2916static void
2917vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2918{
2919 vat_main_t *vam = &vat_main;
2920 i32 retval = ntohl (mp->retval);
2921
2922 if (0 <= retval)
2923 {
2924 print (vam->ofp, "%-20s%-16s",
2925 mp->status ? "enabled" : "disabled",
2926 mp->status ? (char *) mp->locator_set_name : "");
2927 }
2928
2929 vam->retval = retval;
2930 vam->result_ready = 1;
2931}
2932
2933static void
2934vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2935 mp)
2936{
2937 vat_main_t *vam = &vat_main;
2938 vat_json_node_t node;
2939 u8 *status = 0;
2940
2941 status = format (0, "%s", mp->status ? "enabled" : "disabled");
2942 vec_add1 (status, 0);
2943
2944 vat_json_init_object (&node);
2945 vat_json_object_add_string_copy (&node, "status", status);
2946 if (mp->status)
2947 {
2948 vat_json_object_add_string_copy (&node, "locator_set",
2949 mp->locator_set_name);
2950 }
2951
2952 vec_free (status);
2953
2954 vat_json_print (vam->ofp, &node);
2955 vat_json_free (&node);
2956
2957 vam->retval = ntohl (mp->retval);
2958 vam->result_ready = 1;
2959}
2960
2961static u8 *
2962format_policer_type (u8 * s, va_list * va)
2963{
2964 u32 i = va_arg (*va, u32);
2965
2966 if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2967 s = format (s, "1r2c");
2968 else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2969 s = format (s, "1r3c");
2970 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2971 s = format (s, "2r3c-2698");
2972 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2973 s = format (s, "2r3c-4115");
2974 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2975 s = format (s, "2r3c-mef5cf1");
2976 else
2977 s = format (s, "ILLEGAL");
2978 return s;
2979}
2980
2981static u8 *
2982format_policer_rate_type (u8 * s, va_list * va)
2983{
2984 u32 i = va_arg (*va, u32);
2985
2986 if (i == SSE2_QOS_RATE_KBPS)
2987 s = format (s, "kbps");
2988 else if (i == SSE2_QOS_RATE_PPS)
2989 s = format (s, "pps");
2990 else
2991 s = format (s, "ILLEGAL");
2992 return s;
2993}
2994
2995static u8 *
2996format_policer_round_type (u8 * s, va_list * va)
2997{
2998 u32 i = va_arg (*va, u32);
2999
3000 if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3001 s = format (s, "closest");
3002 else if (i == SSE2_QOS_ROUND_TO_UP)
3003 s = format (s, "up");
3004 else if (i == SSE2_QOS_ROUND_TO_DOWN)
3005 s = format (s, "down");
3006 else
3007 s = format (s, "ILLEGAL");
3008 return s;
3009}
3010
3011static u8 *
3012format_policer_action_type (u8 * s, va_list * va)
3013{
3014 u32 i = va_arg (*va, u32);
3015
3016 if (i == SSE2_QOS_ACTION_DROP)
3017 s = format (s, "drop");
3018 else if (i == SSE2_QOS_ACTION_TRANSMIT)
3019 s = format (s, "transmit");
3020 else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3021 s = format (s, "mark-and-transmit");
3022 else
3023 s = format (s, "ILLEGAL");
3024 return s;
3025}
3026
3027static u8 *
3028format_dscp (u8 * s, va_list * va)
3029{
3030 u32 i = va_arg (*va, u32);
3031 char *t = 0;
3032
3033 switch (i)
3034 {
3035#define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3036 foreach_vnet_dscp
3037#undef _
3038 default:
3039 return format (s, "ILLEGAL");
3040 }
3041 s = format (s, "%s", t);
3042 return s;
3043}
3044
3045static void
3046vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3047{
3048 vat_main_t *vam = &vat_main;
3049 u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3050
3051 if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3052 conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3053 else
3054 conform_dscp_str = format (0, "");
3055
3056 if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3057 exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3058 else
3059 exceed_dscp_str = format (0, "");
3060
3061 if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3062 violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3063 else
3064 violate_dscp_str = format (0, "");
3065
3066 print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3067 "rate type %U, round type %U, %s rate, %s color-aware, "
3068 "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3069 "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3070 "conform action %U%s, exceed action %U%s, violate action %U%s",
3071 mp->name,
3072 format_policer_type, mp->type,
3073 ntohl (mp->cir),
3074 ntohl (mp->eir),
3075 clib_net_to_host_u64 (mp->cb),
3076 clib_net_to_host_u64 (mp->eb),
3077 format_policer_rate_type, mp->rate_type,
3078 format_policer_round_type, mp->round_type,
3079 mp->single_rate ? "single" : "dual",
3080 mp->color_aware ? "is" : "not",
3081 ntohl (mp->cir_tokens_per_period),
3082 ntohl (mp->pir_tokens_per_period),
3083 ntohl (mp->scale),
3084 ntohl (mp->current_limit),
3085 ntohl (mp->current_bucket),
3086 ntohl (mp->extended_limit),
3087 ntohl (mp->extended_bucket),
3088 clib_net_to_host_u64 (mp->last_update_time),
3089 format_policer_action_type, mp->conform_action_type,
3090 conform_dscp_str,
3091 format_policer_action_type, mp->exceed_action_type,
3092 exceed_dscp_str,
3093 format_policer_action_type, mp->violate_action_type,
3094 violate_dscp_str);
3095
3096 vec_free (conform_dscp_str);
3097 vec_free (exceed_dscp_str);
3098 vec_free (violate_dscp_str);
3099}
3100
3101static void vl_api_policer_details_t_handler_json
3102 (vl_api_policer_details_t * mp)
3103{
3104 vat_main_t *vam = &vat_main;
3105 vat_json_node_t *node;
3106 u8 *rate_type_str, *round_type_str, *type_str;
3107 u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3108
3109 rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3110 round_type_str =
3111 format (0, "%U", format_policer_round_type, mp->round_type);
3112 type_str = format (0, "%U", format_policer_type, mp->type);
3113 conform_action_str = format (0, "%U", format_policer_action_type,
3114 mp->conform_action_type);
3115 exceed_action_str = format (0, "%U", format_policer_action_type,
3116 mp->exceed_action_type);
3117 violate_action_str = format (0, "%U", format_policer_action_type,
3118 mp->violate_action_type);
3119
3120 if (VAT_JSON_ARRAY != vam->json_tree.type)
3121 {
3122 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3123 vat_json_init_array (&vam->json_tree);
3124 }
3125 node = vat_json_array_add (&vam->json_tree);
3126
3127 vat_json_init_object (node);
3128 vat_json_object_add_string_copy (node, "name", mp->name);
3129 vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3130 vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3131 vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3132 vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3133 vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3134 vat_json_object_add_string_copy (node, "round_type", round_type_str);
3135 vat_json_object_add_string_copy (node, "type", type_str);
3136 vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3137 vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3138 vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3139 vat_json_object_add_uint (node, "cir_tokens_per_period",
3140 ntohl (mp->cir_tokens_per_period));
3141 vat_json_object_add_uint (node, "eir_tokens_per_period",
3142 ntohl (mp->pir_tokens_per_period));
3143 vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3144 vat_json_object_add_uint (node, "current_bucket",
3145 ntohl (mp->current_bucket));
3146 vat_json_object_add_uint (node, "extended_limit",
3147 ntohl (mp->extended_limit));
3148 vat_json_object_add_uint (node, "extended_bucket",
3149 ntohl (mp->extended_bucket));
3150 vat_json_object_add_uint (node, "last_update_time",
3151 ntohl (mp->last_update_time));
3152 vat_json_object_add_string_copy (node, "conform_action",
3153 conform_action_str);
3154 if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3155 {
3156 u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3157 vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3158 vec_free (dscp_str);
3159 }
3160 vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3161 if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3162 {
3163 u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3164 vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3165 vec_free (dscp_str);
3166 }
3167 vat_json_object_add_string_copy (node, "violate_action",
3168 violate_action_str);
3169 if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3170 {
3171 u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3172 vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3173 vec_free (dscp_str);
3174 }
3175
3176 vec_free (rate_type_str);
3177 vec_free (round_type_str);
3178 vec_free (type_str);
3179 vec_free (conform_action_str);
3180 vec_free (exceed_action_str);
3181 vec_free (violate_action_str);
3182}
3183
3184static void
3185vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3186 mp)
3187{
3188 vat_main_t *vam = &vat_main;
3189 int i, count = ntohl (mp->count);
3190
3191 if (count > 0)
3192 print (vam->ofp, "classify table ids (%d) : ", count);
3193 for (i = 0; i < count; i++)
3194 {
3195 print (vam->ofp, "%d", ntohl (mp->ids[i]));
3196 print (vam->ofp, (i < count - 1) ? "," : "");
3197 }
3198 vam->retval = ntohl (mp->retval);
3199 vam->result_ready = 1;
3200}
3201
3202static void
3203 vl_api_classify_table_ids_reply_t_handler_json
3204 (vl_api_classify_table_ids_reply_t * mp)
3205{
3206 vat_main_t *vam = &vat_main;
3207 int i, count = ntohl (mp->count);
3208
3209 if (count > 0)
3210 {
3211 vat_json_node_t node;
3212
3213 vat_json_init_object (&node);
3214 for (i = 0; i < count; i++)
3215 {
3216 vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3217 }
3218 vat_json_print (vam->ofp, &node);
3219 vat_json_free (&node);
3220 }
3221 vam->retval = ntohl (mp->retval);
3222 vam->result_ready = 1;
3223}
3224
3225static void
3226 vl_api_classify_table_by_interface_reply_t_handler
3227 (vl_api_classify_table_by_interface_reply_t * mp)
3228{
3229 vat_main_t *vam = &vat_main;
3230 u32 table_id;
3231
3232 table_id = ntohl (mp->l2_table_id);
3233 if (table_id != ~0)
3234 print (vam->ofp, "l2 table id : %d", table_id);
3235 else
3236 print (vam->ofp, "l2 table id : No input ACL tables configured");
3237 table_id = ntohl (mp->ip4_table_id);
3238 if (table_id != ~0)
3239 print (vam->ofp, "ip4 table id : %d", table_id);
3240 else
3241 print (vam->ofp, "ip4 table id : No input ACL tables configured");
3242 table_id = ntohl (mp->ip6_table_id);
3243 if (table_id != ~0)
3244 print (vam->ofp, "ip6 table id : %d", table_id);
3245 else
3246 print (vam->ofp, "ip6 table id : No input ACL tables configured");
3247 vam->retval = ntohl (mp->retval);
3248 vam->result_ready = 1;
3249}
3250
3251static void
3252 vl_api_classify_table_by_interface_reply_t_handler_json
3253 (vl_api_classify_table_by_interface_reply_t * mp)
3254{
3255 vat_main_t *vam = &vat_main;
3256 vat_json_node_t node;
3257
3258 vat_json_init_object (&node);
3259
3260 vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3261 vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3262 vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3263
3264 vat_json_print (vam->ofp, &node);
3265 vat_json_free (&node);
3266
3267 vam->retval = ntohl (mp->retval);
3268 vam->result_ready = 1;
3269}
3270
3271static void vl_api_policer_add_del_reply_t_handler
3272 (vl_api_policer_add_del_reply_t * mp)
3273{
3274 vat_main_t *vam = &vat_main;
3275 i32 retval = ntohl (mp->retval);
3276 if (vam->async_mode)
3277 {
3278 vam->async_errors += (retval < 0);
3279 }
3280 else
3281 {
3282 vam->retval = retval;
3283 vam->result_ready = 1;
3284 if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3285 /*
3286 * Note: this is just barely thread-safe, depends on
3287 * the main thread spinning waiting for an answer...
3288 */
3289 errmsg ("policer index %d", ntohl (mp->policer_index));
3290 }
3291}
3292
3293static void vl_api_policer_add_del_reply_t_handler_json
3294 (vl_api_policer_add_del_reply_t * mp)
3295{
3296 vat_main_t *vam = &vat_main;
3297 vat_json_node_t node;
3298
3299 vat_json_init_object (&node);
3300 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3301 vat_json_object_add_uint (&node, "policer_index",
3302 ntohl (mp->policer_index));
3303
3304 vat_json_print (vam->ofp, &node);
3305 vat_json_free (&node);
3306
3307 vam->retval = ntohl (mp->retval);
3308 vam->result_ready = 1;
3309}
3310
3311/* Format hex dump. */
3312u8 *
3313format_hex_bytes (u8 * s, va_list * va)
3314{
3315 u8 *bytes = va_arg (*va, u8 *);
3316 int n_bytes = va_arg (*va, int);
3317 uword i;
3318
3319 /* Print short or long form depending on byte count. */
3320 uword short_form = n_bytes <= 32;
3321 uword indent = format_get_indent (s);
3322
3323 if (n_bytes == 0)
3324 return s;
3325
3326 for (i = 0; i < n_bytes; i++)
3327 {
3328 if (!short_form && (i % 32) == 0)
3329 s = format (s, "%08x: ", i);
3330 s = format (s, "%02x", bytes[i]);
3331 if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3332 s = format (s, "\n%U", format_white_space, indent);
3333 }
3334
3335 return s;
3336}
3337
3338static void
3339vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3340 * mp)
3341{
3342 vat_main_t *vam = &vat_main;
3343 i32 retval = ntohl (mp->retval);
3344 if (retval == 0)
3345 {
3346 print (vam->ofp, "classify table info :");
3347 print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3348 ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3349 ntohl (mp->miss_next_index));
3350 print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3351 ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3352 ntohl (mp->match_n_vectors));
3353 print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3354 ntohl (mp->mask_length));
3355 }
3356 vam->retval = retval;
3357 vam->result_ready = 1;
3358}
3359
3360static void
3361 vl_api_classify_table_info_reply_t_handler_json
3362 (vl_api_classify_table_info_reply_t * mp)
3363{
3364 vat_main_t *vam = &vat_main;
3365 vat_json_node_t node;
3366
3367 i32 retval = ntohl (mp->retval);
3368 if (retval == 0)
3369 {
3370 vat_json_init_object (&node);
3371
3372 vat_json_object_add_int (&node, "sessions",
3373 ntohl (mp->active_sessions));
3374 vat_json_object_add_int (&node, "nexttbl",
3375 ntohl (mp->next_table_index));
3376 vat_json_object_add_int (&node, "nextnode",
3377 ntohl (mp->miss_next_index));
3378 vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3379 vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3380 vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3381 u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3382 ntohl (mp->mask_length), 0);
3383 vat_json_object_add_string_copy (&node, "mask", s);
3384
3385 vat_json_print (vam->ofp, &node);
3386 vat_json_free (&node);
3387 }
3388 vam->retval = ntohl (mp->retval);
3389 vam->result_ready = 1;
3390}
3391
3392static void
3393vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3394 mp)
3395{
3396 vat_main_t *vam = &vat_main;
3397
3398 print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3399 ntohl (mp->hit_next_index), ntohl (mp->advance),
3400 ntohl (mp->opaque_index));
3401 print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3402 ntohl (mp->match_length));
3403}
3404
3405static void
3406 vl_api_classify_session_details_t_handler_json
3407 (vl_api_classify_session_details_t * mp)
3408{
3409 vat_main_t *vam = &vat_main;
3410 vat_json_node_t *node = NULL;
3411
3412 if (VAT_JSON_ARRAY != vam->json_tree.type)
3413 {
3414 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3415 vat_json_init_array (&vam->json_tree);
3416 }
3417 node = vat_json_array_add (&vam->json_tree);
3418
3419 vat_json_init_object (node);
3420 vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3421 vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3422 vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3423 u8 *s =
3424 format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3425 0);
3426 vat_json_object_add_string_copy (node, "match", s);
3427}
3428
3429static void vl_api_pg_create_interface_reply_t_handler
3430 (vl_api_pg_create_interface_reply_t * mp)
3431{
3432 vat_main_t *vam = &vat_main;
3433
3434 vam->retval = ntohl (mp->retval);
3435 vam->result_ready = 1;
3436}
3437
3438static void vl_api_pg_create_interface_reply_t_handler_json
3439 (vl_api_pg_create_interface_reply_t * mp)
3440{
3441 vat_main_t *vam = &vat_main;
3442 vat_json_node_t node;
3443
3444 i32 retval = ntohl (mp->retval);
3445 if (retval == 0)
3446 {
3447 vat_json_init_object (&node);
3448
3449 vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3450
3451 vat_json_print (vam->ofp, &node);
3452 vat_json_free (&node);
3453 }
3454 vam->retval = ntohl (mp->retval);
3455 vam->result_ready = 1;
3456}
3457
3458static void vl_api_policer_classify_details_t_handler
3459 (vl_api_policer_classify_details_t * mp)
3460{
3461 vat_main_t *vam = &vat_main;
3462
3463 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3464 ntohl (mp->table_index));
3465}
3466
3467static void vl_api_policer_classify_details_t_handler_json
3468 (vl_api_policer_classify_details_t * mp)
3469{
3470 vat_main_t *vam = &vat_main;
3471 vat_json_node_t *node;
3472
3473 if (VAT_JSON_ARRAY != vam->json_tree.type)
3474 {
3475 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3476 vat_json_init_array (&vam->json_tree);
3477 }
3478 node = vat_json_array_add (&vam->json_tree);
3479
3480 vat_json_init_object (node);
3481 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3482 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3483}
3484
3485static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3486 (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3487{
3488 vat_main_t *vam = &vat_main;
3489 i32 retval = ntohl (mp->retval);
3490 if (vam->async_mode)
3491 {
3492 vam->async_errors += (retval < 0);
3493 }
3494 else
3495 {
3496 vam->retval = retval;
3497 vam->sw_if_index = ntohl (mp->sw_if_index);
3498 vam->result_ready = 1;
3499 }
3500}
3501
3502static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3503 (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3504{
3505 vat_main_t *vam = &vat_main;
3506 vat_json_node_t node;
3507
3508 vat_json_init_object (&node);
3509 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3510 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3511
3512 vat_json_print (vam->ofp, &node);
3513 vat_json_free (&node);
3514
3515 vam->retval = ntohl (mp->retval);
3516 vam->result_ready = 1;
3517}
3518
3519static void vl_api_flow_classify_details_t_handler
3520 (vl_api_flow_classify_details_t * mp)
3521{
3522 vat_main_t *vam = &vat_main;
3523
3524 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3525 ntohl (mp->table_index));
3526}
3527
3528static void vl_api_flow_classify_details_t_handler_json
3529 (vl_api_flow_classify_details_t * mp)
3530{
3531 vat_main_t *vam = &vat_main;
3532 vat_json_node_t *node;
3533
3534 if (VAT_JSON_ARRAY != vam->json_tree.type)
3535 {
3536 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3537 vat_json_init_array (&vam->json_tree);
3538 }
3539 node = vat_json_array_add (&vam->json_tree);
3540
3541 vat_json_init_object (node);
3542 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3543 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3544}
3545
3546
3547
3548#define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3549#define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3550#define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3551#define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3552#define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3553#define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3554
3555/*
3556 * Generate boilerplate reply handlers, which
3557 * dig the return value out of the xxx_reply_t API message,
3558 * stick it into vam->retval, and set vam->result_ready
3559 *
3560 * Could also do this by pointing N message decode slots at
3561 * a single function, but that could break in subtle ways.
3562 */
3563
3564#define foreach_standard_reply_retval_handler \
3565_(sw_interface_set_flags_reply) \
3566_(sw_interface_add_del_address_reply) \
3567_(sw_interface_set_table_reply) \
3568_(sw_interface_set_mpls_enable_reply) \
3569_(sw_interface_set_vpath_reply) \
3570_(sw_interface_set_vxlan_bypass_reply) \
3571_(sw_interface_set_l2_bridge_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003572_(bridge_domain_add_del_reply) \
3573_(sw_interface_set_l2_xconnect_reply) \
3574_(l2fib_add_del_reply) \
3575_(ip_add_del_route_reply) \
3576_(mpls_route_add_del_reply) \
3577_(mpls_ip_bind_unbind_reply) \
3578_(proxy_arp_add_del_reply) \
3579_(proxy_arp_intfc_enable_disable_reply) \
3580_(sw_interface_set_unnumbered_reply) \
3581_(ip_neighbor_add_del_reply) \
3582_(reset_vrf_reply) \
3583_(oam_add_del_reply) \
3584_(reset_fib_reply) \
3585_(dhcp_proxy_config_reply) \
3586_(dhcp_proxy_config_2_reply) \
3587_(dhcp_proxy_set_vss_reply) \
3588_(dhcp_client_config_reply) \
3589_(set_ip_flow_hash_reply) \
3590_(sw_interface_ip6_enable_disable_reply) \
3591_(sw_interface_ip6_set_link_local_address_reply) \
3592_(sw_interface_ip6nd_ra_prefix_reply) \
3593_(sw_interface_ip6nd_ra_config_reply) \
3594_(set_arp_neighbor_limit_reply) \
3595_(l2_patch_add_del_reply) \
3596_(sr_tunnel_add_del_reply) \
3597_(sr_policy_add_del_reply) \
3598_(sr_multicast_map_add_del_reply) \
3599_(classify_add_del_session_reply) \
3600_(classify_set_interface_ip_table_reply) \
3601_(classify_set_interface_l2_tables_reply) \
3602_(l2tpv3_set_tunnel_cookies_reply) \
3603_(l2tpv3_interface_enable_disable_reply) \
3604_(l2tpv3_set_lookup_key_reply) \
3605_(l2_fib_clear_table_reply) \
3606_(l2_interface_efp_filter_reply) \
3607_(l2_interface_vlan_tag_rewrite_reply) \
3608_(modify_vhost_user_if_reply) \
3609_(delete_vhost_user_if_reply) \
3610_(want_ip4_arp_events_reply) \
3611_(want_ip6_nd_events_reply) \
3612_(input_acl_set_interface_reply) \
3613_(ipsec_spd_add_del_reply) \
3614_(ipsec_interface_add_del_spd_reply) \
3615_(ipsec_spd_add_del_entry_reply) \
3616_(ipsec_sad_add_del_entry_reply) \
3617_(ipsec_sa_set_key_reply) \
3618_(ikev2_profile_add_del_reply) \
3619_(ikev2_profile_set_auth_reply) \
3620_(ikev2_profile_set_id_reply) \
3621_(ikev2_profile_set_ts_reply) \
3622_(ikev2_set_local_key_reply) \
3623_(delete_loopback_reply) \
3624_(bd_ip_mac_add_del_reply) \
3625_(map_del_domain_reply) \
3626_(map_add_del_rule_reply) \
3627_(want_interface_events_reply) \
3628_(want_stats_reply) \
3629_(cop_interface_enable_disable_reply) \
3630_(cop_whitelist_enable_disable_reply) \
3631_(sw_interface_clear_stats_reply) \
3632_(ioam_enable_reply) \
3633_(ioam_disable_reply) \
3634_(lisp_add_del_locator_reply) \
3635_(lisp_add_del_local_eid_reply) \
3636_(lisp_add_del_remote_mapping_reply) \
3637_(lisp_add_del_adjacency_reply) \
3638_(lisp_gpe_add_del_fwd_entry_reply) \
3639_(lisp_add_del_map_resolver_reply) \
3640_(lisp_add_del_map_server_reply) \
3641_(lisp_gpe_enable_disable_reply) \
3642_(lisp_gpe_add_del_iface_reply) \
3643_(lisp_enable_disable_reply) \
3644_(lisp_rloc_probe_enable_disable_reply) \
3645_(lisp_map_register_enable_disable_reply) \
3646_(lisp_pitr_set_locator_set_reply) \
3647_(lisp_map_request_mode_reply) \
3648_(lisp_add_del_map_request_itr_rlocs_reply) \
3649_(lisp_eid_table_add_del_map_reply) \
3650_(vxlan_gpe_add_del_tunnel_reply) \
3651_(af_packet_delete_reply) \
3652_(policer_classify_set_interface_reply) \
3653_(netmap_create_reply) \
3654_(netmap_delete_reply) \
3655_(set_ipfix_exporter_reply) \
3656_(set_ipfix_classify_stream_reply) \
3657_(ipfix_classify_table_add_del_reply) \
3658_(flow_classify_set_interface_reply) \
3659_(sw_interface_span_enable_disable_reply) \
3660_(pg_capture_reply) \
3661_(pg_enable_disable_reply) \
3662_(ip_source_and_port_range_check_add_del_reply) \
3663_(ip_source_and_port_range_check_interface_add_del_reply)\
3664_(delete_subif_reply) \
3665_(l2_interface_pbb_tag_rewrite_reply) \
3666_(punt_reply) \
3667_(feature_enable_disable_reply) \
3668_(sw_interface_tag_add_del_reply) \
3669_(sw_interface_set_mtu_reply)
3670
Pavel Kotucek738f3f22017-01-09 15:11:03 +01003671#if DPDK > 0
3672#define foreach_standard_dpdk_reply_retval_handler \
3673_(sw_interface_set_dpdk_hqos_pipe_reply) \
3674_(sw_interface_set_dpdk_hqos_subport_reply) \
3675_(sw_interface_set_dpdk_hqos_tctbl_reply)
3676#endif
3677
Damjan Marion7cd468a2016-12-19 23:05:39 +01003678#define _(n) \
3679 static void vl_api_##n##_t_handler \
3680 (vl_api_##n##_t * mp) \
3681 { \
3682 vat_main_t * vam = &vat_main; \
3683 i32 retval = ntohl(mp->retval); \
3684 if (vam->async_mode) { \
3685 vam->async_errors += (retval < 0); \
3686 } else { \
3687 vam->retval = retval; \
3688 vam->result_ready = 1; \
3689 } \
3690 }
3691foreach_standard_reply_retval_handler;
3692#undef _
3693
3694#define _(n) \
3695 static void vl_api_##n##_t_handler_json \
3696 (vl_api_##n##_t * mp) \
3697 { \
3698 vat_main_t * vam = &vat_main; \
3699 vat_json_node_t node; \
3700 vat_json_init_object(&node); \
3701 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
3702 vat_json_print(vam->ofp, &node); \
3703 vam->retval = ntohl(mp->retval); \
3704 vam->result_ready = 1; \
3705 }
3706foreach_standard_reply_retval_handler;
3707#undef _
3708
Pavel Kotucek738f3f22017-01-09 15:11:03 +01003709#if DPDK > 0
3710#define _(n) \
3711 static void vl_api_##n##_t_handler \
3712 (vl_api_##n##_t * mp) \
3713 { \
3714 vat_main_t * vam = &vat_main; \
3715 i32 retval = ntohl(mp->retval); \
3716 if (vam->async_mode) { \
3717 vam->async_errors += (retval < 0); \
3718 } else { \
3719 vam->retval = retval; \
3720 vam->result_ready = 1; \
3721 } \
3722 }
3723foreach_standard_dpdk_reply_retval_handler;
3724#undef _
3725
3726#define _(n) \
3727 static void vl_api_##n##_t_handler_json \
3728 (vl_api_##n##_t * mp) \
3729 { \
3730 vat_main_t * vam = &vat_main; \
3731 vat_json_node_t node; \
3732 vat_json_init_object(&node); \
3733 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
3734 vat_json_print(vam->ofp, &node); \
3735 vam->retval = ntohl(mp->retval); \
3736 vam->result_ready = 1; \
3737 }
3738foreach_standard_dpdk_reply_retval_handler;
3739#undef _
3740#endif
3741
Damjan Marion7cd468a2016-12-19 23:05:39 +01003742/*
3743 * Table of message reply handlers, must include boilerplate handlers
3744 * we just generated
3745 */
3746
3747#define foreach_vpe_api_reply_msg \
3748_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
3749_(SW_INTERFACE_DETAILS, sw_interface_details) \
3750_(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \
3751_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
3752_(CONTROL_PING_REPLY, control_ping_reply) \
3753_(CLI_REPLY, cli_reply) \
3754_(CLI_INBAND_REPLY, cli_inband_reply) \
3755_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
3756 sw_interface_add_del_address_reply) \
3757_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
3758_(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3759_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
3760_(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3761_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
3762 sw_interface_set_l2_xconnect_reply) \
3763_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
3764 sw_interface_set_l2_bridge_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003765_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
3766_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
3767_(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details) \
3768_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
3769_(L2_FLAGS_REPLY, l2_flags_reply) \
3770_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
3771_(TAP_CONNECT_REPLY, tap_connect_reply) \
3772_(TAP_MODIFY_REPLY, tap_modify_reply) \
3773_(TAP_DELETE_REPLY, tap_delete_reply) \
3774_(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details) \
3775_(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply) \
3776_(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply) \
3777_(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply) \
3778_(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply) \
3779_(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY, \
3780 proxy_arp_intfc_enable_disable_reply) \
3781_(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply) \
3782_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
3783 sw_interface_set_unnumbered_reply) \
3784_(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply) \
3785_(RESET_VRF_REPLY, reset_vrf_reply) \
3786_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
3787_(CREATE_SUBIF_REPLY, create_subif_reply) \
3788_(OAM_ADD_DEL_REPLY, oam_add_del_reply) \
3789_(RESET_FIB_REPLY, reset_fib_reply) \
3790_(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply) \
3791_(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply) \
3792_(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply) \
3793_(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply) \
3794_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
3795_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
3796 sw_interface_ip6_enable_disable_reply) \
3797_(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY, \
3798 sw_interface_ip6_set_link_local_address_reply) \
3799_(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY, \
3800 sw_interface_ip6nd_ra_prefix_reply) \
3801_(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY, \
3802 sw_interface_ip6nd_ra_config_reply) \
3803_(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply) \
3804_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
3805_(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply) \
3806_(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply) \
3807_(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply) \
3808_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \
3809_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \
3810_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \
3811classify_set_interface_ip_table_reply) \
3812_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY, \
3813 classify_set_interface_l2_tables_reply) \
3814_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
3815_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
3816_(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply) \
3817_(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply) \
3818_(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY, \
3819 l2tpv3_interface_enable_disable_reply) \
3820_(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply) \
3821_(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details) \
3822_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
3823_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
3824_(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply) \
3825_(GRE_TUNNEL_DETAILS, gre_tunnel_details) \
3826_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
3827_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
3828_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3829_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
3830_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply) \
3831_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply) \
3832_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply) \
3833_(SHOW_VERSION_REPLY, show_version_reply) \
3834_(L2_FIB_TABLE_ENTRY, l2_fib_table_entry) \
3835_(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply) \
3836_(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details) \
3837_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
3838_(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply) \
3839_(IP4_ARP_EVENT, ip4_arp_event) \
3840_(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply) \
3841_(IP6_ND_EVENT, ip6_nd_event) \
3842_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply) \
3843_(IP_ADDRESS_DETAILS, ip_address_details) \
3844_(IP_DETAILS, ip_details) \
3845_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \
3846_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3847_(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply) \
3848_(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply) \
3849_(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply) \
3850_(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply) \
3851_(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply) \
3852_(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply) \
3853_(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply) \
3854_(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply) \
3855_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
3856_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
3857_(DHCP_COMPL_EVENT, dhcp_compl_event) \
3858_(VNET_INTERFACE_COUNTERS, vnet_interface_counters) \
3859_(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters) \
3860_(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters) \
3861_(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply) \
3862_(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply) \
3863_(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply) \
3864_(MAP_DOMAIN_DETAILS, map_domain_details) \
3865_(MAP_RULE_DETAILS, map_rule_details) \
3866_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
3867_(WANT_STATS_REPLY, want_stats_reply) \
3868_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
3869_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3870_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3871_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
3872_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
3873_(IOAM_ENABLE_REPLY, ioam_enable_reply) \
3874_(IOAM_DISABLE_REPLY, ioam_disable_reply) \
3875_(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply) \
3876_(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply) \
3877_(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply) \
3878_(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3879_(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply) \
3880_(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply) \
3881_(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply) \
3882_(LISP_ADD_DEL_MAP_SERVER_REPLY, lisp_add_del_map_server_reply) \
3883_(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply) \
3884_(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply) \
3885_(LISP_MAP_REGISTER_ENABLE_DISABLE_REPLY, \
3886 lisp_map_register_enable_disable_reply) \
3887_(LISP_RLOC_PROBE_ENABLE_DISABLE_REPLY, \
3888 lisp_rloc_probe_enable_disable_reply) \
3889_(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply) \
3890_(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply) \
3891_(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply) \
3892_(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply) \
3893_(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details) \
3894_(LISP_LOCATOR_DETAILS, lisp_locator_details) \
3895_(LISP_EID_TABLE_DETAILS, lisp_eid_table_details) \
3896_(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details) \
3897_(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details) \
3898_(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details) \
3899_(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details) \
3900_(LISP_MAP_SERVER_DETAILS, lisp_map_server_details) \
3901_(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply) \
3902_(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply) \
3903_(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY, \
3904 lisp_add_del_map_request_itr_rlocs_reply) \
3905_(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY, \
3906 lisp_get_map_request_itr_rlocs_reply) \
3907_(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply) \
3908_(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply) \
3909_(SHOW_LISP_RLOC_PROBE_STATE_REPLY, show_lisp_rloc_probe_state_reply) \
3910_(SHOW_LISP_MAP_REGISTER_STATE_REPLY, \
3911 show_lisp_map_register_state_reply) \
3912_(AF_PACKET_CREATE_REPLY, af_packet_create_reply) \
3913_(AF_PACKET_DELETE_REPLY, af_packet_delete_reply) \
3914_(POLICER_ADD_DEL_REPLY, policer_add_del_reply) \
3915_(POLICER_DETAILS, policer_details) \
3916_(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3917_(POLICER_CLASSIFY_DETAILS, policer_classify_details) \
3918_(NETMAP_CREATE_REPLY, netmap_create_reply) \
3919_(NETMAP_DELETE_REPLY, netmap_delete_reply) \
3920_(MPLS_TUNNEL_DETAILS, mpls_tunnel_details) \
3921_(MPLS_FIB_DETAILS, mpls_fib_details) \
3922_(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply) \
3923_(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3924_(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply) \
3925_(CLASSIFY_SESSION_DETAILS, classify_session_details) \
3926_(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply) \
3927_(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details) \
3928_(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply) \
3929_(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details) \
3930_(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3931_(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details) \
3932_(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3933_(FLOW_CLASSIFY_DETAILS, flow_classify_details) \
3934_(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3935_(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details) \
3936_(GET_NEXT_INDEX_REPLY, get_next_index_reply) \
3937_(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply) \
3938_(PG_CAPTURE_REPLY, pg_capture_reply) \
3939_(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply) \
3940_(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY, \
3941 ip_source_and_port_range_check_add_del_reply) \
3942_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY, \
3943 ip_source_and_port_range_check_interface_add_del_reply) \
3944_(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply) \
3945_(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details) \
3946_(DELETE_SUBIF_REPLY, delete_subif_reply) \
3947_(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3948_(PUNT_REPLY, punt_reply) \
3949_(IP_FIB_DETAILS, ip_fib_details) \
3950_(IP6_FIB_DETAILS, ip6_fib_details) \
3951_(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply) \
3952_(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply) \
3953_(L2_XCONNECT_DETAILS, l2_xconnect_details) \
3954_(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply) \
3955_(IP_NEIGHBOR_DETAILS, ip_neighbor_details) \
3956_(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
3957
Pavel Kotucek738f3f22017-01-09 15:11:03 +01003958#if DPDK > 0
3959#define foreach_vpe_dpdk_api_reply_msg \
3960_(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY, \
3961 sw_interface_set_dpdk_hqos_pipe_reply) \
3962_(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY, \
3963 sw_interface_set_dpdk_hqos_subport_reply) \
3964_(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY, \
3965 sw_interface_set_dpdk_hqos_tctbl_reply)
3966#endif
3967
Damjan Marion7cd468a2016-12-19 23:05:39 +01003968/* M: construct, but don't yet send a message */
3969
3970#define M(T,t) \
3971do { \
3972 vam->result_ready = 0; \
3973 mp = vl_msg_api_alloc_as_if_client(sizeof(*mp)); \
3974 memset (mp, 0, sizeof (*mp)); \
3975 mp->_vl_msg_id = ntohs (VL_API_##T); \
3976 mp->client_index = vam->my_client_index; \
3977} while(0);
3978
3979#define M2(T,t,n) \
3980do { \
3981 vam->result_ready = 0; \
3982 mp = vl_msg_api_alloc_as_if_client(sizeof(*mp)+(n)); \
3983 memset (mp, 0, sizeof (*mp)); \
3984 mp->_vl_msg_id = ntohs (VL_API_##T); \
3985 mp->client_index = vam->my_client_index; \
3986} while(0);
3987
3988
3989/* S: send a message */
3990#define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3991
3992/* W: wait for results, with timeout */
3993#define W \
3994do { \
3995 timeout = vat_time_now (vam) + 1.0; \
3996 \
3997 while (vat_time_now (vam) < timeout) { \
3998 if (vam->result_ready == 1) { \
3999 return (vam->retval); \
4000 } \
4001 vat_suspend (vam->vlib_main, 1e-3); \
4002 } \
4003 return -99; \
4004} while(0);
4005
4006/* W2: wait for results, with timeout */
4007#define W2(body) \
4008do { \
4009 timeout = vat_time_now (vam) + 1.0; \
4010 \
4011 while (vat_time_now (vam) < timeout) { \
4012 if (vam->result_ready == 1) { \
4013 (body); \
4014 return (vam->retval); \
4015 } \
4016 vat_suspend (vam->vlib_main, 1e-3); \
4017 } \
4018 return -99; \
4019} while(0);
4020
4021typedef struct
4022{
4023 u8 *name;
4024 u32 value;
4025} name_sort_t;
4026
4027
4028#define STR_VTR_OP_CASE(op) \
4029 case L2_VTR_ ## op: \
4030 return "" # op;
4031
4032static const char *
4033str_vtr_op (u32 vtr_op)
4034{
4035 switch (vtr_op)
4036 {
4037 STR_VTR_OP_CASE (DISABLED);
4038 STR_VTR_OP_CASE (PUSH_1);
4039 STR_VTR_OP_CASE (PUSH_2);
4040 STR_VTR_OP_CASE (POP_1);
4041 STR_VTR_OP_CASE (POP_2);
4042 STR_VTR_OP_CASE (TRANSLATE_1_1);
4043 STR_VTR_OP_CASE (TRANSLATE_1_2);
4044 STR_VTR_OP_CASE (TRANSLATE_2_1);
4045 STR_VTR_OP_CASE (TRANSLATE_2_2);
4046 }
4047
4048 return "UNKNOWN";
4049}
4050
4051static int
4052dump_sub_interface_table (vat_main_t * vam)
4053{
4054 const sw_interface_subif_t *sub = NULL;
4055
4056 if (vam->json_output)
4057 {
4058 clib_warning
4059 ("JSON output supported only for VPE API calls and dump_stats_table");
4060 return -99;
4061 }
4062
4063 print (vam->ofp,
4064 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4065 "Interface", "sw_if_index",
4066 "sub id", "dot1ad", "tags", "outer id",
4067 "inner id", "exact", "default", "outer any", "inner any");
4068
4069 vec_foreach (sub, vam->sw_if_subif_table)
4070 {
4071 print (vam->ofp,
4072 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4073 sub->interface_name,
4074 sub->sw_if_index,
4075 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4076 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4077 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4078 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4079 if (sub->vtr_op != L2_VTR_DISABLED)
4080 {
4081 print (vam->ofp,
4082 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4083 "tag1: %d tag2: %d ]",
4084 str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4085 sub->vtr_tag1, sub->vtr_tag2);
4086 }
4087 }
4088
4089 return 0;
4090}
4091
4092static int
4093name_sort_cmp (void *a1, void *a2)
4094{
4095 name_sort_t *n1 = a1;
4096 name_sort_t *n2 = a2;
4097
4098 return strcmp ((char *) n1->name, (char *) n2->name);
4099}
4100
4101static int
4102dump_interface_table (vat_main_t * vam)
4103{
4104 hash_pair_t *p;
4105 name_sort_t *nses = 0, *ns;
4106
4107 if (vam->json_output)
4108 {
4109 clib_warning
4110 ("JSON output supported only for VPE API calls and dump_stats_table");
4111 return -99;
4112 }
4113
4114 /* *INDENT-OFF* */
4115 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4116 ({
4117 vec_add2 (nses, ns, 1);
4118 ns->name = (u8 *)(p->key);
4119 ns->value = (u32) p->value[0];
4120 }));
4121 /* *INDENT-ON* */
4122
4123 vec_sort_with_function (nses, name_sort_cmp);
4124
4125 print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4126 vec_foreach (ns, nses)
4127 {
4128 print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4129 }
4130 vec_free (nses);
4131 return 0;
4132}
4133
4134static int
4135dump_ip_table (vat_main_t * vam, int is_ipv6)
4136{
4137 const ip_details_t *det = NULL;
4138 const ip_address_details_t *address = NULL;
4139 u32 i = ~0;
4140
4141 print (vam->ofp, "%-12s", "sw_if_index");
4142
4143 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4144 {
4145 i++;
4146 if (!det->present)
4147 {
4148 continue;
4149 }
4150 print (vam->ofp, "%-12d", i);
4151 print (vam->ofp, " %-30s%-13s", "Address", "Prefix length");
4152 if (!det->addr)
4153 {
4154 continue;
4155 }
4156 vec_foreach (address, det->addr)
4157 {
4158 print (vam->ofp,
4159 " %-30U%-13d",
4160 is_ipv6 ? format_ip6_address : format_ip4_address,
4161 address->ip, address->prefix_length);
4162 }
4163 }
4164
4165 return 0;
4166}
4167
4168static int
4169dump_ipv4_table (vat_main_t * vam)
4170{
4171 if (vam->json_output)
4172 {
4173 clib_warning
4174 ("JSON output supported only for VPE API calls and dump_stats_table");
4175 return -99;
4176 }
4177
4178 return dump_ip_table (vam, 0);
4179}
4180
4181static int
4182dump_ipv6_table (vat_main_t * vam)
4183{
4184 if (vam->json_output)
4185 {
4186 clib_warning
4187 ("JSON output supported only for VPE API calls and dump_stats_table");
4188 return -99;
4189 }
4190
4191 return dump_ip_table (vam, 1);
4192}
4193
4194static char *
4195counter_type_to_str (u8 counter_type, u8 is_combined)
4196{
4197 if (!is_combined)
4198 {
4199 switch (counter_type)
4200 {
4201 case VNET_INTERFACE_COUNTER_DROP:
4202 return "drop";
4203 case VNET_INTERFACE_COUNTER_PUNT:
4204 return "punt";
4205 case VNET_INTERFACE_COUNTER_IP4:
4206 return "ip4";
4207 case VNET_INTERFACE_COUNTER_IP6:
4208 return "ip6";
4209 case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4210 return "rx-no-buf";
4211 case VNET_INTERFACE_COUNTER_RX_MISS:
4212 return "rx-miss";
4213 case VNET_INTERFACE_COUNTER_RX_ERROR:
4214 return "rx-error";
4215 case VNET_INTERFACE_COUNTER_TX_ERROR:
4216 return "tx-error";
4217 default:
4218 return "INVALID-COUNTER-TYPE";
4219 }
4220 }
4221 else
4222 {
4223 switch (counter_type)
4224 {
4225 case VNET_INTERFACE_COUNTER_RX:
4226 return "rx";
4227 case VNET_INTERFACE_COUNTER_TX:
4228 return "tx";
4229 default:
4230 return "INVALID-COUNTER-TYPE";
4231 }
4232 }
4233}
4234
4235static int
4236dump_stats_table (vat_main_t * vam)
4237{
4238 vat_json_node_t node;
4239 vat_json_node_t *msg_array;
4240 vat_json_node_t *msg;
4241 vat_json_node_t *counter_array;
4242 vat_json_node_t *counter;
4243 interface_counter_t c;
4244 u64 packets;
4245 ip4_fib_counter_t *c4;
4246 ip6_fib_counter_t *c6;
4247 int i, j;
4248
4249 if (!vam->json_output)
4250 {
4251 clib_warning ("dump_stats_table supported only in JSON format");
4252 return -99;
4253 }
4254
4255 vat_json_init_object (&node);
4256
4257 /* interface counters */
4258 msg_array = vat_json_object_add (&node, "interface_counters");
4259 vat_json_init_array (msg_array);
4260 for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4261 {
4262 msg = vat_json_array_add (msg_array);
4263 vat_json_init_object (msg);
4264 vat_json_object_add_string_copy (msg, "vnet_counter_type",
4265 (u8 *) counter_type_to_str (i, 0));
4266 vat_json_object_add_int (msg, "is_combined", 0);
4267 counter_array = vat_json_object_add (msg, "data");
4268 vat_json_init_array (counter_array);
4269 for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4270 {
4271 packets = vam->simple_interface_counters[i][j];
4272 vat_json_array_add_uint (counter_array, packets);
4273 }
4274 }
4275 for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4276 {
4277 msg = vat_json_array_add (msg_array);
4278 vat_json_init_object (msg);
4279 vat_json_object_add_string_copy (msg, "vnet_counter_type",
4280 (u8 *) counter_type_to_str (i, 1));
4281 vat_json_object_add_int (msg, "is_combined", 1);
4282 counter_array = vat_json_object_add (msg, "data");
4283 vat_json_init_array (counter_array);
4284 for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4285 {
4286 c = vam->combined_interface_counters[i][j];
4287 counter = vat_json_array_add (counter_array);
4288 vat_json_init_object (counter);
4289 vat_json_object_add_uint (counter, "packets", c.packets);
4290 vat_json_object_add_uint (counter, "bytes", c.bytes);
4291 }
4292 }
4293
4294 /* ip4 fib counters */
4295 msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4296 vat_json_init_array (msg_array);
4297 for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4298 {
4299 msg = vat_json_array_add (msg_array);
4300 vat_json_init_object (msg);
4301 vat_json_object_add_uint (msg, "vrf_id",
4302 vam->ip4_fib_counters_vrf_id_by_index[i]);
4303 counter_array = vat_json_object_add (msg, "c");
4304 vat_json_init_array (counter_array);
4305 for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4306 {
4307 counter = vat_json_array_add (counter_array);
4308 vat_json_init_object (counter);
4309 c4 = &vam->ip4_fib_counters[i][j];
4310 vat_json_object_add_ip4 (counter, "address", c4->address);
4311 vat_json_object_add_uint (counter, "address_length",
4312 c4->address_length);
4313 vat_json_object_add_uint (counter, "packets", c4->packets);
4314 vat_json_object_add_uint (counter, "bytes", c4->bytes);
4315 }
4316 }
4317
4318 /* ip6 fib counters */
4319 msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4320 vat_json_init_array (msg_array);
4321 for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4322 {
4323 msg = vat_json_array_add (msg_array);
4324 vat_json_init_object (msg);
4325 vat_json_object_add_uint (msg, "vrf_id",
4326 vam->ip6_fib_counters_vrf_id_by_index[i]);
4327 counter_array = vat_json_object_add (msg, "c");
4328 vat_json_init_array (counter_array);
4329 for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4330 {
4331 counter = vat_json_array_add (counter_array);
4332 vat_json_init_object (counter);
4333 c6 = &vam->ip6_fib_counters[i][j];
4334 vat_json_object_add_ip6 (counter, "address", c6->address);
4335 vat_json_object_add_uint (counter, "address_length",
4336 c6->address_length);
4337 vat_json_object_add_uint (counter, "packets", c6->packets);
4338 vat_json_object_add_uint (counter, "bytes", c6->bytes);
4339 }
4340 }
4341
4342 vat_json_print (vam->ofp, &node);
4343 vat_json_free (&node);
4344
4345 return 0;
4346}
4347
4348int
4349exec (vat_main_t * vam)
4350{
4351 api_main_t *am = &api_main;
4352 vl_api_cli_request_t *mp;
4353 f64 timeout;
4354 void *oldheap;
4355 u8 *cmd = 0;
4356 unformat_input_t *i = vam->input;
4357
4358 if (vec_len (i->buffer) == 0)
4359 return -1;
4360
4361 if (vam->exec_mode == 0 && unformat (i, "mode"))
4362 {
4363 vam->exec_mode = 1;
4364 return 0;
4365 }
4366 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4367 {
4368 vam->exec_mode = 0;
4369 return 0;
4370 }
4371
4372
4373 M (CLI_REQUEST, cli_request);
4374
4375 /*
4376 * Copy cmd into shared memory.
4377 * In order for the CLI command to work, it
4378 * must be a vector ending in \n, not a C-string ending
4379 * in \n\0.
4380 */
4381 pthread_mutex_lock (&am->vlib_rp->mutex);
4382 oldheap = svm_push_data_heap (am->vlib_rp);
4383
4384 vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4385 clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4386
4387 svm_pop_heap (oldheap);
4388 pthread_mutex_unlock (&am->vlib_rp->mutex);
4389
4390 mp->cmd_in_shmem = (u64) cmd;
4391 S;
4392 timeout = vat_time_now (vam) + 10.0;
4393
4394 while (vat_time_now (vam) < timeout)
4395 {
4396 if (vam->result_ready == 1)
4397 {
4398 u8 *free_me;
4399 if (vam->shmem_result != NULL)
4400 print (vam->ofp, "%s", vam->shmem_result);
4401 pthread_mutex_lock (&am->vlib_rp->mutex);
4402 oldheap = svm_push_data_heap (am->vlib_rp);
4403
4404 free_me = (u8 *) vam->shmem_result;
4405 vec_free (free_me);
4406
4407 svm_pop_heap (oldheap);
4408 pthread_mutex_unlock (&am->vlib_rp->mutex);
4409 return 0;
4410 }
4411 }
4412 return -99;
4413}
4414
4415/*
4416 * Future replacement of exec() that passes CLI buffers directly in
4417 * the API messages instead of an additional shared memory area.
4418 */
4419static int
4420exec_inband (vat_main_t * vam)
4421{
4422 vl_api_cli_inband_t *mp;
4423 f64 timeout;
4424 unformat_input_t *i = vam->input;
4425
4426 if (vec_len (i->buffer) == 0)
4427 return -1;
4428
4429 if (vam->exec_mode == 0 && unformat (i, "mode"))
4430 {
4431 vam->exec_mode = 1;
4432 return 0;
4433 }
4434 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4435 {
4436 vam->exec_mode = 0;
4437 return 0;
4438 }
4439
4440 /*
4441 * In order for the CLI command to work, it
4442 * must be a vector ending in \n, not a C-string ending
4443 * in \n\0.
4444 */
4445 u32 len = vec_len (vam->input->buffer);
4446 M2 (CLI_INBAND, cli_inband, len);
4447 clib_memcpy (mp->cmd, vam->input->buffer, len);
4448 mp->length = htonl (len);
4449
4450 S;
4451 W2 (print (vam->ofp, "%s", vam->cmd_reply));
4452}
4453
4454static int
4455api_create_loopback (vat_main_t * vam)
4456{
4457 unformat_input_t *i = vam->input;
4458 vl_api_create_loopback_t *mp;
4459 f64 timeout;
4460 u8 mac_address[6];
4461 u8 mac_set = 0;
4462
4463 memset (mac_address, 0, sizeof (mac_address));
4464
4465 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4466 {
4467 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4468 mac_set = 1;
4469 else
4470 break;
4471 }
4472
4473 /* Construct the API message */
4474 M (CREATE_LOOPBACK, create_loopback);
4475 if (mac_set)
4476 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4477
4478 S;
4479 W;
4480}
4481
4482static int
4483api_delete_loopback (vat_main_t * vam)
4484{
4485 unformat_input_t *i = vam->input;
4486 vl_api_delete_loopback_t *mp;
4487 f64 timeout;
4488 u32 sw_if_index = ~0;
4489
4490 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4491 {
4492 if (unformat (i, "sw_if_index %d", &sw_if_index))
4493 ;
4494 else
4495 break;
4496 }
4497
4498 if (sw_if_index == ~0)
4499 {
4500 errmsg ("missing sw_if_index");
4501 return -99;
4502 }
4503
4504 /* Construct the API message */
4505 M (DELETE_LOOPBACK, delete_loopback);
4506 mp->sw_if_index = ntohl (sw_if_index);
4507
4508 S;
4509 W;
4510}
4511
4512static int
4513api_want_stats (vat_main_t * vam)
4514{
4515 unformat_input_t *i = vam->input;
4516 vl_api_want_stats_t *mp;
4517 f64 timeout;
4518 int enable = -1;
4519
4520 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4521 {
4522 if (unformat (i, "enable"))
4523 enable = 1;
4524 else if (unformat (i, "disable"))
4525 enable = 0;
4526 else
4527 break;
4528 }
4529
4530 if (enable == -1)
4531 {
4532 errmsg ("missing enable|disable");
4533 return -99;
4534 }
4535
4536 M (WANT_STATS, want_stats);
4537 mp->enable_disable = enable;
4538
4539 S;
4540 W;
4541}
4542
4543static int
4544api_want_interface_events (vat_main_t * vam)
4545{
4546 unformat_input_t *i = vam->input;
4547 vl_api_want_interface_events_t *mp;
4548 f64 timeout;
4549 int enable = -1;
4550
4551 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4552 {
4553 if (unformat (i, "enable"))
4554 enable = 1;
4555 else if (unformat (i, "disable"))
4556 enable = 0;
4557 else
4558 break;
4559 }
4560
4561 if (enable == -1)
4562 {
4563 errmsg ("missing enable|disable");
4564 return -99;
4565 }
4566
4567 M (WANT_INTERFACE_EVENTS, want_interface_events);
4568 mp->enable_disable = enable;
4569
4570 vam->interface_event_display = enable;
4571
4572 S;
4573 W;
4574}
4575
4576
4577/* Note: non-static, called once to set up the initial intfc table */
4578int
4579api_sw_interface_dump (vat_main_t * vam)
4580{
4581 vl_api_sw_interface_dump_t *mp;
4582 f64 timeout;
4583 hash_pair_t *p;
4584 name_sort_t *nses = 0, *ns;
4585 sw_interface_subif_t *sub = NULL;
4586
4587 /* Toss the old name table */
4588 /* *INDENT-OFF* */
4589 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4590 ({
4591 vec_add2 (nses, ns, 1);
4592 ns->name = (u8 *)(p->key);
4593 ns->value = (u32) p->value[0];
4594 }));
4595 /* *INDENT-ON* */
4596
4597 hash_free (vam->sw_if_index_by_interface_name);
4598
4599 vec_foreach (ns, nses) vec_free (ns->name);
4600
4601 vec_free (nses);
4602
4603 vec_foreach (sub, vam->sw_if_subif_table)
4604 {
4605 vec_free (sub->interface_name);
4606 }
4607 vec_free (vam->sw_if_subif_table);
4608
4609 /* recreate the interface name hash table */
4610 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4611
4612 /* Get list of ethernets */
4613 M (SW_INTERFACE_DUMP, sw_interface_dump);
4614 mp->name_filter_valid = 1;
4615 strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4616 S;
4617
4618 /* and local / loopback interfaces */
4619 M (SW_INTERFACE_DUMP, sw_interface_dump);
4620 mp->name_filter_valid = 1;
4621 strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4622 S;
4623
4624 /* and packet-generator interfaces */
4625 M (SW_INTERFACE_DUMP, sw_interface_dump);
4626 mp->name_filter_valid = 1;
4627 strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4628 S;
4629
4630 /* and vxlan-gpe tunnel interfaces */
4631 M (SW_INTERFACE_DUMP, sw_interface_dump);
4632 mp->name_filter_valid = 1;
4633 strncpy ((char *) mp->name_filter, "vxlan_gpe",
4634 sizeof (mp->name_filter) - 1);
4635 S;
4636
4637 /* and vxlan tunnel interfaces */
4638 M (SW_INTERFACE_DUMP, sw_interface_dump);
4639 mp->name_filter_valid = 1;
4640 strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4641 S;
4642
4643 /* and host (af_packet) interfaces */
4644 M (SW_INTERFACE_DUMP, sw_interface_dump);
4645 mp->name_filter_valid = 1;
4646 strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4647 S;
4648
4649 /* and l2tpv3 tunnel interfaces */
4650 M (SW_INTERFACE_DUMP, sw_interface_dump);
4651 mp->name_filter_valid = 1;
4652 strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4653 sizeof (mp->name_filter) - 1);
4654 S;
4655
4656 /* and GRE tunnel interfaces */
4657 M (SW_INTERFACE_DUMP, sw_interface_dump);
4658 mp->name_filter_valid = 1;
4659 strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4660 S;
4661
4662 /* and LISP-GPE interfaces */
4663 M (SW_INTERFACE_DUMP, sw_interface_dump);
4664 mp->name_filter_valid = 1;
4665 strncpy ((char *) mp->name_filter, "lisp_gpe",
4666 sizeof (mp->name_filter) - 1);
4667 S;
4668
4669 /* and IPSEC tunnel interfaces */
4670 M (SW_INTERFACE_DUMP, sw_interface_dump);
4671 mp->name_filter_valid = 1;
4672 strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4673 S;
4674
4675 /* Use a control ping for synchronization */
4676 {
4677 vl_api_control_ping_t *mp;
4678 M (CONTROL_PING, control_ping);
4679 S;
4680 }
4681 W;
4682}
4683
4684static int
4685api_sw_interface_set_flags (vat_main_t * vam)
4686{
4687 unformat_input_t *i = vam->input;
4688 vl_api_sw_interface_set_flags_t *mp;
4689 f64 timeout;
4690 u32 sw_if_index;
4691 u8 sw_if_index_set = 0;
4692 u8 admin_up = 0, link_up = 0;
4693
4694 /* Parse args required to build the message */
4695 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4696 {
4697 if (unformat (i, "admin-up"))
4698 admin_up = 1;
4699 else if (unformat (i, "admin-down"))
4700 admin_up = 0;
4701 else if (unformat (i, "link-up"))
4702 link_up = 1;
4703 else if (unformat (i, "link-down"))
4704 link_up = 0;
4705 else
4706 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4707 sw_if_index_set = 1;
4708 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4709 sw_if_index_set = 1;
4710 else
4711 break;
4712 }
4713
4714 if (sw_if_index_set == 0)
4715 {
4716 errmsg ("missing interface name or sw_if_index");
4717 return -99;
4718 }
4719
4720 /* Construct the API message */
4721 M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4722 mp->sw_if_index = ntohl (sw_if_index);
4723 mp->admin_up_down = admin_up;
4724 mp->link_up_down = link_up;
4725
4726 /* send it... */
4727 S;
4728
4729 /* Wait for a reply, return the good/bad news... */
4730 W;
4731}
4732
4733static int
4734api_sw_interface_clear_stats (vat_main_t * vam)
4735{
4736 unformat_input_t *i = vam->input;
4737 vl_api_sw_interface_clear_stats_t *mp;
4738 f64 timeout;
4739 u32 sw_if_index;
4740 u8 sw_if_index_set = 0;
4741
4742 /* Parse args required to build the message */
4743 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4744 {
4745 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4746 sw_if_index_set = 1;
4747 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4748 sw_if_index_set = 1;
4749 else
4750 break;
4751 }
4752
4753 /* Construct the API message */
4754 M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4755
4756 if (sw_if_index_set == 1)
4757 mp->sw_if_index = ntohl (sw_if_index);
4758 else
4759 mp->sw_if_index = ~0;
4760
4761 /* send it... */
4762 S;
4763
4764 /* Wait for a reply, return the good/bad news... */
4765 W;
4766}
4767
Pavel Kotucek738f3f22017-01-09 15:11:03 +01004768#if DPDK >0
Damjan Marion7cd468a2016-12-19 23:05:39 +01004769static int
4770api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4771{
4772 unformat_input_t *i = vam->input;
4773 vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4774 f64 timeout;
4775 u32 sw_if_index;
4776 u8 sw_if_index_set = 0;
4777 u32 subport;
4778 u8 subport_set = 0;
4779 u32 pipe;
4780 u8 pipe_set = 0;
4781 u32 profile;
4782 u8 profile_set = 0;
4783
4784 /* Parse args required to build the message */
4785 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4786 {
4787 if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4788 sw_if_index_set = 1;
4789 else if (unformat (i, "sw_if_index %u", &sw_if_index))
4790 sw_if_index_set = 1;
4791 else if (unformat (i, "subport %u", &subport))
4792 subport_set = 1;
4793 else
4794 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4795 sw_if_index_set = 1;
4796 else if (unformat (i, "pipe %u", &pipe))
4797 pipe_set = 1;
4798 else if (unformat (i, "profile %u", &profile))
4799 profile_set = 1;
4800 else
4801 break;
4802 }
4803
4804 if (sw_if_index_set == 0)
4805 {
4806 errmsg ("missing interface name or sw_if_index");
4807 return -99;
4808 }
4809
4810 if (subport_set == 0)
4811 {
4812 errmsg ("missing subport ");
4813 return -99;
4814 }
4815
4816 if (pipe_set == 0)
4817 {
4818 errmsg ("missing pipe");
4819 return -99;
4820 }
4821
4822 if (profile_set == 0)
4823 {
4824 errmsg ("missing profile");
4825 return -99;
4826 }
4827
4828 M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4829
4830 mp->sw_if_index = ntohl (sw_if_index);
4831 mp->subport = ntohl (subport);
4832 mp->pipe = ntohl (pipe);
4833 mp->profile = ntohl (profile);
4834
4835
4836 S;
4837 W;
4838 /* NOTREACHED */
4839 return 0;
4840}
4841
4842static int
4843api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4844{
4845 unformat_input_t *i = vam->input;
4846 vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4847 f64 timeout;
4848 u32 sw_if_index;
4849 u8 sw_if_index_set = 0;
4850 u32 subport;
4851 u8 subport_set = 0;
4852 u32 tb_rate = 1250000000; /* 10GbE */
4853 u32 tb_size = 1000000;
4854 u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4855 u32 tc_period = 10;
4856
4857 /* Parse args required to build the message */
4858 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4859 {
4860 if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4861 sw_if_index_set = 1;
4862 else if (unformat (i, "sw_if_index %u", &sw_if_index))
4863 sw_if_index_set = 1;
4864 else if (unformat (i, "subport %u", &subport))
4865 subport_set = 1;
4866 else
4867 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4868 sw_if_index_set = 1;
4869 else if (unformat (i, "rate %u", &tb_rate))
4870 {
4871 u32 tc_id;
4872
4873 for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4874 tc_id++)
4875 tc_rate[tc_id] = tb_rate;
4876 }
4877 else if (unformat (i, "bktsize %u", &tb_size))
4878 ;
4879 else if (unformat (i, "tc0 %u", &tc_rate[0]))
4880 ;
4881 else if (unformat (i, "tc1 %u", &tc_rate[1]))
4882 ;
4883 else if (unformat (i, "tc2 %u", &tc_rate[2]))
4884 ;
4885 else if (unformat (i, "tc3 %u", &tc_rate[3]))
4886 ;
4887 else if (unformat (i, "period %u", &tc_period))
4888 ;
4889 else
4890 break;
4891 }
4892
4893 if (sw_if_index_set == 0)
4894 {
4895 errmsg ("missing interface name or sw_if_index");
4896 return -99;
4897 }
4898
4899 if (subport_set == 0)
4900 {
4901 errmsg ("missing subport ");
4902 return -99;
4903 }
4904
4905 M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4906
4907 mp->sw_if_index = ntohl (sw_if_index);
4908 mp->subport = ntohl (subport);
4909 mp->tb_rate = ntohl (tb_rate);
4910 mp->tb_size = ntohl (tb_size);
4911 mp->tc_rate[0] = ntohl (tc_rate[0]);
4912 mp->tc_rate[1] = ntohl (tc_rate[1]);
4913 mp->tc_rate[2] = ntohl (tc_rate[2]);
4914 mp->tc_rate[3] = ntohl (tc_rate[3]);
4915 mp->tc_period = ntohl (tc_period);
4916
4917 S;
4918 W;
4919 /* NOTREACHED */
4920 return 0;
4921}
4922
4923static int
4924api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4925{
4926 unformat_input_t *i = vam->input;
4927 vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4928 f64 timeout;
4929 u32 sw_if_index;
4930 u8 sw_if_index_set = 0;
4931 u8 entry_set = 0;
4932 u8 tc_set = 0;
4933 u8 queue_set = 0;
4934 u32 entry, tc, queue;
4935
4936 /* Parse args required to build the message */
4937 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4938 {
4939 if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4940 sw_if_index_set = 1;
4941 else if (unformat (i, "sw_if_index %u", &sw_if_index))
4942 sw_if_index_set = 1;
4943 else if (unformat (i, "entry %d", &entry))
4944 entry_set = 1;
4945 else if (unformat (i, "tc %d", &tc))
4946 tc_set = 1;
4947 else if (unformat (i, "queue %d", &queue))
4948 queue_set = 1;
4949 else
4950 break;
4951 }
4952
4953 if (sw_if_index_set == 0)
4954 {
4955 errmsg ("missing interface name or sw_if_index");
4956 return -99;
4957 }
4958
4959 if (entry_set == 0)
4960 {
4961 errmsg ("missing entry ");
4962 return -99;
4963 }
4964
4965 if (tc_set == 0)
4966 {
4967 errmsg ("missing traffic class ");
4968 return -99;
4969 }
4970
4971 if (queue_set == 0)
4972 {
4973 errmsg ("missing queue ");
4974 return -99;
4975 }
4976
4977 M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4978
4979 mp->sw_if_index = ntohl (sw_if_index);
4980 mp->entry = ntohl (entry);
4981 mp->tc = ntohl (tc);
4982 mp->queue = ntohl (queue);
4983
4984 S;
4985 W;
4986 /* NOTREACHED */
4987 return 0;
4988}
Pavel Kotucek738f3f22017-01-09 15:11:03 +01004989#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01004990
4991static int
4992api_sw_interface_add_del_address (vat_main_t * vam)
4993{
4994 unformat_input_t *i = vam->input;
4995 vl_api_sw_interface_add_del_address_t *mp;
4996 f64 timeout;
4997 u32 sw_if_index;
4998 u8 sw_if_index_set = 0;
4999 u8 is_add = 1, del_all = 0;
5000 u32 address_length = 0;
5001 u8 v4_address_set = 0;
5002 u8 v6_address_set = 0;
5003 ip4_address_t v4address;
5004 ip6_address_t v6address;
5005
5006 /* Parse args required to build the message */
5007 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5008 {
5009 if (unformat (i, "del-all"))
5010 del_all = 1;
5011 else if (unformat (i, "del"))
5012 is_add = 0;
5013 else
5014 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5015 sw_if_index_set = 1;
5016 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5017 sw_if_index_set = 1;
5018 else if (unformat (i, "%U/%d",
5019 unformat_ip4_address, &v4address, &address_length))
5020 v4_address_set = 1;
5021 else if (unformat (i, "%U/%d",
5022 unformat_ip6_address, &v6address, &address_length))
5023 v6_address_set = 1;
5024 else
5025 break;
5026 }
5027
5028 if (sw_if_index_set == 0)
5029 {
5030 errmsg ("missing interface name or sw_if_index");
5031 return -99;
5032 }
5033 if (v4_address_set && v6_address_set)
5034 {
5035 errmsg ("both v4 and v6 addresses set");
5036 return -99;
5037 }
5038 if (!v4_address_set && !v6_address_set && !del_all)
5039 {
5040 errmsg ("no addresses set");
5041 return -99;
5042 }
5043
5044 /* Construct the API message */
5045 M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
5046
5047 mp->sw_if_index = ntohl (sw_if_index);
5048 mp->is_add = is_add;
5049 mp->del_all = del_all;
5050 if (v6_address_set)
5051 {
5052 mp->is_ipv6 = 1;
5053 clib_memcpy (mp->address, &v6address, sizeof (v6address));
5054 }
5055 else
5056 {
5057 clib_memcpy (mp->address, &v4address, sizeof (v4address));
5058 }
5059 mp->address_length = address_length;
5060
5061 /* send it... */
5062 S;
5063
5064 /* Wait for a reply, return good/bad news */
5065 W;
5066}
5067
5068static int
5069api_sw_interface_set_mpls_enable (vat_main_t * vam)
5070{
5071 unformat_input_t *i = vam->input;
5072 vl_api_sw_interface_set_mpls_enable_t *mp;
5073 f64 timeout;
5074 u32 sw_if_index;
5075 u8 sw_if_index_set = 0;
5076 u8 enable = 1;
5077
5078 /* Parse args required to build the message */
5079 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5080 {
5081 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5082 sw_if_index_set = 1;
5083 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5084 sw_if_index_set = 1;
5085 else if (unformat (i, "disable"))
5086 enable = 0;
5087 else if (unformat (i, "dis"))
5088 enable = 0;
5089 else
5090 break;
5091 }
5092
5093 if (sw_if_index_set == 0)
5094 {
5095 errmsg ("missing interface name or sw_if_index");
5096 return -99;
5097 }
5098
5099 /* Construct the API message */
5100 M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
5101
5102 mp->sw_if_index = ntohl (sw_if_index);
5103 mp->enable = enable;
5104
5105 /* send it... */
5106 S;
5107
5108 /* Wait for a reply... */
5109 W;
5110}
5111
5112static int
5113api_sw_interface_set_table (vat_main_t * vam)
5114{
5115 unformat_input_t *i = vam->input;
5116 vl_api_sw_interface_set_table_t *mp;
5117 f64 timeout;
5118 u32 sw_if_index, vrf_id = 0;
5119 u8 sw_if_index_set = 0;
5120 u8 is_ipv6 = 0;
5121
5122 /* Parse args required to build the message */
5123 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5124 {
5125 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5126 sw_if_index_set = 1;
5127 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5128 sw_if_index_set = 1;
5129 else if (unformat (i, "vrf %d", &vrf_id))
5130 ;
5131 else if (unformat (i, "ipv6"))
5132 is_ipv6 = 1;
5133 else
5134 break;
5135 }
5136
5137 if (sw_if_index_set == 0)
5138 {
5139 errmsg ("missing interface name or sw_if_index");
5140 return -99;
5141 }
5142
5143 /* Construct the API message */
5144 M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
5145
5146 mp->sw_if_index = ntohl (sw_if_index);
5147 mp->is_ipv6 = is_ipv6;
5148 mp->vrf_id = ntohl (vrf_id);
5149
5150 /* send it... */
5151 S;
5152
5153 /* Wait for a reply... */
5154 W;
5155}
5156
5157static void vl_api_sw_interface_get_table_reply_t_handler
5158 (vl_api_sw_interface_get_table_reply_t * mp)
5159{
5160 vat_main_t *vam = &vat_main;
5161
5162 print (vam->ofp, "%d", ntohl (mp->vrf_id));
5163
5164 vam->retval = ntohl (mp->retval);
5165 vam->result_ready = 1;
5166
5167}
5168
5169static void vl_api_sw_interface_get_table_reply_t_handler_json
5170 (vl_api_sw_interface_get_table_reply_t * mp)
5171{
5172 vat_main_t *vam = &vat_main;
5173 vat_json_node_t node;
5174
5175 vat_json_init_object (&node);
5176 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5177 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5178
5179 vat_json_print (vam->ofp, &node);
5180 vat_json_free (&node);
5181
5182 vam->retval = ntohl (mp->retval);
5183 vam->result_ready = 1;
5184}
5185
5186static int
5187api_sw_interface_get_table (vat_main_t * vam)
5188{
5189 unformat_input_t *i = vam->input;
5190 vl_api_sw_interface_get_table_t *mp;
5191 u32 sw_if_index;
5192 u8 sw_if_index_set = 0;
5193 u8 is_ipv6 = 0;
5194 f64 timeout;
5195
5196 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5197 {
5198 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5199 sw_if_index_set = 1;
5200 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5201 sw_if_index_set = 1;
5202 else if (unformat (i, "ipv6"))
5203 is_ipv6 = 1;
5204 else
5205 break;
5206 }
5207
5208 if (sw_if_index_set == 0)
5209 {
5210 errmsg ("missing interface name or sw_if_index");
5211 return -99;
5212 }
5213
5214 M (SW_INTERFACE_GET_TABLE, sw_interface_get_table);
5215 mp->sw_if_index = htonl (sw_if_index);
5216 mp->is_ipv6 = is_ipv6;
5217
5218 S;
5219 W;
5220}
5221
5222static int
5223api_sw_interface_set_vpath (vat_main_t * vam)
5224{
5225 unformat_input_t *i = vam->input;
5226 vl_api_sw_interface_set_vpath_t *mp;
5227 f64 timeout;
5228 u32 sw_if_index = 0;
5229 u8 sw_if_index_set = 0;
5230 u8 is_enable = 0;
5231
5232 /* Parse args required to build the message */
5233 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5234 {
5235 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5236 sw_if_index_set = 1;
5237 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5238 sw_if_index_set = 1;
5239 else if (unformat (i, "enable"))
5240 is_enable = 1;
5241 else if (unformat (i, "disable"))
5242 is_enable = 0;
5243 else
5244 break;
5245 }
5246
5247 if (sw_if_index_set == 0)
5248 {
5249 errmsg ("missing interface name or sw_if_index");
5250 return -99;
5251 }
5252
5253 /* Construct the API message */
5254 M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5255
5256 mp->sw_if_index = ntohl (sw_if_index);
5257 mp->enable = is_enable;
5258
5259 /* send it... */
5260 S;
5261
5262 /* Wait for a reply... */
5263 W;
5264}
5265
5266static int
5267api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5268{
5269 unformat_input_t *i = vam->input;
5270 vl_api_sw_interface_set_vxlan_bypass_t *mp;
5271 f64 timeout;
5272 u32 sw_if_index = 0;
5273 u8 sw_if_index_set = 0;
5274 u8 is_enable = 0;
5275 u8 is_ipv6 = 0;
5276
5277 /* Parse args required to build the message */
5278 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5279 {
5280 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5281 sw_if_index_set = 1;
5282 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5283 sw_if_index_set = 1;
5284 else if (unformat (i, "enable"))
5285 is_enable = 1;
5286 else if (unformat (i, "disable"))
5287 is_enable = 0;
5288 else if (unformat (i, "ip4"))
5289 is_ipv6 = 0;
5290 else if (unformat (i, "ip6"))
5291 is_ipv6 = 1;
5292 else
5293 break;
5294 }
5295
5296 if (sw_if_index_set == 0)
5297 {
5298 errmsg ("missing interface name or sw_if_index");
5299 return -99;
5300 }
5301
5302 /* Construct the API message */
5303 M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5304
5305 mp->sw_if_index = ntohl (sw_if_index);
5306 mp->enable = is_enable;
5307 mp->is_ipv6 = is_ipv6;
5308
5309 /* send it... */
5310 S;
5311
5312 /* Wait for a reply... */
5313 W;
5314}
5315
5316static int
5317api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5318{
5319 unformat_input_t *i = vam->input;
5320 vl_api_sw_interface_set_l2_xconnect_t *mp;
5321 f64 timeout;
5322 u32 rx_sw_if_index;
5323 u8 rx_sw_if_index_set = 0;
5324 u32 tx_sw_if_index;
5325 u8 tx_sw_if_index_set = 0;
5326 u8 enable = 1;
5327
5328 /* Parse args required to build the message */
5329 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5330 {
5331 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5332 rx_sw_if_index_set = 1;
5333 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5334 tx_sw_if_index_set = 1;
5335 else if (unformat (i, "rx"))
5336 {
5337 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5338 {
5339 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5340 &rx_sw_if_index))
5341 rx_sw_if_index_set = 1;
5342 }
5343 else
5344 break;
5345 }
5346 else if (unformat (i, "tx"))
5347 {
5348 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5349 {
5350 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5351 &tx_sw_if_index))
5352 tx_sw_if_index_set = 1;
5353 }
5354 else
5355 break;
5356 }
5357 else if (unformat (i, "enable"))
5358 enable = 1;
5359 else if (unformat (i, "disable"))
5360 enable = 0;
5361 else
5362 break;
5363 }
5364
5365 if (rx_sw_if_index_set == 0)
5366 {
5367 errmsg ("missing rx interface name or rx_sw_if_index");
5368 return -99;
5369 }
5370
5371 if (enable && (tx_sw_if_index_set == 0))
5372 {
5373 errmsg ("missing tx interface name or tx_sw_if_index");
5374 return -99;
5375 }
5376
5377 M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5378
5379 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5380 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5381 mp->enable = enable;
5382
5383 S;
5384 W;
5385 /* NOTREACHED */
5386 return 0;
5387}
5388
5389static int
5390api_sw_interface_set_l2_bridge (vat_main_t * vam)
5391{
5392 unformat_input_t *i = vam->input;
5393 vl_api_sw_interface_set_l2_bridge_t *mp;
5394 f64 timeout;
5395 u32 rx_sw_if_index;
5396 u8 rx_sw_if_index_set = 0;
5397 u32 bd_id;
5398 u8 bd_id_set = 0;
5399 u8 bvi = 0;
5400 u32 shg = 0;
5401 u8 enable = 1;
5402
5403 /* Parse args required to build the message */
5404 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5405 {
5406 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5407 rx_sw_if_index_set = 1;
5408 else if (unformat (i, "bd_id %d", &bd_id))
5409 bd_id_set = 1;
5410 else
5411 if (unformat
5412 (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5413 rx_sw_if_index_set = 1;
5414 else if (unformat (i, "shg %d", &shg))
5415 ;
5416 else if (unformat (i, "bvi"))
5417 bvi = 1;
5418 else if (unformat (i, "enable"))
5419 enable = 1;
5420 else if (unformat (i, "disable"))
5421 enable = 0;
5422 else
5423 break;
5424 }
5425
5426 if (rx_sw_if_index_set == 0)
5427 {
5428 errmsg ("missing rx interface name or sw_if_index");
5429 return -99;
5430 }
5431
5432 if (enable && (bd_id_set == 0))
5433 {
5434 errmsg ("missing bridge domain");
5435 return -99;
5436 }
5437
5438 M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5439
5440 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5441 mp->bd_id = ntohl (bd_id);
5442 mp->shg = (u8) shg;
5443 mp->bvi = bvi;
5444 mp->enable = enable;
5445
5446 S;
5447 W;
5448 /* NOTREACHED */
5449 return 0;
5450}
5451
5452static int
5453api_bridge_domain_dump (vat_main_t * vam)
5454{
5455 unformat_input_t *i = vam->input;
5456 vl_api_bridge_domain_dump_t *mp;
5457 f64 timeout;
5458 u32 bd_id = ~0;
5459
5460 /* Parse args required to build the message */
5461 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5462 {
5463 if (unformat (i, "bd_id %d", &bd_id))
5464 ;
5465 else
5466 break;
5467 }
5468
5469 M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5470 mp->bd_id = ntohl (bd_id);
5471 S;
5472
5473 /* Use a control ping for synchronization */
5474 {
5475 vl_api_control_ping_t *mp;
5476 M (CONTROL_PING, control_ping);
5477 S;
5478 }
5479
5480 W;
5481 /* NOTREACHED */
5482 return 0;
5483}
5484
5485static int
5486api_bridge_domain_add_del (vat_main_t * vam)
5487{
5488 unformat_input_t *i = vam->input;
5489 vl_api_bridge_domain_add_del_t *mp;
5490 f64 timeout;
5491 u32 bd_id = ~0;
5492 u8 is_add = 1;
5493 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5494 u32 mac_age = 0;
5495
5496 /* Parse args required to build the message */
5497 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5498 {
5499 if (unformat (i, "bd_id %d", &bd_id))
5500 ;
5501 else if (unformat (i, "flood %d", &flood))
5502 ;
5503 else if (unformat (i, "uu-flood %d", &uu_flood))
5504 ;
5505 else if (unformat (i, "forward %d", &forward))
5506 ;
5507 else if (unformat (i, "learn %d", &learn))
5508 ;
5509 else if (unformat (i, "arp-term %d", &arp_term))
5510 ;
5511 else if (unformat (i, "mac-age %d", &mac_age))
5512 ;
5513 else if (unformat (i, "del"))
5514 {
5515 is_add = 0;
5516 flood = uu_flood = forward = learn = 0;
5517 }
5518 else
5519 break;
5520 }
5521
5522 if (bd_id == ~0)
5523 {
5524 errmsg ("missing bridge domain");
5525 return -99;
5526 }
5527
5528 if (mac_age > 255)
5529 {
5530 errmsg ("mac age must be less than 256 ");
5531 return -99;
5532 }
5533
5534 M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5535
5536 mp->bd_id = ntohl (bd_id);
5537 mp->flood = flood;
5538 mp->uu_flood = uu_flood;
5539 mp->forward = forward;
5540 mp->learn = learn;
5541 mp->arp_term = arp_term;
5542 mp->is_add = is_add;
5543 mp->mac_age = (u8) mac_age;
5544
5545 S;
5546 W;
5547 /* NOTREACHED */
5548 return 0;
5549}
5550
5551static int
5552api_l2fib_add_del (vat_main_t * vam)
5553{
5554 unformat_input_t *i = vam->input;
5555 vl_api_l2fib_add_del_t *mp;
5556 f64 timeout;
5557 u64 mac = 0;
5558 u8 mac_set = 0;
5559 u32 bd_id;
5560 u8 bd_id_set = 0;
5561 u32 sw_if_index = ~0;
5562 u8 sw_if_index_set = 0;
5563 u8 is_add = 1;
5564 u8 static_mac = 0;
5565 u8 filter_mac = 0;
5566 u8 bvi_mac = 0;
5567 int count = 1;
5568 f64 before = 0;
5569 int j;
5570
5571 /* Parse args required to build the message */
5572 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5573 {
5574 if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5575 mac_set = 1;
5576 else if (unformat (i, "bd_id %d", &bd_id))
5577 bd_id_set = 1;
5578 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5579 sw_if_index_set = 1;
5580 else if (unformat (i, "sw_if"))
5581 {
5582 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5583 {
5584 if (unformat
5585 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5586 sw_if_index_set = 1;
5587 }
5588 else
5589 break;
5590 }
5591 else if (unformat (i, "static"))
5592 static_mac = 1;
5593 else if (unformat (i, "filter"))
5594 {
5595 filter_mac = 1;
5596 static_mac = 1;
5597 }
5598 else if (unformat (i, "bvi"))
5599 {
5600 bvi_mac = 1;
5601 static_mac = 1;
5602 }
5603 else if (unformat (i, "del"))
5604 is_add = 0;
5605 else if (unformat (i, "count %d", &count))
5606 ;
5607 else
5608 break;
5609 }
5610
5611 if (mac_set == 0)
5612 {
5613 errmsg ("missing mac address");
5614 return -99;
5615 }
5616
5617 if (bd_id_set == 0)
5618 {
5619 errmsg ("missing bridge domain");
5620 return -99;
5621 }
5622
5623 if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5624 {
5625 errmsg ("missing interface name or sw_if_index");
5626 return -99;
5627 }
5628
5629 if (count > 1)
5630 {
5631 /* Turn on async mode */
5632 vam->async_mode = 1;
5633 vam->async_errors = 0;
5634 before = vat_time_now (vam);
5635 }
5636
5637 for (j = 0; j < count; j++)
5638 {
5639 M (L2FIB_ADD_DEL, l2fib_add_del);
5640
5641 mp->mac = mac;
5642 mp->bd_id = ntohl (bd_id);
5643 mp->is_add = is_add;
5644
5645 if (is_add)
5646 {
5647 mp->sw_if_index = ntohl (sw_if_index);
5648 mp->static_mac = static_mac;
5649 mp->filter_mac = filter_mac;
5650 mp->bvi_mac = bvi_mac;
5651 }
5652 increment_mac_address (&mac);
5653 /* send it... */
5654 S;
5655 }
5656
5657 if (count > 1)
5658 {
5659 vl_api_control_ping_t *mp;
5660 f64 after;
5661
5662 /* Shut off async mode */
5663 vam->async_mode = 0;
5664
5665 M (CONTROL_PING, control_ping);
5666 S;
5667
5668 timeout = vat_time_now (vam) + 1.0;
5669 while (vat_time_now (vam) < timeout)
5670 if (vam->result_ready == 1)
5671 goto out;
5672 vam->retval = -99;
5673
5674 out:
5675 if (vam->retval == -99)
5676 errmsg ("timeout");
5677
5678 if (vam->async_errors > 0)
5679 {
5680 errmsg ("%d asynchronous errors", vam->async_errors);
5681 vam->retval = -98;
5682 }
5683 vam->async_errors = 0;
5684 after = vat_time_now (vam);
5685
5686 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5687 count, after - before, count / (after - before));
5688 }
5689 else
5690 {
5691 /* Wait for a reply... */
5692 W;
5693 }
5694 /* Return the good/bad news */
5695 return (vam->retval);
5696}
5697
5698static int
5699api_l2_flags (vat_main_t * vam)
5700{
5701 unformat_input_t *i = vam->input;
5702 vl_api_l2_flags_t *mp;
5703 f64 timeout;
5704 u32 sw_if_index;
5705 u32 feature_bitmap = 0;
5706 u8 sw_if_index_set = 0;
5707
5708 /* Parse args required to build the message */
5709 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5710 {
5711 if (unformat (i, "sw_if_index %d", &sw_if_index))
5712 sw_if_index_set = 1;
5713 else if (unformat (i, "sw_if"))
5714 {
5715 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5716 {
5717 if (unformat
5718 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5719 sw_if_index_set = 1;
5720 }
5721 else
5722 break;
5723 }
5724 else if (unformat (i, "learn"))
5725 feature_bitmap |= L2INPUT_FEAT_LEARN;
5726 else if (unformat (i, "forward"))
5727 feature_bitmap |= L2INPUT_FEAT_FWD;
5728 else if (unformat (i, "flood"))
5729 feature_bitmap |= L2INPUT_FEAT_FLOOD;
5730 else if (unformat (i, "uu-flood"))
5731 feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5732 else
5733 break;
5734 }
5735
5736 if (sw_if_index_set == 0)
5737 {
5738 errmsg ("missing interface name or sw_if_index");
5739 return -99;
5740 }
5741
5742 M (L2_FLAGS, l2_flags);
5743
5744 mp->sw_if_index = ntohl (sw_if_index);
5745 mp->feature_bitmap = ntohl (feature_bitmap);
5746
5747 S;
5748 W;
5749 /* NOTREACHED */
5750 return 0;
5751}
5752
5753static int
5754api_bridge_flags (vat_main_t * vam)
5755{
5756 unformat_input_t *i = vam->input;
5757 vl_api_bridge_flags_t *mp;
5758 f64 timeout;
5759 u32 bd_id;
5760 u8 bd_id_set = 0;
5761 u8 is_set = 1;
5762 u32 flags = 0;
5763
5764 /* Parse args required to build the message */
5765 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5766 {
5767 if (unformat (i, "bd_id %d", &bd_id))
5768 bd_id_set = 1;
5769 else if (unformat (i, "learn"))
5770 flags |= L2_LEARN;
5771 else if (unformat (i, "forward"))
5772 flags |= L2_FWD;
5773 else if (unformat (i, "flood"))
5774 flags |= L2_FLOOD;
5775 else if (unformat (i, "uu-flood"))
5776 flags |= L2_UU_FLOOD;
5777 else if (unformat (i, "arp-term"))
5778 flags |= L2_ARP_TERM;
5779 else if (unformat (i, "off"))
5780 is_set = 0;
5781 else if (unformat (i, "disable"))
5782 is_set = 0;
5783 else
5784 break;
5785 }
5786
5787 if (bd_id_set == 0)
5788 {
5789 errmsg ("missing bridge domain");
5790 return -99;
5791 }
5792
5793 M (BRIDGE_FLAGS, bridge_flags);
5794
5795 mp->bd_id = ntohl (bd_id);
5796 mp->feature_bitmap = ntohl (flags);
5797 mp->is_set = is_set;
5798
5799 S;
5800 W;
5801 /* NOTREACHED */
5802 return 0;
5803}
5804
5805static int
5806api_bd_ip_mac_add_del (vat_main_t * vam)
5807{
5808 unformat_input_t *i = vam->input;
5809 vl_api_bd_ip_mac_add_del_t *mp;
5810 f64 timeout;
5811 u32 bd_id;
5812 u8 is_ipv6 = 0;
5813 u8 is_add = 1;
5814 u8 bd_id_set = 0;
5815 u8 ip_set = 0;
5816 u8 mac_set = 0;
5817 ip4_address_t v4addr;
5818 ip6_address_t v6addr;
5819 u8 macaddr[6];
5820
5821
5822 /* Parse args required to build the message */
5823 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5824 {
5825 if (unformat (i, "bd_id %d", &bd_id))
5826 {
5827 bd_id_set++;
5828 }
5829 else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5830 {
5831 ip_set++;
5832 }
5833 else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5834 {
5835 ip_set++;
5836 is_ipv6++;
5837 }
5838 else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5839 {
5840 mac_set++;
5841 }
5842 else if (unformat (i, "del"))
5843 is_add = 0;
5844 else
5845 break;
5846 }
5847
5848 if (bd_id_set == 0)
5849 {
5850 errmsg ("missing bridge domain");
5851 return -99;
5852 }
5853 else if (ip_set == 0)
5854 {
5855 errmsg ("missing IP address");
5856 return -99;
5857 }
5858 else if (mac_set == 0)
5859 {
5860 errmsg ("missing MAC address");
5861 return -99;
5862 }
5863
5864 M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5865
5866 mp->bd_id = ntohl (bd_id);
5867 mp->is_ipv6 = is_ipv6;
5868 mp->is_add = is_add;
5869 if (is_ipv6)
5870 clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5871 else
5872 clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5873 clib_memcpy (mp->mac_address, macaddr, 6);
5874 S;
5875 W;
5876 /* NOTREACHED */
5877 return 0;
5878}
5879
5880static int
5881api_tap_connect (vat_main_t * vam)
5882{
5883 unformat_input_t *i = vam->input;
5884 vl_api_tap_connect_t *mp;
5885 f64 timeout;
5886 u8 mac_address[6];
5887 u8 random_mac = 1;
5888 u8 name_set = 0;
5889 u8 *tap_name;
5890 u8 *tag = 0;
5891
5892 memset (mac_address, 0, sizeof (mac_address));
5893
5894 /* Parse args required to build the message */
5895 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5896 {
5897 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5898 {
5899 random_mac = 0;
5900 }
5901 else if (unformat (i, "random-mac"))
5902 random_mac = 1;
5903 else if (unformat (i, "tapname %s", &tap_name))
5904 name_set = 1;
5905 else if (unformat (i, "tag %s", &tag))
5906 ;
5907 else
5908 break;
5909 }
5910
5911 if (name_set == 0)
5912 {
5913 errmsg ("missing tap name");
5914 return -99;
5915 }
5916 if (vec_len (tap_name) > 63)
5917 {
5918 errmsg ("tap name too long");
5919 return -99;
5920 }
5921 vec_add1 (tap_name, 0);
5922
5923 if (vec_len (tag) > 63)
5924 {
5925 errmsg ("tag too long");
5926 return -99;
5927 }
5928
5929 /* Construct the API message */
5930 M (TAP_CONNECT, tap_connect);
5931
5932 mp->use_random_mac = random_mac;
5933 clib_memcpy (mp->mac_address, mac_address, 6);
5934 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5935 if (tag)
5936 clib_memcpy (mp->tag, tag, vec_len (tag));
5937
5938 vec_free (tap_name);
5939 vec_free (tag);
5940
5941 /* send it... */
5942 S;
5943
5944 /* Wait for a reply... */
5945 W;
5946}
5947
5948static int
5949api_tap_modify (vat_main_t * vam)
5950{
5951 unformat_input_t *i = vam->input;
5952 vl_api_tap_modify_t *mp;
5953 f64 timeout;
5954 u8 mac_address[6];
5955 u8 random_mac = 1;
5956 u8 name_set = 0;
5957 u8 *tap_name;
5958 u32 sw_if_index = ~0;
5959 u8 sw_if_index_set = 0;
5960
5961 memset (mac_address, 0, sizeof (mac_address));
5962
5963 /* Parse args required to build the message */
5964 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5965 {
5966 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5967 sw_if_index_set = 1;
5968 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5969 sw_if_index_set = 1;
5970 else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5971 {
5972 random_mac = 0;
5973 }
5974 else if (unformat (i, "random-mac"))
5975 random_mac = 1;
5976 else if (unformat (i, "tapname %s", &tap_name))
5977 name_set = 1;
5978 else
5979 break;
5980 }
5981
5982 if (sw_if_index_set == 0)
5983 {
5984 errmsg ("missing vpp interface name");
5985 return -99;
5986 }
5987 if (name_set == 0)
5988 {
5989 errmsg ("missing tap name");
5990 return -99;
5991 }
5992 if (vec_len (tap_name) > 63)
5993 {
5994 errmsg ("tap name too long");
5995 }
5996 vec_add1 (tap_name, 0);
5997
5998 /* Construct the API message */
5999 M (TAP_MODIFY, tap_modify);
6000
6001 mp->use_random_mac = random_mac;
6002 mp->sw_if_index = ntohl (sw_if_index);
6003 clib_memcpy (mp->mac_address, mac_address, 6);
6004 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6005 vec_free (tap_name);
6006
6007 /* send it... */
6008 S;
6009
6010 /* Wait for a reply... */
6011 W;
6012}
6013
6014static int
6015api_tap_delete (vat_main_t * vam)
6016{
6017 unformat_input_t *i = vam->input;
6018 vl_api_tap_delete_t *mp;
6019 f64 timeout;
6020 u32 sw_if_index = ~0;
6021 u8 sw_if_index_set = 0;
6022
6023 /* Parse args required to build the message */
6024 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6025 {
6026 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6027 sw_if_index_set = 1;
6028 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6029 sw_if_index_set = 1;
6030 else
6031 break;
6032 }
6033
6034 if (sw_if_index_set == 0)
6035 {
6036 errmsg ("missing vpp interface name");
6037 return -99;
6038 }
6039
6040 /* Construct the API message */
6041 M (TAP_DELETE, tap_delete);
6042
6043 mp->sw_if_index = ntohl (sw_if_index);
6044
6045 /* send it... */
6046 S;
6047
6048 /* Wait for a reply... */
6049 W;
6050}
6051
6052static int
6053api_ip_add_del_route (vat_main_t * vam)
6054{
6055 unformat_input_t *i = vam->input;
6056 vl_api_ip_add_del_route_t *mp;
6057 f64 timeout;
6058 u32 sw_if_index = ~0, vrf_id = 0;
6059 u8 is_ipv6 = 0;
6060 u8 is_local = 0, is_drop = 0;
6061 u8 is_unreach = 0, is_prohibit = 0;
6062 u8 create_vrf_if_needed = 0;
6063 u8 is_add = 1;
6064 u32 next_hop_weight = 1;
6065 u8 not_last = 0;
6066 u8 is_multipath = 0;
6067 u8 address_set = 0;
6068 u8 address_length_set = 0;
6069 u32 next_hop_table_id = 0;
6070 u32 resolve_attempts = 0;
6071 u32 dst_address_length = 0;
6072 u8 next_hop_set = 0;
6073 ip4_address_t v4_dst_address, v4_next_hop_address;
6074 ip6_address_t v6_dst_address, v6_next_hop_address;
6075 int count = 1;
6076 int j;
6077 f64 before = 0;
6078 u32 random_add_del = 0;
6079 u32 *random_vector = 0;
6080 uword *random_hash;
6081 u32 random_seed = 0xdeaddabe;
6082 u32 classify_table_index = ~0;
6083 u8 is_classify = 0;
6084 u8 resolve_host = 0, resolve_attached = 0;
6085 mpls_label_t *next_hop_out_label_stack = NULL;
6086 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6087 mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6088
6089 /* Parse args required to build the message */
6090 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6091 {
6092 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6093 ;
6094 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6095 ;
6096 else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6097 {
6098 address_set = 1;
6099 is_ipv6 = 0;
6100 }
6101 else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6102 {
6103 address_set = 1;
6104 is_ipv6 = 1;
6105 }
6106 else if (unformat (i, "/%d", &dst_address_length))
6107 {
6108 address_length_set = 1;
6109 }
6110
6111 else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6112 &v4_next_hop_address))
6113 {
6114 next_hop_set = 1;
6115 }
6116 else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6117 &v6_next_hop_address))
6118 {
6119 next_hop_set = 1;
6120 }
6121 else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6122 ;
6123 else if (unformat (i, "weight %d", &next_hop_weight))
6124 ;
6125 else if (unformat (i, "drop"))
6126 {
6127 is_drop = 1;
6128 }
6129 else if (unformat (i, "null-send-unreach"))
6130 {
6131 is_unreach = 1;
6132 }
6133 else if (unformat (i, "null-send-prohibit"))
6134 {
6135 is_prohibit = 1;
6136 }
6137 else if (unformat (i, "local"))
6138 {
6139 is_local = 1;
6140 }
6141 else if (unformat (i, "classify %d", &classify_table_index))
6142 {
6143 is_classify = 1;
6144 }
6145 else if (unformat (i, "del"))
6146 is_add = 0;
6147 else if (unformat (i, "add"))
6148 is_add = 1;
6149 else if (unformat (i, "not-last"))
6150 not_last = 1;
6151 else if (unformat (i, "resolve-via-host"))
6152 resolve_host = 1;
6153 else if (unformat (i, "resolve-via-attached"))
6154 resolve_attached = 1;
6155 else if (unformat (i, "multipath"))
6156 is_multipath = 1;
6157 else if (unformat (i, "vrf %d", &vrf_id))
6158 ;
6159 else if (unformat (i, "create-vrf"))
6160 create_vrf_if_needed = 1;
6161 else if (unformat (i, "count %d", &count))
6162 ;
6163 else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6164 ;
6165 else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6166 ;
6167 else if (unformat (i, "out-label %d", &next_hop_out_label))
6168 vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6169 else if (unformat (i, "via-label %d", &next_hop_via_label))
6170 ;
6171 else if (unformat (i, "random"))
6172 random_add_del = 1;
6173 else if (unformat (i, "seed %d", &random_seed))
6174 ;
6175 else
6176 {
6177 clib_warning ("parse error '%U'", format_unformat_error, i);
6178 return -99;
6179 }
6180 }
6181
6182 if (!next_hop_set && !is_drop && !is_local &&
6183 !is_classify && !is_unreach && !is_prohibit &&
6184 MPLS_LABEL_INVALID == next_hop_via_label)
6185 {
6186 errmsg
6187 ("next hop / local / drop / unreach / prohibit / classify not set");
6188 return -99;
6189 }
6190
6191 if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6192 {
6193 errmsg ("next hop and next-hop via label set");
6194 return -99;
6195 }
6196 if (address_set == 0)
6197 {
6198 errmsg ("missing addresses");
6199 return -99;
6200 }
6201
6202 if (address_length_set == 0)
6203 {
6204 errmsg ("missing address length");
6205 return -99;
6206 }
6207
6208 /* Generate a pile of unique, random routes */
6209 if (random_add_del)
6210 {
6211 u32 this_random_address;
6212 random_hash = hash_create (count, sizeof (uword));
6213
6214 hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6215 for (j = 0; j <= count; j++)
6216 {
6217 do
6218 {
6219 this_random_address = random_u32 (&random_seed);
6220 this_random_address =
6221 clib_host_to_net_u32 (this_random_address);
6222 }
6223 while (hash_get (random_hash, this_random_address));
6224 vec_add1 (random_vector, this_random_address);
6225 hash_set (random_hash, this_random_address, 1);
6226 }
6227 hash_free (random_hash);
6228 v4_dst_address.as_u32 = random_vector[0];
6229 }
6230
6231 if (count > 1)
6232 {
6233 /* Turn on async mode */
6234 vam->async_mode = 1;
6235 vam->async_errors = 0;
6236 before = vat_time_now (vam);
6237 }
6238
6239 for (j = 0; j < count; j++)
6240 {
6241 /* Construct the API message */
6242 M2 (IP_ADD_DEL_ROUTE, ip_add_del_route,
6243 sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6244
6245 mp->next_hop_sw_if_index = ntohl (sw_if_index);
6246 mp->table_id = ntohl (vrf_id);
6247 mp->create_vrf_if_needed = create_vrf_if_needed;
6248
6249 mp->is_add = is_add;
6250 mp->is_drop = is_drop;
6251 mp->is_unreach = is_unreach;
6252 mp->is_prohibit = is_prohibit;
6253 mp->is_ipv6 = is_ipv6;
6254 mp->is_local = is_local;
6255 mp->is_classify = is_classify;
6256 mp->is_multipath = is_multipath;
6257 mp->is_resolve_host = resolve_host;
6258 mp->is_resolve_attached = resolve_attached;
6259 mp->not_last = not_last;
6260 mp->next_hop_weight = next_hop_weight;
6261 mp->dst_address_length = dst_address_length;
6262 mp->next_hop_table_id = ntohl (next_hop_table_id);
6263 mp->classify_table_index = ntohl (classify_table_index);
6264 mp->next_hop_via_label = ntohl (next_hop_via_label);
6265 mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6266 if (0 != mp->next_hop_n_out_labels)
6267 {
6268 memcpy (mp->next_hop_out_label_stack,
6269 next_hop_out_label_stack,
6270 vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6271 vec_free (next_hop_out_label_stack);
6272 }
6273
6274 if (is_ipv6)
6275 {
6276 clib_memcpy (mp->dst_address, &v6_dst_address,
6277 sizeof (v6_dst_address));
6278 if (next_hop_set)
6279 clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6280 sizeof (v6_next_hop_address));
6281 increment_v6_address (&v6_dst_address);
6282 }
6283 else
6284 {
6285 clib_memcpy (mp->dst_address, &v4_dst_address,
6286 sizeof (v4_dst_address));
6287 if (next_hop_set)
6288 clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6289 sizeof (v4_next_hop_address));
6290 if (random_add_del)
6291 v4_dst_address.as_u32 = random_vector[j + 1];
6292 else
6293 increment_v4_address (&v4_dst_address);
6294 }
6295 /* send it... */
6296 S;
6297 /* If we receive SIGTERM, stop now... */
6298 if (vam->do_exit)
6299 break;
6300 }
6301
6302 /* When testing multiple add/del ops, use a control-ping to sync */
6303 if (count > 1)
6304 {
6305 vl_api_control_ping_t *mp;
6306 f64 after;
6307
6308 /* Shut off async mode */
6309 vam->async_mode = 0;
6310
6311 M (CONTROL_PING, control_ping);
6312 S;
6313
6314 timeout = vat_time_now (vam) + 1.0;
6315 while (vat_time_now (vam) < timeout)
6316 if (vam->result_ready == 1)
6317 goto out;
6318 vam->retval = -99;
6319
6320 out:
6321 if (vam->retval == -99)
6322 errmsg ("timeout");
6323
6324 if (vam->async_errors > 0)
6325 {
6326 errmsg ("%d asynchronous errors", vam->async_errors);
6327 vam->retval = -98;
6328 }
6329 vam->async_errors = 0;
6330 after = vat_time_now (vam);
6331
6332 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6333 if (j > 0)
6334 count = j;
6335
6336 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6337 count, after - before, count / (after - before));
6338 }
6339 else
6340 {
6341 /* Wait for a reply... */
6342 W;
6343 }
6344
6345 /* Return the good/bad news */
6346 return (vam->retval);
6347}
6348
6349static int
6350api_mpls_route_add_del (vat_main_t * vam)
6351{
6352 unformat_input_t *i = vam->input;
6353 vl_api_mpls_route_add_del_t *mp;
6354 f64 timeout;
6355 u32 sw_if_index = ~0, table_id = 0;
6356 u8 create_table_if_needed = 0;
6357 u8 is_add = 1;
6358 u32 next_hop_weight = 1;
6359 u8 is_multipath = 0;
6360 u32 next_hop_table_id = 0;
6361 u8 next_hop_set = 0;
6362 ip4_address_t v4_next_hop_address = {
6363 .as_u32 = 0,
6364 };
6365 ip6_address_t v6_next_hop_address = { {0} };
6366 int count = 1;
6367 int j;
6368 f64 before = 0;
6369 u32 classify_table_index = ~0;
6370 u8 is_classify = 0;
6371 u8 resolve_host = 0, resolve_attached = 0;
6372 mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6373 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6374 mpls_label_t *next_hop_out_label_stack = NULL;
6375 mpls_label_t local_label = MPLS_LABEL_INVALID;
6376 u8 is_eos = 0;
6377 u8 next_hop_proto_is_ip4 = 1;
6378
6379 /* Parse args required to build the message */
6380 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6381 {
6382 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6383 ;
6384 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6385 ;
6386 else if (unformat (i, "%d", &local_label))
6387 ;
6388 else if (unformat (i, "eos"))
6389 is_eos = 1;
6390 else if (unformat (i, "non-eos"))
6391 is_eos = 0;
6392 else if (unformat (i, "via %U", unformat_ip4_address,
6393 &v4_next_hop_address))
6394 {
6395 next_hop_set = 1;
6396 next_hop_proto_is_ip4 = 1;
6397 }
6398 else if (unformat (i, "via %U", unformat_ip6_address,
6399 &v6_next_hop_address))
6400 {
6401 next_hop_set = 1;
6402 next_hop_proto_is_ip4 = 0;
6403 }
6404 else if (unformat (i, "weight %d", &next_hop_weight))
6405 ;
6406 else if (unformat (i, "create-table"))
6407 create_table_if_needed = 1;
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, "resolve-via-host"))
6417 resolve_host = 1;
6418 else if (unformat (i, "resolve-via-attached"))
6419 resolve_attached = 1;
6420 else if (unformat (i, "multipath"))
6421 is_multipath = 1;
6422 else if (unformat (i, "count %d", &count))
6423 ;
6424 else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6425 {
6426 next_hop_set = 1;
6427 next_hop_proto_is_ip4 = 1;
6428 }
6429 else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6430 {
6431 next_hop_set = 1;
6432 next_hop_proto_is_ip4 = 0;
6433 }
6434 else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6435 ;
6436 else if (unformat (i, "via-label %d", &next_hop_via_label))
6437 ;
6438 else if (unformat (i, "out-label %d", &next_hop_out_label))
6439 vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6440 else
6441 {
6442 clib_warning ("parse error '%U'", format_unformat_error, i);
6443 return -99;
6444 }
6445 }
6446
6447 if (!next_hop_set && !is_classify)
6448 {
6449 errmsg ("next hop / classify not set");
6450 return -99;
6451 }
6452
6453 if (MPLS_LABEL_INVALID == local_label)
6454 {
6455 errmsg ("missing label");
6456 return -99;
6457 }
6458
6459 if (count > 1)
6460 {
6461 /* Turn on async mode */
6462 vam->async_mode = 1;
6463 vam->async_errors = 0;
6464 before = vat_time_now (vam);
6465 }
6466
6467 for (j = 0; j < count; j++)
6468 {
6469 /* Construct the API message */
6470 M2 (MPLS_ROUTE_ADD_DEL, mpls_route_add_del,
6471 sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6472
6473 mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6474 mp->mr_table_id = ntohl (table_id);
6475 mp->mr_create_table_if_needed = create_table_if_needed;
6476
6477 mp->mr_is_add = is_add;
6478 mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6479 mp->mr_is_classify = is_classify;
6480 mp->mr_is_multipath = is_multipath;
6481 mp->mr_is_resolve_host = resolve_host;
6482 mp->mr_is_resolve_attached = resolve_attached;
6483 mp->mr_next_hop_weight = next_hop_weight;
6484 mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6485 mp->mr_classify_table_index = ntohl (classify_table_index);
6486 mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6487 mp->mr_label = ntohl (local_label);
6488 mp->mr_eos = is_eos;
6489
6490 mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6491 if (0 != mp->mr_next_hop_n_out_labels)
6492 {
6493 memcpy (mp->mr_next_hop_out_label_stack,
6494 next_hop_out_label_stack,
6495 vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6496 vec_free (next_hop_out_label_stack);
6497 }
6498
6499 if (next_hop_set)
6500 {
6501 if (next_hop_proto_is_ip4)
6502 {
6503 clib_memcpy (mp->mr_next_hop,
6504 &v4_next_hop_address,
6505 sizeof (v4_next_hop_address));
6506 }
6507 else
6508 {
6509 clib_memcpy (mp->mr_next_hop,
6510 &v6_next_hop_address,
6511 sizeof (v6_next_hop_address));
6512 }
6513 }
6514 local_label++;
6515
6516 /* send it... */
6517 S;
6518 /* If we receive SIGTERM, stop now... */
6519 if (vam->do_exit)
6520 break;
6521 }
6522
6523 /* When testing multiple add/del ops, use a control-ping to sync */
6524 if (count > 1)
6525 {
6526 vl_api_control_ping_t *mp;
6527 f64 after;
6528
6529 /* Shut off async mode */
6530 vam->async_mode = 0;
6531
6532 M (CONTROL_PING, control_ping);
6533 S;
6534
6535 timeout = vat_time_now (vam) + 1.0;
6536 while (vat_time_now (vam) < timeout)
6537 if (vam->result_ready == 1)
6538 goto out;
6539 vam->retval = -99;
6540
6541 out:
6542 if (vam->retval == -99)
6543 errmsg ("timeout");
6544
6545 if (vam->async_errors > 0)
6546 {
6547 errmsg ("%d asynchronous errors", vam->async_errors);
6548 vam->retval = -98;
6549 }
6550 vam->async_errors = 0;
6551 after = vat_time_now (vam);
6552
6553 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6554 if (j > 0)
6555 count = j;
6556
6557 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6558 count, after - before, count / (after - before));
6559 }
6560 else
6561 {
6562 /* Wait for a reply... */
6563 W;
6564 }
6565
6566 /* Return the good/bad news */
6567 return (vam->retval);
6568}
6569
6570static int
6571api_mpls_ip_bind_unbind (vat_main_t * vam)
6572{
6573 unformat_input_t *i = vam->input;
6574 vl_api_mpls_ip_bind_unbind_t *mp;
6575 f64 timeout;
6576 u32 ip_table_id = 0;
6577 u8 create_table_if_needed = 0;
6578 u8 is_bind = 1;
6579 u8 is_ip4 = 1;
6580 ip4_address_t v4_address;
6581 ip6_address_t v6_address;
6582 u32 address_length;
6583 u8 address_set = 0;
6584 mpls_label_t local_label = MPLS_LABEL_INVALID;
6585
6586 /* Parse args required to build the message */
6587 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6588 {
6589 if (unformat (i, "%U/%d", unformat_ip4_address,
6590 &v4_address, &address_length))
6591 {
6592 is_ip4 = 1;
6593 address_set = 1;
6594 }
6595 else if (unformat (i, "%U/%d", unformat_ip6_address,
6596 &v6_address, &address_length))
6597 {
6598 is_ip4 = 0;
6599 address_set = 1;
6600 }
6601 else if (unformat (i, "%d", &local_label))
6602 ;
6603 else if (unformat (i, "create-table"))
6604 create_table_if_needed = 1;
6605 else if (unformat (i, "table-id %d", &ip_table_id))
6606 ;
6607 else if (unformat (i, "unbind"))
6608 is_bind = 0;
6609 else if (unformat (i, "bind"))
6610 is_bind = 1;
6611 else
6612 {
6613 clib_warning ("parse error '%U'", format_unformat_error, i);
6614 return -99;
6615 }
6616 }
6617
6618 if (!address_set)
6619 {
6620 errmsg ("IP addres not set");
6621 return -99;
6622 }
6623
6624 if (MPLS_LABEL_INVALID == local_label)
6625 {
6626 errmsg ("missing label");
6627 return -99;
6628 }
6629
6630 /* Construct the API message */
6631 M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6632
6633 mp->mb_create_table_if_needed = create_table_if_needed;
6634 mp->mb_is_bind = is_bind;
6635 mp->mb_is_ip4 = is_ip4;
6636 mp->mb_ip_table_id = ntohl (ip_table_id);
6637 mp->mb_mpls_table_id = 0;
6638 mp->mb_label = ntohl (local_label);
6639 mp->mb_address_length = address_length;
6640
6641 if (is_ip4)
6642 clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6643 else
6644 clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6645
6646 /* send it... */
6647 S;
6648
6649 /* Wait for a reply... */
6650 W;
6651}
6652
6653static int
6654api_proxy_arp_add_del (vat_main_t * vam)
6655{
6656 unformat_input_t *i = vam->input;
6657 vl_api_proxy_arp_add_del_t *mp;
6658 f64 timeout;
6659 u32 vrf_id = 0;
6660 u8 is_add = 1;
6661 ip4_address_t lo, hi;
6662 u8 range_set = 0;
6663
6664 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6665 {
6666 if (unformat (i, "vrf %d", &vrf_id))
6667 ;
6668 else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6669 unformat_ip4_address, &hi))
6670 range_set = 1;
6671 else if (unformat (i, "del"))
6672 is_add = 0;
6673 else
6674 {
6675 clib_warning ("parse error '%U'", format_unformat_error, i);
6676 return -99;
6677 }
6678 }
6679
6680 if (range_set == 0)
6681 {
6682 errmsg ("address range not set");
6683 return -99;
6684 }
6685
6686 M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6687
6688 mp->vrf_id = ntohl (vrf_id);
6689 mp->is_add = is_add;
6690 clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6691 clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6692
6693 S;
6694 W;
6695 /* NOTREACHED */
6696 return 0;
6697}
6698
6699static int
6700api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6701{
6702 unformat_input_t *i = vam->input;
6703 vl_api_proxy_arp_intfc_enable_disable_t *mp;
6704 f64 timeout;
6705 u32 sw_if_index;
6706 u8 enable = 1;
6707 u8 sw_if_index_set = 0;
6708
6709 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6710 {
6711 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6712 sw_if_index_set = 1;
6713 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6714 sw_if_index_set = 1;
6715 else if (unformat (i, "enable"))
6716 enable = 1;
6717 else if (unformat (i, "disable"))
6718 enable = 0;
6719 else
6720 {
6721 clib_warning ("parse error '%U'", format_unformat_error, i);
6722 return -99;
6723 }
6724 }
6725
6726 if (sw_if_index_set == 0)
6727 {
6728 errmsg ("missing interface name or sw_if_index");
6729 return -99;
6730 }
6731
6732 M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6733
6734 mp->sw_if_index = ntohl (sw_if_index);
6735 mp->enable_disable = enable;
6736
6737 S;
6738 W;
6739 /* NOTREACHED */
6740 return 0;
6741}
6742
6743static int
6744api_mpls_tunnel_add_del (vat_main_t * vam)
6745{
6746 unformat_input_t *i = vam->input;
6747 vl_api_mpls_tunnel_add_del_t *mp;
6748 f64 timeout;
6749
6750 u8 is_add = 1;
6751 u8 l2_only = 0;
6752 u32 sw_if_index = ~0;
6753 u32 next_hop_sw_if_index = ~0;
6754 u32 next_hop_proto_is_ip4 = 1;
6755
6756 u32 next_hop_table_id = 0;
6757 ip4_address_t v4_next_hop_address = {
6758 .as_u32 = 0,
6759 };
6760 ip6_address_t v6_next_hop_address = { {0} };
6761 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
6762
6763 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6764 {
6765 if (unformat (i, "add"))
6766 is_add = 1;
6767 else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6768 is_add = 0;
6769 else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
6770 ;
6771 else if (unformat (i, "via %U",
6772 unformat_ip4_address, &v4_next_hop_address))
6773 {
6774 next_hop_proto_is_ip4 = 1;
6775 }
6776 else if (unformat (i, "via %U",
6777 unformat_ip6_address, &v6_next_hop_address))
6778 {
6779 next_hop_proto_is_ip4 = 0;
6780 }
6781 else if (unformat (i, "l2-only"))
6782 l2_only = 1;
6783 else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6784 ;
6785 else if (unformat (i, "out-label %d", &next_hop_out_label))
6786 vec_add1 (labels, ntohl (next_hop_out_label));
6787 else
6788 {
6789 clib_warning ("parse error '%U'", format_unformat_error, i);
6790 return -99;
6791 }
6792 }
6793
6794 M2 (MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del,
6795 sizeof (mpls_label_t) * vec_len (labels));
6796
6797 mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
6798 mp->mt_sw_if_index = ntohl (sw_if_index);
6799 mp->mt_is_add = is_add;
6800 mp->mt_l2_only = l2_only;
6801 mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
6802 mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6803
6804 mp->mt_next_hop_n_out_labels = vec_len (labels);
6805
6806 if (0 != mp->mt_next_hop_n_out_labels)
6807 {
6808 clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
6809 sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
6810 vec_free (labels);
6811 }
6812
6813 if (next_hop_proto_is_ip4)
6814 {
6815 clib_memcpy (mp->mt_next_hop,
6816 &v4_next_hop_address, sizeof (v4_next_hop_address));
6817 }
6818 else
6819 {
6820 clib_memcpy (mp->mt_next_hop,
6821 &v6_next_hop_address, sizeof (v6_next_hop_address));
6822 }
6823
6824 S;
6825 W;
6826 /* NOTREACHED */
6827 return 0;
6828}
6829
6830static int
6831api_sw_interface_set_unnumbered (vat_main_t * vam)
6832{
6833 unformat_input_t *i = vam->input;
6834 vl_api_sw_interface_set_unnumbered_t *mp;
6835 f64 timeout;
6836 u32 sw_if_index;
6837 u32 unnum_sw_index = ~0;
6838 u8 is_add = 1;
6839 u8 sw_if_index_set = 0;
6840
6841 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6842 {
6843 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6844 sw_if_index_set = 1;
6845 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6846 sw_if_index_set = 1;
6847 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6848 ;
6849 else if (unformat (i, "del"))
6850 is_add = 0;
6851 else
6852 {
6853 clib_warning ("parse error '%U'", format_unformat_error, i);
6854 return -99;
6855 }
6856 }
6857
6858 if (sw_if_index_set == 0)
6859 {
6860 errmsg ("missing interface name or sw_if_index");
6861 return -99;
6862 }
6863
6864 M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6865
6866 mp->sw_if_index = ntohl (sw_if_index);
6867 mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6868 mp->is_add = is_add;
6869
6870 S;
6871 W;
6872 /* NOTREACHED */
6873 return 0;
6874}
6875
6876static int
6877api_ip_neighbor_add_del (vat_main_t * vam)
6878{
6879 unformat_input_t *i = vam->input;
6880 vl_api_ip_neighbor_add_del_t *mp;
6881 f64 timeout;
6882 u32 sw_if_index;
6883 u8 sw_if_index_set = 0;
6884 u32 vrf_id = 0;
6885 u8 is_add = 1;
6886 u8 is_static = 0;
6887 u8 mac_address[6];
6888 u8 mac_set = 0;
6889 u8 v4_address_set = 0;
6890 u8 v6_address_set = 0;
6891 ip4_address_t v4address;
6892 ip6_address_t v6address;
6893
6894 memset (mac_address, 0, sizeof (mac_address));
6895
6896 /* Parse args required to build the message */
6897 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6898 {
6899 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6900 {
6901 mac_set = 1;
6902 }
6903 else if (unformat (i, "del"))
6904 is_add = 0;
6905 else
6906 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6907 sw_if_index_set = 1;
6908 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6909 sw_if_index_set = 1;
6910 else if (unformat (i, "is_static"))
6911 is_static = 1;
6912 else if (unformat (i, "vrf %d", &vrf_id))
6913 ;
6914 else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6915 v4_address_set = 1;
6916 else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6917 v6_address_set = 1;
6918 else
6919 {
6920 clib_warning ("parse error '%U'", format_unformat_error, i);
6921 return -99;
6922 }
6923 }
6924
6925 if (sw_if_index_set == 0)
6926 {
6927 errmsg ("missing interface name or sw_if_index");
6928 return -99;
6929 }
6930 if (v4_address_set && v6_address_set)
6931 {
6932 errmsg ("both v4 and v6 addresses set");
6933 return -99;
6934 }
6935 if (!v4_address_set && !v6_address_set)
6936 {
6937 errmsg ("no address set");
6938 return -99;
6939 }
6940
6941 /* Construct the API message */
6942 M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6943
6944 mp->sw_if_index = ntohl (sw_if_index);
6945 mp->is_add = is_add;
6946 mp->vrf_id = ntohl (vrf_id);
6947 mp->is_static = is_static;
6948 if (mac_set)
6949 clib_memcpy (mp->mac_address, mac_address, 6);
6950 if (v6_address_set)
6951 {
6952 mp->is_ipv6 = 1;
6953 clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6954 }
6955 else
6956 {
6957 /* mp->is_ipv6 = 0; via memset in M macro above */
6958 clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6959 }
6960
6961 /* send it... */
6962 S;
6963
6964 /* Wait for a reply, return good/bad news */
6965 W;
6966
6967 /* NOTREACHED */
6968 return 0;
6969}
6970
6971static int
6972api_reset_vrf (vat_main_t * vam)
6973{
6974 unformat_input_t *i = vam->input;
6975 vl_api_reset_vrf_t *mp;
6976 f64 timeout;
6977 u32 vrf_id = 0;
6978 u8 is_ipv6 = 0;
6979 u8 vrf_id_set = 0;
6980
6981 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6982 {
6983 if (unformat (i, "vrf %d", &vrf_id))
6984 vrf_id_set = 1;
6985 else if (unformat (i, "ipv6"))
6986 is_ipv6 = 1;
6987 else
6988 {
6989 clib_warning ("parse error '%U'", format_unformat_error, i);
6990 return -99;
6991 }
6992 }
6993
6994 if (vrf_id_set == 0)
6995 {
6996 errmsg ("missing vrf id");
6997 return -99;
6998 }
6999
7000 M (RESET_VRF, reset_vrf);
7001
7002 mp->vrf_id = ntohl (vrf_id);
7003 mp->is_ipv6 = is_ipv6;
7004
7005 S;
7006 W;
7007 /* NOTREACHED */
7008 return 0;
7009}
7010
7011static int
7012api_create_vlan_subif (vat_main_t * vam)
7013{
7014 unformat_input_t *i = vam->input;
7015 vl_api_create_vlan_subif_t *mp;
7016 f64 timeout;
7017 u32 sw_if_index;
7018 u8 sw_if_index_set = 0;
7019 u32 vlan_id;
7020 u8 vlan_id_set = 0;
7021
7022 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7023 {
7024 if (unformat (i, "sw_if_index %d", &sw_if_index))
7025 sw_if_index_set = 1;
7026 else
7027 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7028 sw_if_index_set = 1;
7029 else if (unformat (i, "vlan %d", &vlan_id))
7030 vlan_id_set = 1;
7031 else
7032 {
7033 clib_warning ("parse error '%U'", format_unformat_error, i);
7034 return -99;
7035 }
7036 }
7037
7038 if (sw_if_index_set == 0)
7039 {
7040 errmsg ("missing interface name or sw_if_index");
7041 return -99;
7042 }
7043
7044 if (vlan_id_set == 0)
7045 {
7046 errmsg ("missing vlan_id");
7047 return -99;
7048 }
7049 M (CREATE_VLAN_SUBIF, create_vlan_subif);
7050
7051 mp->sw_if_index = ntohl (sw_if_index);
7052 mp->vlan_id = ntohl (vlan_id);
7053
7054 S;
7055 W;
7056 /* NOTREACHED */
7057 return 0;
7058}
7059
7060#define foreach_create_subif_bit \
7061_(no_tags) \
7062_(one_tag) \
7063_(two_tags) \
7064_(dot1ad) \
7065_(exact_match) \
7066_(default_sub) \
7067_(outer_vlan_id_any) \
7068_(inner_vlan_id_any)
7069
7070static int
7071api_create_subif (vat_main_t * vam)
7072{
7073 unformat_input_t *i = vam->input;
7074 vl_api_create_subif_t *mp;
7075 f64 timeout;
7076 u32 sw_if_index;
7077 u8 sw_if_index_set = 0;
7078 u32 sub_id;
7079 u8 sub_id_set = 0;
7080 u32 no_tags = 0;
7081 u32 one_tag = 0;
7082 u32 two_tags = 0;
7083 u32 dot1ad = 0;
7084 u32 exact_match = 0;
7085 u32 default_sub = 0;
7086 u32 outer_vlan_id_any = 0;
7087 u32 inner_vlan_id_any = 0;
7088 u32 tmp;
7089 u16 outer_vlan_id = 0;
7090 u16 inner_vlan_id = 0;
7091
7092 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7093 {
7094 if (unformat (i, "sw_if_index %d", &sw_if_index))
7095 sw_if_index_set = 1;
7096 else
7097 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7098 sw_if_index_set = 1;
7099 else if (unformat (i, "sub_id %d", &sub_id))
7100 sub_id_set = 1;
7101 else if (unformat (i, "outer_vlan_id %d", &tmp))
7102 outer_vlan_id = tmp;
7103 else if (unformat (i, "inner_vlan_id %d", &tmp))
7104 inner_vlan_id = tmp;
7105
7106#define _(a) else if (unformat (i, #a)) a = 1 ;
7107 foreach_create_subif_bit
7108#undef _
7109 else
7110 {
7111 clib_warning ("parse error '%U'", format_unformat_error, i);
7112 return -99;
7113 }
7114 }
7115
7116 if (sw_if_index_set == 0)
7117 {
7118 errmsg ("missing interface name or sw_if_index");
7119 return -99;
7120 }
7121
7122 if (sub_id_set == 0)
7123 {
7124 errmsg ("missing sub_id");
7125 return -99;
7126 }
7127 M (CREATE_SUBIF, create_subif);
7128
7129 mp->sw_if_index = ntohl (sw_if_index);
7130 mp->sub_id = ntohl (sub_id);
7131
7132#define _(a) mp->a = a;
7133 foreach_create_subif_bit;
7134#undef _
7135
7136 mp->outer_vlan_id = ntohs (outer_vlan_id);
7137 mp->inner_vlan_id = ntohs (inner_vlan_id);
7138
7139 S;
7140 W;
7141 /* NOTREACHED */
7142 return 0;
7143}
7144
7145static int
7146api_oam_add_del (vat_main_t * vam)
7147{
7148 unformat_input_t *i = vam->input;
7149 vl_api_oam_add_del_t *mp;
7150 f64 timeout;
7151 u32 vrf_id = 0;
7152 u8 is_add = 1;
7153 ip4_address_t src, dst;
7154 u8 src_set = 0;
7155 u8 dst_set = 0;
7156
7157 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7158 {
7159 if (unformat (i, "vrf %d", &vrf_id))
7160 ;
7161 else if (unformat (i, "src %U", unformat_ip4_address, &src))
7162 src_set = 1;
7163 else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7164 dst_set = 1;
7165 else if (unformat (i, "del"))
7166 is_add = 0;
7167 else
7168 {
7169 clib_warning ("parse error '%U'", format_unformat_error, i);
7170 return -99;
7171 }
7172 }
7173
7174 if (src_set == 0)
7175 {
7176 errmsg ("missing src addr");
7177 return -99;
7178 }
7179
7180 if (dst_set == 0)
7181 {
7182 errmsg ("missing dst addr");
7183 return -99;
7184 }
7185
7186 M (OAM_ADD_DEL, oam_add_del);
7187
7188 mp->vrf_id = ntohl (vrf_id);
7189 mp->is_add = is_add;
7190 clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7191 clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7192
7193 S;
7194 W;
7195 /* NOTREACHED */
7196 return 0;
7197}
7198
7199static int
7200api_reset_fib (vat_main_t * vam)
7201{
7202 unformat_input_t *i = vam->input;
7203 vl_api_reset_fib_t *mp;
7204 f64 timeout;
7205 u32 vrf_id = 0;
7206 u8 is_ipv6 = 0;
7207 u8 vrf_id_set = 0;
7208
7209 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7210 {
7211 if (unformat (i, "vrf %d", &vrf_id))
7212 vrf_id_set = 1;
7213 else if (unformat (i, "ipv6"))
7214 is_ipv6 = 1;
7215 else
7216 {
7217 clib_warning ("parse error '%U'", format_unformat_error, i);
7218 return -99;
7219 }
7220 }
7221
7222 if (vrf_id_set == 0)
7223 {
7224 errmsg ("missing vrf id");
7225 return -99;
7226 }
7227
7228 M (RESET_FIB, reset_fib);
7229
7230 mp->vrf_id = ntohl (vrf_id);
7231 mp->is_ipv6 = is_ipv6;
7232
7233 S;
7234 W;
7235 /* NOTREACHED */
7236 return 0;
7237}
7238
7239static int
7240api_dhcp_proxy_config (vat_main_t * vam)
7241{
7242 unformat_input_t *i = vam->input;
7243 vl_api_dhcp_proxy_config_t *mp;
7244 f64 timeout;
7245 u32 vrf_id = 0;
7246 u8 is_add = 1;
7247 u8 insert_cid = 1;
7248 u8 v4_address_set = 0;
7249 u8 v6_address_set = 0;
7250 ip4_address_t v4address;
7251 ip6_address_t v6address;
7252 u8 v4_src_address_set = 0;
7253 u8 v6_src_address_set = 0;
7254 ip4_address_t v4srcaddress;
7255 ip6_address_t v6srcaddress;
7256
7257 /* Parse args required to build the message */
7258 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7259 {
7260 if (unformat (i, "del"))
7261 is_add = 0;
7262 else if (unformat (i, "vrf %d", &vrf_id))
7263 ;
7264 else if (unformat (i, "insert-cid %d", &insert_cid))
7265 ;
7266 else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7267 v4_address_set = 1;
7268 else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7269 v6_address_set = 1;
7270 else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7271 v4_src_address_set = 1;
7272 else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7273 v6_src_address_set = 1;
7274 else
7275 break;
7276 }
7277
7278 if (v4_address_set && v6_address_set)
7279 {
7280 errmsg ("both v4 and v6 server addresses set");
7281 return -99;
7282 }
7283 if (!v4_address_set && !v6_address_set)
7284 {
7285 errmsg ("no server addresses set");
7286 return -99;
7287 }
7288
7289 if (v4_src_address_set && v6_src_address_set)
7290 {
7291 errmsg ("both v4 and v6 src addresses set");
7292 return -99;
7293 }
7294 if (!v4_src_address_set && !v6_src_address_set)
7295 {
7296 errmsg ("no src addresses set");
7297 return -99;
7298 }
7299
7300 if (!(v4_src_address_set && v4_address_set) &&
7301 !(v6_src_address_set && v6_address_set))
7302 {
7303 errmsg ("no matching server and src addresses set");
7304 return -99;
7305 }
7306
7307 /* Construct the API message */
7308 M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7309
7310 mp->insert_circuit_id = insert_cid;
7311 mp->is_add = is_add;
7312 mp->vrf_id = ntohl (vrf_id);
7313 if (v6_address_set)
7314 {
7315 mp->is_ipv6 = 1;
7316 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7317 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7318 }
7319 else
7320 {
7321 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7322 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7323 }
7324
7325 /* send it... */
7326 S;
7327
7328 /* Wait for a reply, return good/bad news */
7329 W;
7330 /* NOTREACHED */
7331 return 0;
7332}
7333
7334static int
7335api_dhcp_proxy_config_2 (vat_main_t * vam)
7336{
7337 unformat_input_t *i = vam->input;
7338 vl_api_dhcp_proxy_config_2_t *mp;
7339 f64 timeout;
7340 u32 rx_vrf_id = 0;
7341 u32 server_vrf_id = 0;
7342 u8 is_add = 1;
7343 u8 insert_cid = 1;
7344 u8 v4_address_set = 0;
7345 u8 v6_address_set = 0;
7346 ip4_address_t v4address;
7347 ip6_address_t v6address;
7348 u8 v4_src_address_set = 0;
7349 u8 v6_src_address_set = 0;
7350 ip4_address_t v4srcaddress;
7351 ip6_address_t v6srcaddress;
7352
7353 /* Parse args required to build the message */
7354 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7355 {
7356 if (unformat (i, "del"))
7357 is_add = 0;
7358 else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7359 ;
7360 else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7361 ;
7362 else if (unformat (i, "insert-cid %d", &insert_cid))
7363 ;
7364 else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7365 v4_address_set = 1;
7366 else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7367 v6_address_set = 1;
7368 else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7369 v4_src_address_set = 1;
7370 else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7371 v6_src_address_set = 1;
7372 else
7373 break;
7374 }
7375
7376 if (v4_address_set && v6_address_set)
7377 {
7378 errmsg ("both v4 and v6 server addresses set");
7379 return -99;
7380 }
7381 if (!v4_address_set && !v6_address_set)
7382 {
7383 errmsg ("no server addresses set");
7384 return -99;
7385 }
7386
7387 if (v4_src_address_set && v6_src_address_set)
7388 {
7389 errmsg ("both v4 and v6 src addresses set");
7390 return -99;
7391 }
7392 if (!v4_src_address_set && !v6_src_address_set)
7393 {
7394 errmsg ("no src addresses set");
7395 return -99;
7396 }
7397
7398 if (!(v4_src_address_set && v4_address_set) &&
7399 !(v6_src_address_set && v6_address_set))
7400 {
7401 errmsg ("no matching server and src addresses set");
7402 return -99;
7403 }
7404
7405 /* Construct the API message */
7406 M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7407
7408 mp->insert_circuit_id = insert_cid;
7409 mp->is_add = is_add;
7410 mp->rx_vrf_id = ntohl (rx_vrf_id);
7411 mp->server_vrf_id = ntohl (server_vrf_id);
7412 if (v6_address_set)
7413 {
7414 mp->is_ipv6 = 1;
7415 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7416 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7417 }
7418 else
7419 {
7420 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7421 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7422 }
7423
7424 /* send it... */
7425 S;
7426
7427 /* Wait for a reply, return good/bad news */
7428 W;
7429 /* NOTREACHED */
7430 return 0;
7431}
7432
7433static int
7434api_dhcp_proxy_set_vss (vat_main_t * vam)
7435{
7436 unformat_input_t *i = vam->input;
7437 vl_api_dhcp_proxy_set_vss_t *mp;
7438 f64 timeout;
7439 u8 is_ipv6 = 0;
7440 u8 is_add = 1;
7441 u32 tbl_id;
7442 u8 tbl_id_set = 0;
7443 u32 oui;
7444 u8 oui_set = 0;
7445 u32 fib_id;
7446 u8 fib_id_set = 0;
7447
7448 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7449 {
7450 if (unformat (i, "tbl_id %d", &tbl_id))
7451 tbl_id_set = 1;
7452 if (unformat (i, "fib_id %d", &fib_id))
7453 fib_id_set = 1;
7454 if (unformat (i, "oui %d", &oui))
7455 oui_set = 1;
7456 else if (unformat (i, "ipv6"))
7457 is_ipv6 = 1;
7458 else if (unformat (i, "del"))
7459 is_add = 0;
7460 else
7461 {
7462 clib_warning ("parse error '%U'", format_unformat_error, i);
7463 return -99;
7464 }
7465 }
7466
7467 if (tbl_id_set == 0)
7468 {
7469 errmsg ("missing tbl id");
7470 return -99;
7471 }
7472
7473 if (fib_id_set == 0)
7474 {
7475 errmsg ("missing fib id");
7476 return -99;
7477 }
7478 if (oui_set == 0)
7479 {
7480 errmsg ("missing oui");
7481 return -99;
7482 }
7483
7484 M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7485 mp->tbl_id = ntohl (tbl_id);
7486 mp->fib_id = ntohl (fib_id);
7487 mp->oui = ntohl (oui);
7488 mp->is_ipv6 = is_ipv6;
7489 mp->is_add = is_add;
7490
7491 S;
7492 W;
7493 /* NOTREACHED */
7494 return 0;
7495}
7496
7497static int
7498api_dhcp_client_config (vat_main_t * vam)
7499{
7500 unformat_input_t *i = vam->input;
7501 vl_api_dhcp_client_config_t *mp;
7502 f64 timeout;
7503 u32 sw_if_index;
7504 u8 sw_if_index_set = 0;
7505 u8 is_add = 1;
7506 u8 *hostname = 0;
7507 u8 disable_event = 0;
7508
7509 /* Parse args required to build the message */
7510 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7511 {
7512 if (unformat (i, "del"))
7513 is_add = 0;
7514 else
7515 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7516 sw_if_index_set = 1;
7517 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7518 sw_if_index_set = 1;
7519 else if (unformat (i, "hostname %s", &hostname))
7520 ;
7521 else if (unformat (i, "disable_event"))
7522 disable_event = 1;
7523 else
7524 break;
7525 }
7526
7527 if (sw_if_index_set == 0)
7528 {
7529 errmsg ("missing interface name or sw_if_index");
7530 return -99;
7531 }
7532
7533 if (vec_len (hostname) > 63)
7534 {
7535 errmsg ("hostname too long");
7536 }
7537 vec_add1 (hostname, 0);
7538
7539 /* Construct the API message */
7540 M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7541
7542 mp->sw_if_index = ntohl (sw_if_index);
7543 clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7544 vec_free (hostname);
7545 mp->is_add = is_add;
7546 mp->want_dhcp_event = disable_event ? 0 : 1;
7547 mp->pid = getpid ();
7548
7549 /* send it... */
7550 S;
7551
7552 /* Wait for a reply, return good/bad news */
7553 W;
7554 /* NOTREACHED */
7555 return 0;
7556}
7557
7558static int
7559api_set_ip_flow_hash (vat_main_t * vam)
7560{
7561 unformat_input_t *i = vam->input;
7562 vl_api_set_ip_flow_hash_t *mp;
7563 f64 timeout;
7564 u32 vrf_id = 0;
7565 u8 is_ipv6 = 0;
7566 u8 vrf_id_set = 0;
7567 u8 src = 0;
7568 u8 dst = 0;
7569 u8 sport = 0;
7570 u8 dport = 0;
7571 u8 proto = 0;
7572 u8 reverse = 0;
7573
7574 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7575 {
7576 if (unformat (i, "vrf %d", &vrf_id))
7577 vrf_id_set = 1;
7578 else if (unformat (i, "ipv6"))
7579 is_ipv6 = 1;
7580 else if (unformat (i, "src"))
7581 src = 1;
7582 else if (unformat (i, "dst"))
7583 dst = 1;
7584 else if (unformat (i, "sport"))
7585 sport = 1;
7586 else if (unformat (i, "dport"))
7587 dport = 1;
7588 else if (unformat (i, "proto"))
7589 proto = 1;
7590 else if (unformat (i, "reverse"))
7591 reverse = 1;
7592
7593 else
7594 {
7595 clib_warning ("parse error '%U'", format_unformat_error, i);
7596 return -99;
7597 }
7598 }
7599
7600 if (vrf_id_set == 0)
7601 {
7602 errmsg ("missing vrf id");
7603 return -99;
7604 }
7605
7606 M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7607 mp->src = src;
7608 mp->dst = dst;
7609 mp->sport = sport;
7610 mp->dport = dport;
7611 mp->proto = proto;
7612 mp->reverse = reverse;
7613 mp->vrf_id = ntohl (vrf_id);
7614 mp->is_ipv6 = is_ipv6;
7615
7616 S;
7617 W;
7618 /* NOTREACHED */
7619 return 0;
7620}
7621
7622static int
7623api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7624{
7625 unformat_input_t *i = vam->input;
7626 vl_api_sw_interface_ip6_enable_disable_t *mp;
7627 f64 timeout;
7628 u32 sw_if_index;
7629 u8 sw_if_index_set = 0;
7630 u8 enable = 0;
7631
7632 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7633 {
7634 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7635 sw_if_index_set = 1;
7636 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7637 sw_if_index_set = 1;
7638 else if (unformat (i, "enable"))
7639 enable = 1;
7640 else if (unformat (i, "disable"))
7641 enable = 0;
7642 else
7643 {
7644 clib_warning ("parse error '%U'", format_unformat_error, i);
7645 return -99;
7646 }
7647 }
7648
7649 if (sw_if_index_set == 0)
7650 {
7651 errmsg ("missing interface name or sw_if_index");
7652 return -99;
7653 }
7654
7655 M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7656
7657 mp->sw_if_index = ntohl (sw_if_index);
7658 mp->enable = enable;
7659
7660 S;
7661 W;
7662 /* NOTREACHED */
7663 return 0;
7664}
7665
7666static int
7667api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7668{
7669 unformat_input_t *i = vam->input;
7670 vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7671 f64 timeout;
7672 u32 sw_if_index;
7673 u8 sw_if_index_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007674 u8 v6_address_set = 0;
7675 ip6_address_t v6address;
7676
7677 /* Parse args required to build the message */
7678 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7679 {
7680 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7681 sw_if_index_set = 1;
7682 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7683 sw_if_index_set = 1;
Neale Ranns75152282017-01-09 01:00:45 -08007684 else if (unformat (i, "%U", unformat_ip6_address, &v6address))
Damjan Marion7cd468a2016-12-19 23:05:39 +01007685 v6_address_set = 1;
7686 else
7687 break;
7688 }
7689
7690 if (sw_if_index_set == 0)
7691 {
7692 errmsg ("missing interface name or sw_if_index");
7693 return -99;
7694 }
7695 if (!v6_address_set)
7696 {
7697 errmsg ("no address set");
7698 return -99;
7699 }
7700
7701 /* Construct the API message */
7702 M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7703 sw_interface_ip6_set_link_local_address);
7704
7705 mp->sw_if_index = ntohl (sw_if_index);
7706 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007707
7708 /* send it... */
7709 S;
7710
7711 /* Wait for a reply, return good/bad news */
7712 W;
7713
7714 /* NOTREACHED */
7715 return 0;
7716}
7717
7718
7719static int
7720api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7721{
7722 unformat_input_t *i = vam->input;
7723 vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7724 f64 timeout;
7725 u32 sw_if_index;
7726 u8 sw_if_index_set = 0;
7727 u32 address_length = 0;
7728 u8 v6_address_set = 0;
7729 ip6_address_t v6address;
7730 u8 use_default = 0;
7731 u8 no_advertise = 0;
7732 u8 off_link = 0;
7733 u8 no_autoconfig = 0;
7734 u8 no_onlink = 0;
7735 u8 is_no = 0;
7736 u32 val_lifetime = 0;
7737 u32 pref_lifetime = 0;
7738
7739 /* Parse args required to build the message */
7740 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7741 {
7742 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7743 sw_if_index_set = 1;
7744 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7745 sw_if_index_set = 1;
7746 else if (unformat (i, "%U/%d",
7747 unformat_ip6_address, &v6address, &address_length))
7748 v6_address_set = 1;
7749 else if (unformat (i, "val_life %d", &val_lifetime))
7750 ;
7751 else if (unformat (i, "pref_life %d", &pref_lifetime))
7752 ;
7753 else if (unformat (i, "def"))
7754 use_default = 1;
7755 else if (unformat (i, "noadv"))
7756 no_advertise = 1;
7757 else if (unformat (i, "offl"))
7758 off_link = 1;
7759 else if (unformat (i, "noauto"))
7760 no_autoconfig = 1;
7761 else if (unformat (i, "nolink"))
7762 no_onlink = 1;
7763 else if (unformat (i, "isno"))
7764 is_no = 1;
7765 else
7766 {
7767 clib_warning ("parse error '%U'", format_unformat_error, i);
7768 return -99;
7769 }
7770 }
7771
7772 if (sw_if_index_set == 0)
7773 {
7774 errmsg ("missing interface name or sw_if_index");
7775 return -99;
7776 }
7777 if (!v6_address_set)
7778 {
7779 errmsg ("no address set");
7780 return -99;
7781 }
7782
7783 /* Construct the API message */
7784 M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7785
7786 mp->sw_if_index = ntohl (sw_if_index);
7787 clib_memcpy (mp->address, &v6address, sizeof (v6address));
7788 mp->address_length = address_length;
7789 mp->use_default = use_default;
7790 mp->no_advertise = no_advertise;
7791 mp->off_link = off_link;
7792 mp->no_autoconfig = no_autoconfig;
7793 mp->no_onlink = no_onlink;
7794 mp->is_no = is_no;
7795 mp->val_lifetime = ntohl (val_lifetime);
7796 mp->pref_lifetime = ntohl (pref_lifetime);
7797
7798 /* send it... */
7799 S;
7800
7801 /* Wait for a reply, return good/bad news */
7802 W;
7803
7804 /* NOTREACHED */
7805 return 0;
7806}
7807
7808static int
7809api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7810{
7811 unformat_input_t *i = vam->input;
7812 vl_api_sw_interface_ip6nd_ra_config_t *mp;
7813 f64 timeout;
7814 u32 sw_if_index;
7815 u8 sw_if_index_set = 0;
7816 u8 suppress = 0;
7817 u8 managed = 0;
7818 u8 other = 0;
7819 u8 ll_option = 0;
7820 u8 send_unicast = 0;
7821 u8 cease = 0;
7822 u8 is_no = 0;
7823 u8 default_router = 0;
7824 u32 max_interval = 0;
7825 u32 min_interval = 0;
7826 u32 lifetime = 0;
7827 u32 initial_count = 0;
7828 u32 initial_interval = 0;
7829
7830
7831 /* Parse args required to build the message */
7832 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7833 {
7834 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7835 sw_if_index_set = 1;
7836 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7837 sw_if_index_set = 1;
7838 else if (unformat (i, "maxint %d", &max_interval))
7839 ;
7840 else if (unformat (i, "minint %d", &min_interval))
7841 ;
7842 else if (unformat (i, "life %d", &lifetime))
7843 ;
7844 else if (unformat (i, "count %d", &initial_count))
7845 ;
7846 else if (unformat (i, "interval %d", &initial_interval))
7847 ;
7848 else if (unformat (i, "suppress") || unformat (i, "surpress"))
7849 suppress = 1;
7850 else if (unformat (i, "managed"))
7851 managed = 1;
7852 else if (unformat (i, "other"))
7853 other = 1;
7854 else if (unformat (i, "ll"))
7855 ll_option = 1;
7856 else if (unformat (i, "send"))
7857 send_unicast = 1;
7858 else if (unformat (i, "cease"))
7859 cease = 1;
7860 else if (unformat (i, "isno"))
7861 is_no = 1;
7862 else if (unformat (i, "def"))
7863 default_router = 1;
7864 else
7865 {
7866 clib_warning ("parse error '%U'", format_unformat_error, i);
7867 return -99;
7868 }
7869 }
7870
7871 if (sw_if_index_set == 0)
7872 {
7873 errmsg ("missing interface name or sw_if_index");
7874 return -99;
7875 }
7876
7877 /* Construct the API message */
7878 M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7879
7880 mp->sw_if_index = ntohl (sw_if_index);
7881 mp->max_interval = ntohl (max_interval);
7882 mp->min_interval = ntohl (min_interval);
7883 mp->lifetime = ntohl (lifetime);
7884 mp->initial_count = ntohl (initial_count);
7885 mp->initial_interval = ntohl (initial_interval);
7886 mp->suppress = suppress;
7887 mp->managed = managed;
7888 mp->other = other;
7889 mp->ll_option = ll_option;
7890 mp->send_unicast = send_unicast;
7891 mp->cease = cease;
7892 mp->is_no = is_no;
7893 mp->default_router = default_router;
7894
7895 /* send it... */
7896 S;
7897
7898 /* Wait for a reply, return good/bad news */
7899 W;
7900
7901 /* NOTREACHED */
7902 return 0;
7903}
7904
7905static int
7906api_set_arp_neighbor_limit (vat_main_t * vam)
7907{
7908 unformat_input_t *i = vam->input;
7909 vl_api_set_arp_neighbor_limit_t *mp;
7910 f64 timeout;
7911 u32 arp_nbr_limit;
7912 u8 limit_set = 0;
7913 u8 is_ipv6 = 0;
7914
7915 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7916 {
7917 if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7918 limit_set = 1;
7919 else if (unformat (i, "ipv6"))
7920 is_ipv6 = 1;
7921 else
7922 {
7923 clib_warning ("parse error '%U'", format_unformat_error, i);
7924 return -99;
7925 }
7926 }
7927
7928 if (limit_set == 0)
7929 {
7930 errmsg ("missing limit value");
7931 return -99;
7932 }
7933
7934 M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7935
7936 mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7937 mp->is_ipv6 = is_ipv6;
7938
7939 S;
7940 W;
7941 /* NOTREACHED */
7942 return 0;
7943}
7944
7945static int
7946api_l2_patch_add_del (vat_main_t * vam)
7947{
7948 unformat_input_t *i = vam->input;
7949 vl_api_l2_patch_add_del_t *mp;
7950 f64 timeout;
7951 u32 rx_sw_if_index;
7952 u8 rx_sw_if_index_set = 0;
7953 u32 tx_sw_if_index;
7954 u8 tx_sw_if_index_set = 0;
7955 u8 is_add = 1;
7956
7957 /* Parse args required to build the message */
7958 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7959 {
7960 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7961 rx_sw_if_index_set = 1;
7962 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7963 tx_sw_if_index_set = 1;
7964 else if (unformat (i, "rx"))
7965 {
7966 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7967 {
7968 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7969 &rx_sw_if_index))
7970 rx_sw_if_index_set = 1;
7971 }
7972 else
7973 break;
7974 }
7975 else if (unformat (i, "tx"))
7976 {
7977 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7978 {
7979 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7980 &tx_sw_if_index))
7981 tx_sw_if_index_set = 1;
7982 }
7983 else
7984 break;
7985 }
7986 else if (unformat (i, "del"))
7987 is_add = 0;
7988 else
7989 break;
7990 }
7991
7992 if (rx_sw_if_index_set == 0)
7993 {
7994 errmsg ("missing rx interface name or rx_sw_if_index");
7995 return -99;
7996 }
7997
7998 if (tx_sw_if_index_set == 0)
7999 {
8000 errmsg ("missing tx interface name or tx_sw_if_index");
8001 return -99;
8002 }
8003
8004 M (L2_PATCH_ADD_DEL, l2_patch_add_del);
8005
8006 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8007 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8008 mp->is_add = is_add;
8009
8010 S;
8011 W;
8012 /* NOTREACHED */
8013 return 0;
8014}
8015
8016static int
8017api_ioam_enable (vat_main_t * vam)
8018{
8019 unformat_input_t *input = vam->input;
8020 vl_api_ioam_enable_t *mp;
8021 f64 timeout;
8022 u32 id = 0;
8023 int has_trace_option = 0;
8024 int has_pot_option = 0;
8025 int has_seqno_option = 0;
8026 int has_analyse_option = 0;
8027
8028 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8029 {
8030 if (unformat (input, "trace"))
8031 has_trace_option = 1;
8032 else if (unformat (input, "pot"))
8033 has_pot_option = 1;
8034 else if (unformat (input, "seqno"))
8035 has_seqno_option = 1;
8036 else if (unformat (input, "analyse"))
8037 has_analyse_option = 1;
8038 else
8039 break;
8040 }
8041 M (IOAM_ENABLE, ioam_enable);
8042 mp->id = htons (id);
8043 mp->seqno = has_seqno_option;
8044 mp->analyse = has_analyse_option;
8045 mp->pot_enable = has_pot_option;
8046 mp->trace_enable = has_trace_option;
8047
8048 S;
8049 W;
8050
8051 return (0);
8052
8053}
8054
8055
8056static int
8057api_ioam_disable (vat_main_t * vam)
8058{
8059 vl_api_ioam_disable_t *mp;
8060 f64 timeout;
8061
8062 M (IOAM_DISABLE, ioam_disable);
8063 S;
8064 W;
8065 return 0;
8066}
8067
8068static int
8069api_sr_tunnel_add_del (vat_main_t * vam)
8070{
8071 unformat_input_t *i = vam->input;
8072 vl_api_sr_tunnel_add_del_t *mp;
8073 f64 timeout;
8074 int is_del = 0;
8075 int pl_index;
8076 ip6_address_t src_address;
8077 int src_address_set = 0;
8078 ip6_address_t dst_address;
8079 u32 dst_mask_width;
8080 int dst_address_set = 0;
8081 u16 flags = 0;
8082 u32 rx_table_id = 0;
8083 u32 tx_table_id = 0;
8084 ip6_address_t *segments = 0;
8085 ip6_address_t *this_seg;
8086 ip6_address_t *tags = 0;
8087 ip6_address_t *this_tag;
8088 ip6_address_t next_address, tag;
8089 u8 *name = 0;
8090 u8 *policy_name = 0;
8091
8092 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8093 {
8094 if (unformat (i, "del"))
8095 is_del = 1;
8096 else if (unformat (i, "name %s", &name))
8097 ;
8098 else if (unformat (i, "policy %s", &policy_name))
8099 ;
8100 else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8101 ;
8102 else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8103 ;
8104 else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8105 src_address_set = 1;
8106 else if (unformat (i, "dst %U/%d",
8107 unformat_ip6_address, &dst_address, &dst_mask_width))
8108 dst_address_set = 1;
8109 else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8110 {
8111 vec_add2 (segments, this_seg, 1);
8112 clib_memcpy (this_seg->as_u8, next_address.as_u8,
8113 sizeof (*this_seg));
8114 }
8115 else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8116 {
8117 vec_add2 (tags, this_tag, 1);
8118 clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8119 }
8120 else if (unformat (i, "clean"))
8121 flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8122 else if (unformat (i, "protected"))
8123 flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8124 else if (unformat (i, "InPE %d", &pl_index))
8125 {
8126 if (pl_index <= 0 || pl_index > 4)
8127 {
8128 pl_index_range_error:
8129 errmsg ("pl index %d out of range", pl_index);
8130 return -99;
8131 }
8132 flags |=
8133 IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8134 }
8135 else if (unformat (i, "EgPE %d", &pl_index))
8136 {
8137 if (pl_index <= 0 || pl_index > 4)
8138 goto pl_index_range_error;
8139 flags |=
8140 IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8141 }
8142 else if (unformat (i, "OrgSrc %d", &pl_index))
8143 {
8144 if (pl_index <= 0 || pl_index > 4)
8145 goto pl_index_range_error;
8146 flags |=
8147 IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8148 }
8149 else
8150 break;
8151 }
8152
8153 if (!src_address_set)
8154 {
8155 errmsg ("src address required");
8156 return -99;
8157 }
8158
8159 if (!dst_address_set)
8160 {
8161 errmsg ("dst address required");
8162 return -99;
8163 }
8164
8165 if (!segments)
8166 {
8167 errmsg ("at least one sr segment required");
8168 return -99;
8169 }
8170
8171 M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
8172 vec_len (segments) * sizeof (ip6_address_t)
8173 + vec_len (tags) * sizeof (ip6_address_t));
8174
8175 clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8176 clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8177 mp->dst_mask_width = dst_mask_width;
8178 mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8179 mp->n_segments = vec_len (segments);
8180 mp->n_tags = vec_len (tags);
8181 mp->is_add = is_del == 0;
8182 clib_memcpy (mp->segs_and_tags, segments,
8183 vec_len (segments) * sizeof (ip6_address_t));
8184 clib_memcpy (mp->segs_and_tags +
8185 vec_len (segments) * sizeof (ip6_address_t), tags,
8186 vec_len (tags) * sizeof (ip6_address_t));
8187
8188 mp->outer_vrf_id = ntohl (rx_table_id);
8189 mp->inner_vrf_id = ntohl (tx_table_id);
8190 memcpy (mp->name, name, vec_len (name));
8191 memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8192
8193 vec_free (segments);
8194 vec_free (tags);
8195
8196 S;
8197 W;
8198 /* NOTREACHED */
8199}
8200
8201static int
8202api_sr_policy_add_del (vat_main_t * vam)
8203{
8204 unformat_input_t *input = vam->input;
8205 vl_api_sr_policy_add_del_t *mp;
8206 f64 timeout;
8207 int is_del = 0;
8208 u8 *name = 0;
8209 u8 *tunnel_name = 0;
8210 u8 **tunnel_names = 0;
8211
8212 int name_set = 0;
8213 int tunnel_set = 0;
8214 int j = 0;
8215 int tunnel_names_length = 1; // Init to 1 to offset the #tunnel_names counter byte
8216 int tun_name_len = 0; // Different naming convention used as confusing these would be "bad" (TM)
8217
8218 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8219 {
8220 if (unformat (input, "del"))
8221 is_del = 1;
8222 else if (unformat (input, "name %s", &name))
8223 name_set = 1;
8224 else if (unformat (input, "tunnel %s", &tunnel_name))
8225 {
8226 if (tunnel_name)
8227 {
8228 vec_add1 (tunnel_names, tunnel_name);
8229 /* For serializer:
8230 - length = #bytes to store in serial vector
8231 - +1 = byte to store that length
8232 */
8233 tunnel_names_length += (vec_len (tunnel_name) + 1);
8234 tunnel_set = 1;
8235 tunnel_name = 0;
8236 }
8237 }
8238 else
8239 break;
8240 }
8241
8242 if (!name_set)
8243 {
8244 errmsg ("policy name required");
8245 return -99;
8246 }
8247
8248 if ((!tunnel_set) && (!is_del))
8249 {
8250 errmsg ("tunnel name required");
8251 return -99;
8252 }
8253
8254 M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8255
8256
8257
8258 mp->is_add = !is_del;
8259
8260 memcpy (mp->name, name, vec_len (name));
8261 // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8262 u8 *serial_orig = 0;
8263 vec_validate (serial_orig, tunnel_names_length);
8264 *serial_orig = vec_len (tunnel_names); // Store the number of tunnels as length in first byte of serialized vector
8265 serial_orig += 1; // Move along one byte to store the length of first tunnel_name
8266
8267 for (j = 0; j < vec_len (tunnel_names); j++)
8268 {
8269 tun_name_len = vec_len (tunnel_names[j]);
8270 *serial_orig = tun_name_len; // Store length of tunnel name in first byte of Length/Value pair
8271 serial_orig += 1; // Move along one byte to store the actual tunnel name
8272 memcpy (serial_orig, tunnel_names[j], tun_name_len);
8273 serial_orig += tun_name_len; // Advance past the copy
8274 }
8275 memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length); // Regress serial_orig to head then copy fwd
8276
8277 vec_free (tunnel_names);
8278 vec_free (tunnel_name);
8279
8280 S;
8281 W;
8282 /* NOTREACHED */
8283}
8284
8285static int
8286api_sr_multicast_map_add_del (vat_main_t * vam)
8287{
8288 unformat_input_t *input = vam->input;
8289 vl_api_sr_multicast_map_add_del_t *mp;
8290 f64 timeout;
8291 int is_del = 0;
8292 ip6_address_t multicast_address;
8293 u8 *policy_name = 0;
8294 int multicast_address_set = 0;
8295
8296 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8297 {
8298 if (unformat (input, "del"))
8299 is_del = 1;
8300 else
8301 if (unformat
8302 (input, "address %U", unformat_ip6_address, &multicast_address))
8303 multicast_address_set = 1;
8304 else if (unformat (input, "sr-policy %s", &policy_name))
8305 ;
8306 else
8307 break;
8308 }
8309
8310 if (!is_del && !policy_name)
8311 {
8312 errmsg ("sr-policy name required");
8313 return -99;
8314 }
8315
8316
8317 if (!multicast_address_set)
8318 {
8319 errmsg ("address required");
8320 return -99;
8321 }
8322
8323 M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8324
8325 mp->is_add = !is_del;
8326 memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8327 clib_memcpy (mp->multicast_address, &multicast_address,
8328 sizeof (mp->multicast_address));
8329
8330
8331 vec_free (policy_name);
8332
8333 S;
8334 W;
8335 /* NOTREACHED */
8336}
8337
8338
8339#define foreach_tcp_proto_field \
8340_(src_port) \
8341_(dst_port)
8342
8343#define foreach_udp_proto_field \
8344_(src_port) \
8345_(dst_port)
8346
8347#define foreach_ip4_proto_field \
8348_(src_address) \
8349_(dst_address) \
8350_(tos) \
8351_(length) \
8352_(fragment_id) \
8353_(ttl) \
8354_(protocol) \
8355_(checksum)
8356
8357uword
8358unformat_tcp_mask (unformat_input_t * input, va_list * args)
8359{
8360 u8 **maskp = va_arg (*args, u8 **);
8361 u8 *mask = 0;
8362 u8 found_something = 0;
8363 tcp_header_t *tcp;
8364
8365#define _(a) u8 a=0;
8366 foreach_tcp_proto_field;
8367#undef _
8368
8369 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8370 {
8371 if (0);
8372#define _(a) else if (unformat (input, #a)) a=1;
8373 foreach_tcp_proto_field
8374#undef _
8375 else
8376 break;
8377 }
8378
8379#define _(a) found_something += a;
8380 foreach_tcp_proto_field;
8381#undef _
8382
8383 if (found_something == 0)
8384 return 0;
8385
8386 vec_validate (mask, sizeof (*tcp) - 1);
8387
8388 tcp = (tcp_header_t *) mask;
8389
8390#define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8391 foreach_tcp_proto_field;
8392#undef _
8393
8394 *maskp = mask;
8395 return 1;
8396}
8397
8398uword
8399unformat_udp_mask (unformat_input_t * input, va_list * args)
8400{
8401 u8 **maskp = va_arg (*args, u8 **);
8402 u8 *mask = 0;
8403 u8 found_something = 0;
8404 udp_header_t *udp;
8405
8406#define _(a) u8 a=0;
8407 foreach_udp_proto_field;
8408#undef _
8409
8410 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8411 {
8412 if (0);
8413#define _(a) else if (unformat (input, #a)) a=1;
8414 foreach_udp_proto_field
8415#undef _
8416 else
8417 break;
8418 }
8419
8420#define _(a) found_something += a;
8421 foreach_udp_proto_field;
8422#undef _
8423
8424 if (found_something == 0)
8425 return 0;
8426
8427 vec_validate (mask, sizeof (*udp) - 1);
8428
8429 udp = (udp_header_t *) mask;
8430
8431#define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8432 foreach_udp_proto_field;
8433#undef _
8434
8435 *maskp = mask;
8436 return 1;
8437}
8438
8439typedef struct
8440{
8441 u16 src_port, dst_port;
8442} tcpudp_header_t;
8443
8444uword
8445unformat_l4_mask (unformat_input_t * input, va_list * args)
8446{
8447 u8 **maskp = va_arg (*args, u8 **);
8448 u16 src_port = 0, dst_port = 0;
8449 tcpudp_header_t *tcpudp;
8450
8451 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8452 {
8453 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8454 return 1;
8455 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8456 return 1;
8457 else if (unformat (input, "src_port"))
8458 src_port = 0xFFFF;
8459 else if (unformat (input, "dst_port"))
8460 dst_port = 0xFFFF;
8461 else
8462 return 0;
8463 }
8464
8465 if (!src_port && !dst_port)
8466 return 0;
8467
8468 u8 *mask = 0;
8469 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8470
8471 tcpudp = (tcpudp_header_t *) mask;
8472 tcpudp->src_port = src_port;
8473 tcpudp->dst_port = dst_port;
8474
8475 *maskp = mask;
8476
8477 return 1;
8478}
8479
8480uword
8481unformat_ip4_mask (unformat_input_t * input, va_list * args)
8482{
8483 u8 **maskp = va_arg (*args, u8 **);
8484 u8 *mask = 0;
8485 u8 found_something = 0;
8486 ip4_header_t *ip;
8487
8488#define _(a) u8 a=0;
8489 foreach_ip4_proto_field;
8490#undef _
8491 u8 version = 0;
8492 u8 hdr_length = 0;
8493
8494
8495 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8496 {
8497 if (unformat (input, "version"))
8498 version = 1;
8499 else if (unformat (input, "hdr_length"))
8500 hdr_length = 1;
8501 else if (unformat (input, "src"))
8502 src_address = 1;
8503 else if (unformat (input, "dst"))
8504 dst_address = 1;
8505 else if (unformat (input, "proto"))
8506 protocol = 1;
8507
8508#define _(a) else if (unformat (input, #a)) a=1;
8509 foreach_ip4_proto_field
8510#undef _
8511 else
8512 break;
8513 }
8514
8515#define _(a) found_something += a;
8516 foreach_ip4_proto_field;
8517#undef _
8518
8519 if (found_something == 0)
8520 return 0;
8521
8522 vec_validate (mask, sizeof (*ip) - 1);
8523
8524 ip = (ip4_header_t *) mask;
8525
8526#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8527 foreach_ip4_proto_field;
8528#undef _
8529
8530 ip->ip_version_and_header_length = 0;
8531
8532 if (version)
8533 ip->ip_version_and_header_length |= 0xF0;
8534
8535 if (hdr_length)
8536 ip->ip_version_and_header_length |= 0x0F;
8537
8538 *maskp = mask;
8539 return 1;
8540}
8541
8542#define foreach_ip6_proto_field \
8543_(src_address) \
8544_(dst_address) \
8545_(payload_length) \
8546_(hop_limit) \
8547_(protocol)
8548
8549uword
8550unformat_ip6_mask (unformat_input_t * input, va_list * args)
8551{
8552 u8 **maskp = va_arg (*args, u8 **);
8553 u8 *mask = 0;
8554 u8 found_something = 0;
8555 ip6_header_t *ip;
8556 u32 ip_version_traffic_class_and_flow_label;
8557
8558#define _(a) u8 a=0;
8559 foreach_ip6_proto_field;
8560#undef _
8561 u8 version = 0;
8562 u8 traffic_class = 0;
8563 u8 flow_label = 0;
8564
8565 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8566 {
8567 if (unformat (input, "version"))
8568 version = 1;
8569 else if (unformat (input, "traffic-class"))
8570 traffic_class = 1;
8571 else if (unformat (input, "flow-label"))
8572 flow_label = 1;
8573 else if (unformat (input, "src"))
8574 src_address = 1;
8575 else if (unformat (input, "dst"))
8576 dst_address = 1;
8577 else if (unformat (input, "proto"))
8578 protocol = 1;
8579
8580#define _(a) else if (unformat (input, #a)) a=1;
8581 foreach_ip6_proto_field
8582#undef _
8583 else
8584 break;
8585 }
8586
8587#define _(a) found_something += a;
8588 foreach_ip6_proto_field;
8589#undef _
8590
8591 if (found_something == 0)
8592 return 0;
8593
8594 vec_validate (mask, sizeof (*ip) - 1);
8595
8596 ip = (ip6_header_t *) mask;
8597
8598#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8599 foreach_ip6_proto_field;
8600#undef _
8601
8602 ip_version_traffic_class_and_flow_label = 0;
8603
8604 if (version)
8605 ip_version_traffic_class_and_flow_label |= 0xF0000000;
8606
8607 if (traffic_class)
8608 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8609
8610 if (flow_label)
8611 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8612
8613 ip->ip_version_traffic_class_and_flow_label =
8614 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8615
8616 *maskp = mask;
8617 return 1;
8618}
8619
8620uword
8621unformat_l3_mask (unformat_input_t * input, va_list * args)
8622{
8623 u8 **maskp = va_arg (*args, u8 **);
8624
8625 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8626 {
8627 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8628 return 1;
8629 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8630 return 1;
8631 else
8632 break;
8633 }
8634 return 0;
8635}
8636
8637uword
8638unformat_l2_mask (unformat_input_t * input, va_list * args)
8639{
8640 u8 **maskp = va_arg (*args, u8 **);
8641 u8 *mask = 0;
8642 u8 src = 0;
8643 u8 dst = 0;
8644 u8 proto = 0;
8645 u8 tag1 = 0;
8646 u8 tag2 = 0;
8647 u8 ignore_tag1 = 0;
8648 u8 ignore_tag2 = 0;
8649 u8 cos1 = 0;
8650 u8 cos2 = 0;
8651 u8 dot1q = 0;
8652 u8 dot1ad = 0;
8653 int len = 14;
8654
8655 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8656 {
8657 if (unformat (input, "src"))
8658 src = 1;
8659 else if (unformat (input, "dst"))
8660 dst = 1;
8661 else if (unformat (input, "proto"))
8662 proto = 1;
8663 else if (unformat (input, "tag1"))
8664 tag1 = 1;
8665 else if (unformat (input, "tag2"))
8666 tag2 = 1;
8667 else if (unformat (input, "ignore-tag1"))
8668 ignore_tag1 = 1;
8669 else if (unformat (input, "ignore-tag2"))
8670 ignore_tag2 = 1;
8671 else if (unformat (input, "cos1"))
8672 cos1 = 1;
8673 else if (unformat (input, "cos2"))
8674 cos2 = 1;
8675 else if (unformat (input, "dot1q"))
8676 dot1q = 1;
8677 else if (unformat (input, "dot1ad"))
8678 dot1ad = 1;
8679 else
8680 break;
8681 }
8682 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8683 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8684 return 0;
8685
8686 if (tag1 || ignore_tag1 || cos1 || dot1q)
8687 len = 18;
8688 if (tag2 || ignore_tag2 || cos2 || dot1ad)
8689 len = 22;
8690
8691 vec_validate (mask, len - 1);
8692
8693 if (dst)
8694 memset (mask, 0xff, 6);
8695
8696 if (src)
8697 memset (mask + 6, 0xff, 6);
8698
8699 if (tag2 || dot1ad)
8700 {
8701 /* inner vlan tag */
8702 if (tag2)
8703 {
8704 mask[19] = 0xff;
8705 mask[18] = 0x0f;
8706 }
8707 if (cos2)
8708 mask[18] |= 0xe0;
8709 if (proto)
8710 mask[21] = mask[20] = 0xff;
8711 if (tag1)
8712 {
8713 mask[15] = 0xff;
8714 mask[14] = 0x0f;
8715 }
8716 if (cos1)
8717 mask[14] |= 0xe0;
8718 *maskp = mask;
8719 return 1;
8720 }
8721 if (tag1 | dot1q)
8722 {
8723 if (tag1)
8724 {
8725 mask[15] = 0xff;
8726 mask[14] = 0x0f;
8727 }
8728 if (cos1)
8729 mask[14] |= 0xe0;
8730 if (proto)
8731 mask[16] = mask[17] = 0xff;
8732
8733 *maskp = mask;
8734 return 1;
8735 }
8736 if (cos2)
8737 mask[18] |= 0xe0;
8738 if (cos1)
8739 mask[14] |= 0xe0;
8740 if (proto)
8741 mask[12] = mask[13] = 0xff;
8742
8743 *maskp = mask;
8744 return 1;
8745}
8746
8747uword
8748unformat_classify_mask (unformat_input_t * input, va_list * args)
8749{
8750 u8 **maskp = va_arg (*args, u8 **);
8751 u32 *skipp = va_arg (*args, u32 *);
8752 u32 *matchp = va_arg (*args, u32 *);
8753 u32 match;
8754 u8 *mask = 0;
8755 u8 *l2 = 0;
8756 u8 *l3 = 0;
8757 u8 *l4 = 0;
8758 int i;
8759
8760 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8761 {
8762 if (unformat (input, "hex %U", unformat_hex_string, &mask))
8763 ;
8764 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8765 ;
8766 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8767 ;
8768 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8769 ;
8770 else
8771 break;
8772 }
8773
8774 if (l4 && !l3)
8775 {
8776 vec_free (mask);
8777 vec_free (l2);
8778 vec_free (l4);
8779 return 0;
8780 }
8781
8782 if (mask || l2 || l3 || l4)
8783 {
8784 if (l2 || l3 || l4)
8785 {
8786 /* "With a free Ethernet header in every package" */
8787 if (l2 == 0)
8788 vec_validate (l2, 13);
8789 mask = l2;
8790 if (vec_len (l3))
8791 {
8792 vec_append (mask, l3);
8793 vec_free (l3);
8794 }
8795 if (vec_len (l4))
8796 {
8797 vec_append (mask, l4);
8798 vec_free (l4);
8799 }
8800 }
8801
8802 /* Scan forward looking for the first significant mask octet */
8803 for (i = 0; i < vec_len (mask); i++)
8804 if (mask[i])
8805 break;
8806
8807 /* compute (skip, match) params */
8808 *skipp = i / sizeof (u32x4);
8809 vec_delete (mask, *skipp * sizeof (u32x4), 0);
8810
8811 /* Pad mask to an even multiple of the vector size */
8812 while (vec_len (mask) % sizeof (u32x4))
8813 vec_add1 (mask, 0);
8814
8815 match = vec_len (mask) / sizeof (u32x4);
8816
8817 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8818 {
8819 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8820 if (*tmp || *(tmp + 1))
8821 break;
8822 match--;
8823 }
8824 if (match == 0)
8825 clib_warning ("BUG: match 0");
8826
8827 _vec_len (mask) = match * sizeof (u32x4);
8828
8829 *matchp = match;
8830 *maskp = mask;
8831
8832 return 1;
8833 }
8834
8835 return 0;
8836}
8837
8838#define foreach_l2_next \
8839_(drop, DROP) \
8840_(ethernet, ETHERNET_INPUT) \
8841_(ip4, IP4_INPUT) \
8842_(ip6, IP6_INPUT)
8843
8844uword
8845unformat_l2_next_index (unformat_input_t * input, va_list * args)
8846{
8847 u32 *miss_next_indexp = va_arg (*args, u32 *);
8848 u32 next_index = 0;
8849 u32 tmp;
8850
8851#define _(n,N) \
8852 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8853 foreach_l2_next;
8854#undef _
8855
8856 if (unformat (input, "%d", &tmp))
8857 {
8858 next_index = tmp;
8859 goto out;
8860 }
8861
8862 return 0;
8863
8864out:
8865 *miss_next_indexp = next_index;
8866 return 1;
8867}
8868
8869#define foreach_ip_next \
8870_(drop, DROP) \
8871_(local, LOCAL) \
8872_(rewrite, REWRITE)
8873
8874uword
8875unformat_ip_next_index (unformat_input_t * input, va_list * args)
8876{
8877 u32 *miss_next_indexp = va_arg (*args, u32 *);
8878 u32 next_index = 0;
8879 u32 tmp;
8880
8881#define _(n,N) \
8882 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8883 foreach_ip_next;
8884#undef _
8885
8886 if (unformat (input, "%d", &tmp))
8887 {
8888 next_index = tmp;
8889 goto out;
8890 }
8891
8892 return 0;
8893
8894out:
8895 *miss_next_indexp = next_index;
8896 return 1;
8897}
8898
8899#define foreach_acl_next \
8900_(deny, DENY)
8901
8902uword
8903unformat_acl_next_index (unformat_input_t * input, va_list * args)
8904{
8905 u32 *miss_next_indexp = va_arg (*args, u32 *);
8906 u32 next_index = 0;
8907 u32 tmp;
8908
8909#define _(n,N) \
8910 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8911 foreach_acl_next;
8912#undef _
8913
8914 if (unformat (input, "permit"))
8915 {
8916 next_index = ~0;
8917 goto out;
8918 }
8919 else if (unformat (input, "%d", &tmp))
8920 {
8921 next_index = tmp;
8922 goto out;
8923 }
8924
8925 return 0;
8926
8927out:
8928 *miss_next_indexp = next_index;
8929 return 1;
8930}
8931
8932uword
8933unformat_policer_precolor (unformat_input_t * input, va_list * args)
8934{
8935 u32 *r = va_arg (*args, u32 *);
8936
8937 if (unformat (input, "conform-color"))
8938 *r = POLICE_CONFORM;
8939 else if (unformat (input, "exceed-color"))
8940 *r = POLICE_EXCEED;
8941 else
8942 return 0;
8943
8944 return 1;
8945}
8946
8947static int
8948api_classify_add_del_table (vat_main_t * vam)
8949{
8950 unformat_input_t *i = vam->input;
8951 vl_api_classify_add_del_table_t *mp;
8952
8953 u32 nbuckets = 2;
8954 u32 skip = ~0;
8955 u32 match = ~0;
8956 int is_add = 1;
8957 int del_chain = 0;
8958 u32 table_index = ~0;
8959 u32 next_table_index = ~0;
8960 u32 miss_next_index = ~0;
8961 u32 memory_size = 32 << 20;
8962 u8 *mask = 0;
8963 f64 timeout;
8964 u32 current_data_flag = 0;
8965 int current_data_offset = 0;
8966
8967 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8968 {
8969 if (unformat (i, "del"))
8970 is_add = 0;
8971 else if (unformat (i, "del-chain"))
8972 {
8973 is_add = 0;
8974 del_chain = 1;
8975 }
8976 else if (unformat (i, "buckets %d", &nbuckets))
8977 ;
8978 else if (unformat (i, "memory_size %d", &memory_size))
8979 ;
8980 else if (unformat (i, "skip %d", &skip))
8981 ;
8982 else if (unformat (i, "match %d", &match))
8983 ;
8984 else if (unformat (i, "table %d", &table_index))
8985 ;
8986 else if (unformat (i, "mask %U", unformat_classify_mask,
8987 &mask, &skip, &match))
8988 ;
8989 else if (unformat (i, "next-table %d", &next_table_index))
8990 ;
8991 else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8992 &miss_next_index))
8993 ;
8994 else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8995 &miss_next_index))
8996 ;
8997 else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8998 &miss_next_index))
8999 ;
9000 else if (unformat (i, "current-data-flag %d", &current_data_flag))
9001 ;
9002 else if (unformat (i, "current-data-offset %d", &current_data_offset))
9003 ;
9004 else
9005 break;
9006 }
9007
9008 if (is_add && mask == 0)
9009 {
9010 errmsg ("Mask required");
9011 return -99;
9012 }
9013
9014 if (is_add && skip == ~0)
9015 {
9016 errmsg ("skip count required");
9017 return -99;
9018 }
9019
9020 if (is_add && match == ~0)
9021 {
9022 errmsg ("match count required");
9023 return -99;
9024 }
9025
9026 if (!is_add && table_index == ~0)
9027 {
9028 errmsg ("table index required for delete");
9029 return -99;
9030 }
9031
9032 M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
9033
9034 mp->is_add = is_add;
9035 mp->del_chain = del_chain;
9036 mp->table_index = ntohl (table_index);
9037 mp->nbuckets = ntohl (nbuckets);
9038 mp->memory_size = ntohl (memory_size);
9039 mp->skip_n_vectors = ntohl (skip);
9040 mp->match_n_vectors = ntohl (match);
9041 mp->next_table_index = ntohl (next_table_index);
9042 mp->miss_next_index = ntohl (miss_next_index);
9043 mp->current_data_flag = ntohl (current_data_flag);
9044 mp->current_data_offset = ntohl (current_data_offset);
9045 clib_memcpy (mp->mask, mask, vec_len (mask));
9046
9047 vec_free (mask);
9048
9049 S;
9050 W;
9051 /* NOTREACHED */
9052}
9053
9054uword
9055unformat_l4_match (unformat_input_t * input, va_list * args)
9056{
9057 u8 **matchp = va_arg (*args, u8 **);
9058
9059 u8 *proto_header = 0;
9060 int src_port = 0;
9061 int dst_port = 0;
9062
9063 tcpudp_header_t h;
9064
9065 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9066 {
9067 if (unformat (input, "src_port %d", &src_port))
9068 ;
9069 else if (unformat (input, "dst_port %d", &dst_port))
9070 ;
9071 else
9072 return 0;
9073 }
9074
9075 h.src_port = clib_host_to_net_u16 (src_port);
9076 h.dst_port = clib_host_to_net_u16 (dst_port);
9077 vec_validate (proto_header, sizeof (h) - 1);
9078 memcpy (proto_header, &h, sizeof (h));
9079
9080 *matchp = proto_header;
9081
9082 return 1;
9083}
9084
9085uword
9086unformat_ip4_match (unformat_input_t * input, va_list * args)
9087{
9088 u8 **matchp = va_arg (*args, u8 **);
9089 u8 *match = 0;
9090 ip4_header_t *ip;
9091 int version = 0;
9092 u32 version_val;
9093 int hdr_length = 0;
9094 u32 hdr_length_val;
9095 int src = 0, dst = 0;
9096 ip4_address_t src_val, dst_val;
9097 int proto = 0;
9098 u32 proto_val;
9099 int tos = 0;
9100 u32 tos_val;
9101 int length = 0;
9102 u32 length_val;
9103 int fragment_id = 0;
9104 u32 fragment_id_val;
9105 int ttl = 0;
9106 int ttl_val;
9107 int checksum = 0;
9108 u32 checksum_val;
9109
9110 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9111 {
9112 if (unformat (input, "version %d", &version_val))
9113 version = 1;
9114 else if (unformat (input, "hdr_length %d", &hdr_length_val))
9115 hdr_length = 1;
9116 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9117 src = 1;
9118 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9119 dst = 1;
9120 else if (unformat (input, "proto %d", &proto_val))
9121 proto = 1;
9122 else if (unformat (input, "tos %d", &tos_val))
9123 tos = 1;
9124 else if (unformat (input, "length %d", &length_val))
9125 length = 1;
9126 else if (unformat (input, "fragment_id %d", &fragment_id_val))
9127 fragment_id = 1;
9128 else if (unformat (input, "ttl %d", &ttl_val))
9129 ttl = 1;
9130 else if (unformat (input, "checksum %d", &checksum_val))
9131 checksum = 1;
9132 else
9133 break;
9134 }
9135
9136 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9137 + ttl + checksum == 0)
9138 return 0;
9139
9140 /*
9141 * Aligned because we use the real comparison functions
9142 */
9143 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9144
9145 ip = (ip4_header_t *) match;
9146
9147 /* These are realistically matched in practice */
9148 if (src)
9149 ip->src_address.as_u32 = src_val.as_u32;
9150
9151 if (dst)
9152 ip->dst_address.as_u32 = dst_val.as_u32;
9153
9154 if (proto)
9155 ip->protocol = proto_val;
9156
9157
9158 /* These are not, but they're included for completeness */
9159 if (version)
9160 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9161
9162 if (hdr_length)
9163 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9164
9165 if (tos)
9166 ip->tos = tos_val;
9167
9168 if (length)
9169 ip->length = clib_host_to_net_u16 (length_val);
9170
9171 if (ttl)
9172 ip->ttl = ttl_val;
9173
9174 if (checksum)
9175 ip->checksum = clib_host_to_net_u16 (checksum_val);
9176
9177 *matchp = match;
9178 return 1;
9179}
9180
9181uword
9182unformat_ip6_match (unformat_input_t * input, va_list * args)
9183{
9184 u8 **matchp = va_arg (*args, u8 **);
9185 u8 *match = 0;
9186 ip6_header_t *ip;
9187 int version = 0;
9188 u32 version_val;
9189 u8 traffic_class = 0;
9190 u32 traffic_class_val = 0;
9191 u8 flow_label = 0;
9192 u8 flow_label_val;
9193 int src = 0, dst = 0;
9194 ip6_address_t src_val, dst_val;
9195 int proto = 0;
9196 u32 proto_val;
9197 int payload_length = 0;
9198 u32 payload_length_val;
9199 int hop_limit = 0;
9200 int hop_limit_val;
9201 u32 ip_version_traffic_class_and_flow_label;
9202
9203 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9204 {
9205 if (unformat (input, "version %d", &version_val))
9206 version = 1;
9207 else if (unformat (input, "traffic_class %d", &traffic_class_val))
9208 traffic_class = 1;
9209 else if (unformat (input, "flow_label %d", &flow_label_val))
9210 flow_label = 1;
9211 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9212 src = 1;
9213 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9214 dst = 1;
9215 else if (unformat (input, "proto %d", &proto_val))
9216 proto = 1;
9217 else if (unformat (input, "payload_length %d", &payload_length_val))
9218 payload_length = 1;
9219 else if (unformat (input, "hop_limit %d", &hop_limit_val))
9220 hop_limit = 1;
9221 else
9222 break;
9223 }
9224
9225 if (version + traffic_class + flow_label + src + dst + proto +
9226 payload_length + hop_limit == 0)
9227 return 0;
9228
9229 /*
9230 * Aligned because we use the real comparison functions
9231 */
9232 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9233
9234 ip = (ip6_header_t *) match;
9235
9236 if (src)
9237 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9238
9239 if (dst)
9240 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9241
9242 if (proto)
9243 ip->protocol = proto_val;
9244
9245 ip_version_traffic_class_and_flow_label = 0;
9246
9247 if (version)
9248 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9249
9250 if (traffic_class)
9251 ip_version_traffic_class_and_flow_label |=
9252 (traffic_class_val & 0xFF) << 20;
9253
9254 if (flow_label)
9255 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9256
9257 ip->ip_version_traffic_class_and_flow_label =
9258 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9259
9260 if (payload_length)
9261 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9262
9263 if (hop_limit)
9264 ip->hop_limit = hop_limit_val;
9265
9266 *matchp = match;
9267 return 1;
9268}
9269
9270uword
9271unformat_l3_match (unformat_input_t * input, va_list * args)
9272{
9273 u8 **matchp = va_arg (*args, u8 **);
9274
9275 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9276 {
9277 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9278 return 1;
9279 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9280 return 1;
9281 else
9282 break;
9283 }
9284 return 0;
9285}
9286
9287uword
9288unformat_vlan_tag (unformat_input_t * input, va_list * args)
9289{
9290 u8 *tagp = va_arg (*args, u8 *);
9291 u32 tag;
9292
9293 if (unformat (input, "%d", &tag))
9294 {
9295 tagp[0] = (tag >> 8) & 0x0F;
9296 tagp[1] = tag & 0xFF;
9297 return 1;
9298 }
9299
9300 return 0;
9301}
9302
9303uword
9304unformat_l2_match (unformat_input_t * input, va_list * args)
9305{
9306 u8 **matchp = va_arg (*args, u8 **);
9307 u8 *match = 0;
9308 u8 src = 0;
9309 u8 src_val[6];
9310 u8 dst = 0;
9311 u8 dst_val[6];
9312 u8 proto = 0;
9313 u16 proto_val;
9314 u8 tag1 = 0;
9315 u8 tag1_val[2];
9316 u8 tag2 = 0;
9317 u8 tag2_val[2];
9318 int len = 14;
9319 u8 ignore_tag1 = 0;
9320 u8 ignore_tag2 = 0;
9321 u8 cos1 = 0;
9322 u8 cos2 = 0;
9323 u32 cos1_val = 0;
9324 u32 cos2_val = 0;
9325
9326 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9327 {
9328 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9329 src = 1;
9330 else
9331 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9332 dst = 1;
9333 else if (unformat (input, "proto %U",
9334 unformat_ethernet_type_host_byte_order, &proto_val))
9335 proto = 1;
9336 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9337 tag1 = 1;
9338 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9339 tag2 = 1;
9340 else if (unformat (input, "ignore-tag1"))
9341 ignore_tag1 = 1;
9342 else if (unformat (input, "ignore-tag2"))
9343 ignore_tag2 = 1;
9344 else if (unformat (input, "cos1 %d", &cos1_val))
9345 cos1 = 1;
9346 else if (unformat (input, "cos2 %d", &cos2_val))
9347 cos2 = 1;
9348 else
9349 break;
9350 }
9351 if ((src + dst + proto + tag1 + tag2 +
9352 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9353 return 0;
9354
9355 if (tag1 || ignore_tag1 || cos1)
9356 len = 18;
9357 if (tag2 || ignore_tag2 || cos2)
9358 len = 22;
9359
9360 vec_validate_aligned (match, len - 1, sizeof (u32x4));
9361
9362 if (dst)
9363 clib_memcpy (match, dst_val, 6);
9364
9365 if (src)
9366 clib_memcpy (match + 6, src_val, 6);
9367
9368 if (tag2)
9369 {
9370 /* inner vlan tag */
9371 match[19] = tag2_val[1];
9372 match[18] = tag2_val[0];
9373 if (cos2)
9374 match[18] |= (cos2_val & 0x7) << 5;
9375 if (proto)
9376 {
9377 match[21] = proto_val & 0xff;
9378 match[20] = proto_val >> 8;
9379 }
9380 if (tag1)
9381 {
9382 match[15] = tag1_val[1];
9383 match[14] = tag1_val[0];
9384 }
9385 if (cos1)
9386 match[14] |= (cos1_val & 0x7) << 5;
9387 *matchp = match;
9388 return 1;
9389 }
9390 if (tag1)
9391 {
9392 match[15] = tag1_val[1];
9393 match[14] = tag1_val[0];
9394 if (proto)
9395 {
9396 match[17] = proto_val & 0xff;
9397 match[16] = proto_val >> 8;
9398 }
9399 if (cos1)
9400 match[14] |= (cos1_val & 0x7) << 5;
9401
9402 *matchp = match;
9403 return 1;
9404 }
9405 if (cos2)
9406 match[18] |= (cos2_val & 0x7) << 5;
9407 if (cos1)
9408 match[14] |= (cos1_val & 0x7) << 5;
9409 if (proto)
9410 {
9411 match[13] = proto_val & 0xff;
9412 match[12] = proto_val >> 8;
9413 }
9414
9415 *matchp = match;
9416 return 1;
9417}
9418
9419
9420uword
9421unformat_classify_match (unformat_input_t * input, va_list * args)
9422{
9423 u8 **matchp = va_arg (*args, u8 **);
9424 u32 skip_n_vectors = va_arg (*args, u32);
9425 u32 match_n_vectors = va_arg (*args, u32);
9426
9427 u8 *match = 0;
9428 u8 *l2 = 0;
9429 u8 *l3 = 0;
9430 u8 *l4 = 0;
9431
9432 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9433 {
9434 if (unformat (input, "hex %U", unformat_hex_string, &match))
9435 ;
9436 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9437 ;
9438 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9439 ;
9440 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9441 ;
9442 else
9443 break;
9444 }
9445
9446 if (l4 && !l3)
9447 {
9448 vec_free (match);
9449 vec_free (l2);
9450 vec_free (l4);
9451 return 0;
9452 }
9453
9454 if (match || l2 || l3 || l4)
9455 {
9456 if (l2 || l3 || l4)
9457 {
9458 /* "Win a free Ethernet header in every packet" */
9459 if (l2 == 0)
9460 vec_validate_aligned (l2, 13, sizeof (u32x4));
9461 match = l2;
9462 if (vec_len (l3))
9463 {
9464 vec_append_aligned (match, l3, sizeof (u32x4));
9465 vec_free (l3);
9466 }
9467 if (vec_len (l4))
9468 {
9469 vec_append_aligned (match, l4, sizeof (u32x4));
9470 vec_free (l4);
9471 }
9472 }
9473
9474 /* Make sure the vector is big enough even if key is all 0's */
9475 vec_validate_aligned
9476 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9477 sizeof (u32x4));
9478
9479 /* Set size, include skipped vectors */
9480 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9481
9482 *matchp = match;
9483
9484 return 1;
9485 }
9486
9487 return 0;
9488}
9489
9490static int
9491api_classify_add_del_session (vat_main_t * vam)
9492{
9493 unformat_input_t *i = vam->input;
9494 vl_api_classify_add_del_session_t *mp;
9495 int is_add = 1;
9496 u32 table_index = ~0;
9497 u32 hit_next_index = ~0;
9498 u32 opaque_index = ~0;
9499 u8 *match = 0;
9500 i32 advance = 0;
9501 f64 timeout;
9502 u32 skip_n_vectors = 0;
9503 u32 match_n_vectors = 0;
9504 u32 action = 0;
9505 u32 metadata = 0;
9506
9507 /*
9508 * Warning: you have to supply skip_n and match_n
9509 * because the API client cant simply look at the classify
9510 * table object.
9511 */
9512
9513 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9514 {
9515 if (unformat (i, "del"))
9516 is_add = 0;
9517 else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9518 &hit_next_index))
9519 ;
9520 else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9521 &hit_next_index))
9522 ;
9523 else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9524 &hit_next_index))
9525 ;
9526 else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9527 ;
9528 else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9529 ;
9530 else if (unformat (i, "opaque-index %d", &opaque_index))
9531 ;
9532 else if (unformat (i, "skip_n %d", &skip_n_vectors))
9533 ;
9534 else if (unformat (i, "match_n %d", &match_n_vectors))
9535 ;
9536 else if (unformat (i, "match %U", unformat_classify_match,
9537 &match, skip_n_vectors, match_n_vectors))
9538 ;
9539 else if (unformat (i, "advance %d", &advance))
9540 ;
9541 else if (unformat (i, "table-index %d", &table_index))
9542 ;
9543 else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9544 action = 1;
9545 else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9546 action = 2;
9547 else if (unformat (i, "action %d", &action))
9548 ;
9549 else if (unformat (i, "metadata %d", &metadata))
9550 ;
9551 else
9552 break;
9553 }
9554
9555 if (table_index == ~0)
9556 {
9557 errmsg ("Table index required");
9558 return -99;
9559 }
9560
9561 if (is_add && match == 0)
9562 {
9563 errmsg ("Match value required");
9564 return -99;
9565 }
9566
9567 M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9568
9569 mp->is_add = is_add;
9570 mp->table_index = ntohl (table_index);
9571 mp->hit_next_index = ntohl (hit_next_index);
9572 mp->opaque_index = ntohl (opaque_index);
9573 mp->advance = ntohl (advance);
9574 mp->action = action;
9575 mp->metadata = ntohl (metadata);
9576 clib_memcpy (mp->match, match, vec_len (match));
9577 vec_free (match);
9578
9579 S;
9580 W;
9581 /* NOTREACHED */
9582}
9583
9584static int
9585api_classify_set_interface_ip_table (vat_main_t * vam)
9586{
9587 unformat_input_t *i = vam->input;
9588 vl_api_classify_set_interface_ip_table_t *mp;
9589 f64 timeout;
9590 u32 sw_if_index;
9591 int sw_if_index_set;
9592 u32 table_index = ~0;
9593 u8 is_ipv6 = 0;
9594
9595 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9596 {
9597 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9598 sw_if_index_set = 1;
9599 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9600 sw_if_index_set = 1;
9601 else if (unformat (i, "table %d", &table_index))
9602 ;
9603 else
9604 {
9605 clib_warning ("parse error '%U'", format_unformat_error, i);
9606 return -99;
9607 }
9608 }
9609
9610 if (sw_if_index_set == 0)
9611 {
9612 errmsg ("missing interface name or sw_if_index");
9613 return -99;
9614 }
9615
9616
9617 M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9618
9619 mp->sw_if_index = ntohl (sw_if_index);
9620 mp->table_index = ntohl (table_index);
9621 mp->is_ipv6 = is_ipv6;
9622
9623 S;
9624 W;
9625 /* NOTREACHED */
9626 return 0;
9627}
9628
9629static int
9630api_classify_set_interface_l2_tables (vat_main_t * vam)
9631{
9632 unformat_input_t *i = vam->input;
9633 vl_api_classify_set_interface_l2_tables_t *mp;
9634 f64 timeout;
9635 u32 sw_if_index;
9636 int sw_if_index_set;
9637 u32 ip4_table_index = ~0;
9638 u32 ip6_table_index = ~0;
9639 u32 other_table_index = ~0;
9640 u32 is_input = 1;
9641
9642 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9643 {
9644 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9645 sw_if_index_set = 1;
9646 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9647 sw_if_index_set = 1;
9648 else if (unformat (i, "ip4-table %d", &ip4_table_index))
9649 ;
9650 else if (unformat (i, "ip6-table %d", &ip6_table_index))
9651 ;
9652 else if (unformat (i, "other-table %d", &other_table_index))
9653 ;
9654 else if (unformat (i, "is-input %d", &is_input))
9655 ;
9656 else
9657 {
9658 clib_warning ("parse error '%U'", format_unformat_error, i);
9659 return -99;
9660 }
9661 }
9662
9663 if (sw_if_index_set == 0)
9664 {
9665 errmsg ("missing interface name or sw_if_index");
9666 return -99;
9667 }
9668
9669
9670 M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9671
9672 mp->sw_if_index = ntohl (sw_if_index);
9673 mp->ip4_table_index = ntohl (ip4_table_index);
9674 mp->ip6_table_index = ntohl (ip6_table_index);
9675 mp->other_table_index = ntohl (other_table_index);
9676 mp->is_input = (u8) is_input;
9677
9678 S;
9679 W;
9680 /* NOTREACHED */
9681 return 0;
9682}
9683
9684static int
9685api_set_ipfix_exporter (vat_main_t * vam)
9686{
9687 unformat_input_t *i = vam->input;
9688 vl_api_set_ipfix_exporter_t *mp;
9689 ip4_address_t collector_address;
9690 u8 collector_address_set = 0;
9691 u32 collector_port = ~0;
9692 ip4_address_t src_address;
9693 u8 src_address_set = 0;
9694 u32 vrf_id = ~0;
9695 u32 path_mtu = ~0;
9696 u32 template_interval = ~0;
9697 u8 udp_checksum = 0;
9698 f64 timeout;
9699
9700 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9701 {
9702 if (unformat (i, "collector_address %U", unformat_ip4_address,
9703 &collector_address))
9704 collector_address_set = 1;
9705 else if (unformat (i, "collector_port %d", &collector_port))
9706 ;
9707 else if (unformat (i, "src_address %U", unformat_ip4_address,
9708 &src_address))
9709 src_address_set = 1;
9710 else if (unformat (i, "vrf_id %d", &vrf_id))
9711 ;
9712 else if (unformat (i, "path_mtu %d", &path_mtu))
9713 ;
9714 else if (unformat (i, "template_interval %d", &template_interval))
9715 ;
9716 else if (unformat (i, "udp_checksum"))
9717 udp_checksum = 1;
9718 else
9719 break;
9720 }
9721
9722 if (collector_address_set == 0)
9723 {
9724 errmsg ("collector_address required");
9725 return -99;
9726 }
9727
9728 if (src_address_set == 0)
9729 {
9730 errmsg ("src_address required");
9731 return -99;
9732 }
9733
9734 M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9735
9736 memcpy (mp->collector_address, collector_address.data,
9737 sizeof (collector_address.data));
9738 mp->collector_port = htons ((u16) collector_port);
9739 memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9740 mp->vrf_id = htonl (vrf_id);
9741 mp->path_mtu = htonl (path_mtu);
9742 mp->template_interval = htonl (template_interval);
9743 mp->udp_checksum = udp_checksum;
9744
9745 S;
9746 W;
9747 /* NOTREACHED */
9748}
9749
9750static int
9751api_set_ipfix_classify_stream (vat_main_t * vam)
9752{
9753 unformat_input_t *i = vam->input;
9754 vl_api_set_ipfix_classify_stream_t *mp;
9755 u32 domain_id = 0;
9756 u32 src_port = UDP_DST_PORT_ipfix;
9757 f64 timeout;
9758
9759 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9760 {
9761 if (unformat (i, "domain %d", &domain_id))
9762 ;
9763 else if (unformat (i, "src_port %d", &src_port))
9764 ;
9765 else
9766 {
9767 errmsg ("unknown input `%U'", format_unformat_error, i);
9768 return -99;
9769 }
9770 }
9771
9772 M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9773
9774 mp->domain_id = htonl (domain_id);
9775 mp->src_port = htons ((u16) src_port);
9776
9777 S;
9778 W;
9779 /* NOTREACHED */
9780}
9781
9782static int
9783api_ipfix_classify_table_add_del (vat_main_t * vam)
9784{
9785 unformat_input_t *i = vam->input;
9786 vl_api_ipfix_classify_table_add_del_t *mp;
9787 int is_add = -1;
9788 u32 classify_table_index = ~0;
9789 u8 ip_version = 0;
9790 u8 transport_protocol = 255;
9791 f64 timeout;
9792
9793 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9794 {
9795 if (unformat (i, "add"))
9796 is_add = 1;
9797 else if (unformat (i, "del"))
9798 is_add = 0;
9799 else if (unformat (i, "table %d", &classify_table_index))
9800 ;
9801 else if (unformat (i, "ip4"))
9802 ip_version = 4;
9803 else if (unformat (i, "ip6"))
9804 ip_version = 6;
9805 else if (unformat (i, "tcp"))
9806 transport_protocol = 6;
9807 else if (unformat (i, "udp"))
9808 transport_protocol = 17;
9809 else
9810 {
9811 errmsg ("unknown input `%U'", format_unformat_error, i);
9812 return -99;
9813 }
9814 }
9815
9816 if (is_add == -1)
9817 {
9818 errmsg ("expecting: add|del");
9819 return -99;
9820 }
9821 if (classify_table_index == ~0)
9822 {
9823 errmsg ("classifier table not specified");
9824 return -99;
9825 }
9826 if (ip_version == 0)
9827 {
9828 errmsg ("IP version not specified");
9829 return -99;
9830 }
9831
9832 M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9833
9834 mp->is_add = is_add;
9835 mp->table_id = htonl (classify_table_index);
9836 mp->ip_version = ip_version;
9837 mp->transport_protocol = transport_protocol;
9838
9839 S;
9840 W;
9841 /* NOTREACHED */
9842}
9843
9844static int
9845api_get_node_index (vat_main_t * vam)
9846{
9847 unformat_input_t *i = vam->input;
9848 vl_api_get_node_index_t *mp;
9849 f64 timeout;
9850 u8 *name = 0;
9851
9852 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9853 {
9854 if (unformat (i, "node %s", &name))
9855 ;
9856 else
9857 break;
9858 }
9859 if (name == 0)
9860 {
9861 errmsg ("node name required");
9862 return -99;
9863 }
9864 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9865 {
9866 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9867 return -99;
9868 }
9869
9870 M (GET_NODE_INDEX, get_node_index);
9871 clib_memcpy (mp->node_name, name, vec_len (name));
9872 vec_free (name);
9873
9874 S;
9875 W;
9876 /* NOTREACHED */
9877 return 0;
9878}
9879
9880static int
9881api_get_next_index (vat_main_t * vam)
9882{
9883 unformat_input_t *i = vam->input;
9884 vl_api_get_next_index_t *mp;
9885 f64 timeout;
9886 u8 *node_name = 0, *next_node_name = 0;
9887
9888 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9889 {
9890 if (unformat (i, "node-name %s", &node_name))
9891 ;
9892 else if (unformat (i, "next-node-name %s", &next_node_name))
9893 break;
9894 }
9895
9896 if (node_name == 0)
9897 {
9898 errmsg ("node name required");
9899 return -99;
9900 }
9901 if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9902 {
9903 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9904 return -99;
9905 }
9906
9907 if (next_node_name == 0)
9908 {
9909 errmsg ("next node name required");
9910 return -99;
9911 }
9912 if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9913 {
9914 errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9915 return -99;
9916 }
9917
9918 M (GET_NEXT_INDEX, get_next_index);
9919 clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9920 clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9921 vec_free (node_name);
9922 vec_free (next_node_name);
9923
9924 S;
9925 W;
9926 /* NOTREACHED */
9927 return 0;
9928}
9929
9930static int
9931api_add_node_next (vat_main_t * vam)
9932{
9933 unformat_input_t *i = vam->input;
9934 vl_api_add_node_next_t *mp;
9935 f64 timeout;
9936 u8 *name = 0;
9937 u8 *next = 0;
9938
9939 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9940 {
9941 if (unformat (i, "node %s", &name))
9942 ;
9943 else if (unformat (i, "next %s", &next))
9944 ;
9945 else
9946 break;
9947 }
9948 if (name == 0)
9949 {
9950 errmsg ("node name required");
9951 return -99;
9952 }
9953 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9954 {
9955 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9956 return -99;
9957 }
9958 if (next == 0)
9959 {
9960 errmsg ("next node required");
9961 return -99;
9962 }
9963 if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9964 {
9965 errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9966 return -99;
9967 }
9968
9969 M (ADD_NODE_NEXT, add_node_next);
9970 clib_memcpy (mp->node_name, name, vec_len (name));
9971 clib_memcpy (mp->next_name, next, vec_len (next));
9972 vec_free (name);
9973 vec_free (next);
9974
9975 S;
9976 W;
9977 /* NOTREACHED */
9978 return 0;
9979}
9980
9981static int
9982api_l2tpv3_create_tunnel (vat_main_t * vam)
9983{
9984 unformat_input_t *i = vam->input;
9985 ip6_address_t client_address, our_address;
9986 int client_address_set = 0;
9987 int our_address_set = 0;
9988 u32 local_session_id = 0;
9989 u32 remote_session_id = 0;
9990 u64 local_cookie = 0;
9991 u64 remote_cookie = 0;
9992 u8 l2_sublayer_present = 0;
9993 vl_api_l2tpv3_create_tunnel_t *mp;
9994 f64 timeout;
9995
9996 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9997 {
9998 if (unformat (i, "client_address %U", unformat_ip6_address,
9999 &client_address))
10000 client_address_set = 1;
10001 else if (unformat (i, "our_address %U", unformat_ip6_address,
10002 &our_address))
10003 our_address_set = 1;
10004 else if (unformat (i, "local_session_id %d", &local_session_id))
10005 ;
10006 else if (unformat (i, "remote_session_id %d", &remote_session_id))
10007 ;
10008 else if (unformat (i, "local_cookie %lld", &local_cookie))
10009 ;
10010 else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10011 ;
10012 else if (unformat (i, "l2-sublayer-present"))
10013 l2_sublayer_present = 1;
10014 else
10015 break;
10016 }
10017
10018 if (client_address_set == 0)
10019 {
10020 errmsg ("client_address required");
10021 return -99;
10022 }
10023
10024 if (our_address_set == 0)
10025 {
10026 errmsg ("our_address required");
10027 return -99;
10028 }
10029
10030 M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
10031
10032 clib_memcpy (mp->client_address, client_address.as_u8,
10033 sizeof (mp->client_address));
10034
10035 clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10036
10037 mp->local_session_id = ntohl (local_session_id);
10038 mp->remote_session_id = ntohl (remote_session_id);
10039 mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10040 mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10041 mp->l2_sublayer_present = l2_sublayer_present;
10042 mp->is_ipv6 = 1;
10043
10044 S;
10045 W;
10046 /* NOTREACHED */
10047 return 0;
10048}
10049
10050static int
10051api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10052{
10053 unformat_input_t *i = vam->input;
10054 u32 sw_if_index;
10055 u8 sw_if_index_set = 0;
10056 u64 new_local_cookie = 0;
10057 u64 new_remote_cookie = 0;
10058 vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10059 f64 timeout;
10060
10061 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10062 {
10063 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10064 sw_if_index_set = 1;
10065 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10066 sw_if_index_set = 1;
10067 else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10068 ;
10069 else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10070 ;
10071 else
10072 break;
10073 }
10074
10075 if (sw_if_index_set == 0)
10076 {
10077 errmsg ("missing interface name or sw_if_index");
10078 return -99;
10079 }
10080
10081 M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
10082
10083 mp->sw_if_index = ntohl (sw_if_index);
10084 mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10085 mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10086
10087 S;
10088 W;
10089 /* NOTREACHED */
10090 return 0;
10091}
10092
10093static int
10094api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10095{
10096 unformat_input_t *i = vam->input;
10097 vl_api_l2tpv3_interface_enable_disable_t *mp;
10098 f64 timeout;
10099 u32 sw_if_index;
10100 u8 sw_if_index_set = 0;
10101 u8 enable_disable = 1;
10102
10103 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10104 {
10105 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10106 sw_if_index_set = 1;
10107 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10108 sw_if_index_set = 1;
10109 else if (unformat (i, "enable"))
10110 enable_disable = 1;
10111 else if (unformat (i, "disable"))
10112 enable_disable = 0;
10113 else
10114 break;
10115 }
10116
10117 if (sw_if_index_set == 0)
10118 {
10119 errmsg ("missing interface name or sw_if_index");
10120 return -99;
10121 }
10122
10123 M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
10124
10125 mp->sw_if_index = ntohl (sw_if_index);
10126 mp->enable_disable = enable_disable;
10127
10128 S;
10129 W;
10130 /* NOTREACHED */
10131 return 0;
10132}
10133
10134static int
10135api_l2tpv3_set_lookup_key (vat_main_t * vam)
10136{
10137 unformat_input_t *i = vam->input;
10138 vl_api_l2tpv3_set_lookup_key_t *mp;
10139 f64 timeout;
10140 u8 key = ~0;
10141
10142 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10143 {
10144 if (unformat (i, "lookup_v6_src"))
10145 key = L2T_LOOKUP_SRC_ADDRESS;
10146 else if (unformat (i, "lookup_v6_dst"))
10147 key = L2T_LOOKUP_DST_ADDRESS;
10148 else if (unformat (i, "lookup_session_id"))
10149 key = L2T_LOOKUP_SESSION_ID;
10150 else
10151 break;
10152 }
10153
10154 if (key == (u8) ~ 0)
10155 {
10156 errmsg ("l2tp session lookup key unset");
10157 return -99;
10158 }
10159
10160 M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
10161
10162 mp->key = key;
10163
10164 S;
10165 W;
10166 /* NOTREACHED */
10167 return 0;
10168}
10169
10170static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10171 (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10172{
10173 vat_main_t *vam = &vat_main;
10174
10175 print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10176 format_ip6_address, mp->our_address,
10177 format_ip6_address, mp->client_address,
10178 clib_net_to_host_u32 (mp->sw_if_index));
10179
10180 print (vam->ofp,
10181 " local cookies %016llx %016llx remote cookie %016llx",
10182 clib_net_to_host_u64 (mp->local_cookie[0]),
10183 clib_net_to_host_u64 (mp->local_cookie[1]),
10184 clib_net_to_host_u64 (mp->remote_cookie));
10185
10186 print (vam->ofp, " local session-id %d remote session-id %d",
10187 clib_net_to_host_u32 (mp->local_session_id),
10188 clib_net_to_host_u32 (mp->remote_session_id));
10189
10190 print (vam->ofp, " l2 specific sublayer %s\n",
10191 mp->l2_sublayer_present ? "preset" : "absent");
10192
10193}
10194
10195static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10196 (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10197{
10198 vat_main_t *vam = &vat_main;
10199 vat_json_node_t *node = NULL;
10200 struct in6_addr addr;
10201
10202 if (VAT_JSON_ARRAY != vam->json_tree.type)
10203 {
10204 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10205 vat_json_init_array (&vam->json_tree);
10206 }
10207 node = vat_json_array_add (&vam->json_tree);
10208
10209 vat_json_init_object (node);
10210
10211 clib_memcpy (&addr, mp->our_address, sizeof (addr));
10212 vat_json_object_add_ip6 (node, "our_address", addr);
10213 clib_memcpy (&addr, mp->client_address, sizeof (addr));
10214 vat_json_object_add_ip6 (node, "client_address", addr);
10215
10216 vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10217 vat_json_init_array (lc);
10218 vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10219 vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10220 vat_json_object_add_uint (node, "remote_cookie",
10221 clib_net_to_host_u64 (mp->remote_cookie));
10222
10223 printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10224 vat_json_object_add_uint (node, "local_session_id",
10225 clib_net_to_host_u32 (mp->local_session_id));
10226 vat_json_object_add_uint (node, "remote_session_id",
10227 clib_net_to_host_u32 (mp->remote_session_id));
10228 vat_json_object_add_string_copy (node, "l2_sublayer",
10229 mp->l2_sublayer_present ? (u8 *) "present"
10230 : (u8 *) "absent");
10231}
10232
10233static int
10234api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10235{
10236 vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10237 f64 timeout;
10238
10239 /* Get list of l2tpv3-tunnel interfaces */
10240 M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10241 S;
10242
10243 /* Use a control ping for synchronization */
10244 {
10245 vl_api_control_ping_t *mp;
10246 M (CONTROL_PING, control_ping);
10247 S;
10248 }
10249 W;
10250}
10251
10252
10253static void vl_api_sw_interface_tap_details_t_handler
10254 (vl_api_sw_interface_tap_details_t * mp)
10255{
10256 vat_main_t *vam = &vat_main;
10257
10258 print (vam->ofp, "%-16s %d",
10259 mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10260}
10261
10262static void vl_api_sw_interface_tap_details_t_handler_json
10263 (vl_api_sw_interface_tap_details_t * mp)
10264{
10265 vat_main_t *vam = &vat_main;
10266 vat_json_node_t *node = NULL;
10267
10268 if (VAT_JSON_ARRAY != vam->json_tree.type)
10269 {
10270 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10271 vat_json_init_array (&vam->json_tree);
10272 }
10273 node = vat_json_array_add (&vam->json_tree);
10274
10275 vat_json_init_object (node);
10276 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10277 vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10278}
10279
10280static int
10281api_sw_interface_tap_dump (vat_main_t * vam)
10282{
10283 vl_api_sw_interface_tap_dump_t *mp;
10284 f64 timeout;
10285
10286 print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10287 /* Get list of tap interfaces */
10288 M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10289 S;
10290
10291 /* Use a control ping for synchronization */
10292 {
10293 vl_api_control_ping_t *mp;
10294 M (CONTROL_PING, control_ping);
10295 S;
10296 }
10297 W;
10298}
10299
10300static uword unformat_vxlan_decap_next
10301 (unformat_input_t * input, va_list * args)
10302{
10303 u32 *result = va_arg (*args, u32 *);
10304 u32 tmp;
10305
10306 if (unformat (input, "l2"))
10307 *result = VXLAN_INPUT_NEXT_L2_INPUT;
10308 else if (unformat (input, "%d", &tmp))
10309 *result = tmp;
10310 else
10311 return 0;
10312 return 1;
10313}
10314
10315static int
10316api_vxlan_add_del_tunnel (vat_main_t * vam)
10317{
10318 unformat_input_t *line_input = vam->input;
10319 vl_api_vxlan_add_del_tunnel_t *mp;
10320 f64 timeout;
10321 ip46_address_t src, dst;
10322 u8 is_add = 1;
10323 u8 ipv4_set = 0, ipv6_set = 0;
10324 u8 src_set = 0;
10325 u8 dst_set = 0;
10326 u8 grp_set = 0;
10327 u32 mcast_sw_if_index = ~0;
10328 u32 encap_vrf_id = 0;
10329 u32 decap_next_index = ~0;
10330 u32 vni = 0;
10331
10332 /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10333 memset (&src, 0, sizeof src);
10334 memset (&dst, 0, sizeof dst);
10335
10336 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10337 {
10338 if (unformat (line_input, "del"))
10339 is_add = 0;
10340 else
10341 if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10342 {
10343 ipv4_set = 1;
10344 src_set = 1;
10345 }
10346 else
10347 if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10348 {
10349 ipv4_set = 1;
10350 dst_set = 1;
10351 }
10352 else
10353 if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10354 {
10355 ipv6_set = 1;
10356 src_set = 1;
10357 }
10358 else
10359 if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10360 {
10361 ipv6_set = 1;
10362 dst_set = 1;
10363 }
10364 else if (unformat (line_input, "group %U %U",
10365 unformat_ip4_address, &dst.ip4,
10366 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10367 {
10368 grp_set = dst_set = 1;
10369 ipv4_set = 1;
10370 }
10371 else if (unformat (line_input, "group %U",
10372 unformat_ip4_address, &dst.ip4))
10373 {
10374 grp_set = dst_set = 1;
10375 ipv4_set = 1;
10376 }
10377 else if (unformat (line_input, "group %U %U",
10378 unformat_ip6_address, &dst.ip6,
10379 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10380 {
10381 grp_set = dst_set = 1;
10382 ipv6_set = 1;
10383 }
10384 else if (unformat (line_input, "group %U",
10385 unformat_ip6_address, &dst.ip6))
10386 {
10387 grp_set = dst_set = 1;
10388 ipv6_set = 1;
10389 }
10390 else
10391 if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10392 ;
10393 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10394 ;
10395 else if (unformat (line_input, "decap-next %U",
10396 unformat_vxlan_decap_next, &decap_next_index))
10397 ;
10398 else if (unformat (line_input, "vni %d", &vni))
10399 ;
10400 else
10401 {
10402 errmsg ("parse error '%U'", format_unformat_error, line_input);
10403 return -99;
10404 }
10405 }
10406
10407 if (src_set == 0)
10408 {
10409 errmsg ("tunnel src address not specified");
10410 return -99;
10411 }
10412 if (dst_set == 0)
10413 {
10414 errmsg ("tunnel dst address not specified");
10415 return -99;
10416 }
10417
10418 if (grp_set && !ip46_address_is_multicast (&dst))
10419 {
10420 errmsg ("tunnel group address not multicast");
10421 return -99;
10422 }
10423 if (grp_set && mcast_sw_if_index == ~0)
10424 {
10425 errmsg ("tunnel nonexistent multicast device");
10426 return -99;
10427 }
10428 if (grp_set == 0 && ip46_address_is_multicast (&dst))
10429 {
10430 errmsg ("tunnel dst address must be unicast");
10431 return -99;
10432 }
10433
10434
10435 if (ipv4_set && ipv6_set)
10436 {
10437 errmsg ("both IPv4 and IPv6 addresses specified");
10438 return -99;
10439 }
10440
10441 if ((vni == 0) || (vni >> 24))
10442 {
10443 errmsg ("vni not specified or out of range");
10444 return -99;
10445 }
10446
10447 M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10448
10449 if (ipv6_set)
10450 {
10451 clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10452 clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10453 }
10454 else
10455 {
10456 clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10457 clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10458 }
10459 mp->encap_vrf_id = ntohl (encap_vrf_id);
10460 mp->decap_next_index = ntohl (decap_next_index);
10461 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10462 mp->vni = ntohl (vni);
10463 mp->is_add = is_add;
10464 mp->is_ipv6 = ipv6_set;
10465
10466 S;
10467 W;
10468 /* NOTREACHED */
10469 return 0;
10470}
10471
10472static void vl_api_vxlan_tunnel_details_t_handler
10473 (vl_api_vxlan_tunnel_details_t * mp)
10474{
10475 vat_main_t *vam = &vat_main;
10476 ip46_address_t src, dst;
10477
10478 ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10479 ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10480
10481 print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10482 ntohl (mp->sw_if_index),
10483 format_ip46_address, &src, IP46_TYPE_ANY,
10484 format_ip46_address, &dst, IP46_TYPE_ANY,
10485 ntohl (mp->encap_vrf_id),
10486 ntohl (mp->decap_next_index), ntohl (mp->vni),
10487 ntohl (mp->mcast_sw_if_index));
10488}
10489
10490static void vl_api_vxlan_tunnel_details_t_handler_json
10491 (vl_api_vxlan_tunnel_details_t * mp)
10492{
10493 vat_main_t *vam = &vat_main;
10494 vat_json_node_t *node = NULL;
10495
10496 if (VAT_JSON_ARRAY != vam->json_tree.type)
10497 {
10498 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10499 vat_json_init_array (&vam->json_tree);
10500 }
10501 node = vat_json_array_add (&vam->json_tree);
10502
10503 vat_json_init_object (node);
10504 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10505 if (mp->is_ipv6)
10506 {
10507 struct in6_addr ip6;
10508
10509 clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10510 vat_json_object_add_ip6 (node, "src_address", ip6);
10511 clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10512 vat_json_object_add_ip6 (node, "dst_address", ip6);
10513 }
10514 else
10515 {
10516 struct in_addr ip4;
10517
10518 clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10519 vat_json_object_add_ip4 (node, "src_address", ip4);
10520 clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10521 vat_json_object_add_ip4 (node, "dst_address", ip4);
10522 }
10523 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10524 vat_json_object_add_uint (node, "decap_next_index",
10525 ntohl (mp->decap_next_index));
10526 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10527 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10528 vat_json_object_add_uint (node, "mcast_sw_if_index",
10529 ntohl (mp->mcast_sw_if_index));
10530}
10531
10532static int
10533api_vxlan_tunnel_dump (vat_main_t * vam)
10534{
10535 unformat_input_t *i = vam->input;
10536 vl_api_vxlan_tunnel_dump_t *mp;
10537 f64 timeout;
10538 u32 sw_if_index;
10539 u8 sw_if_index_set = 0;
10540
10541 /* Parse args required to build the message */
10542 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10543 {
10544 if (unformat (i, "sw_if_index %d", &sw_if_index))
10545 sw_if_index_set = 1;
10546 else
10547 break;
10548 }
10549
10550 if (sw_if_index_set == 0)
10551 {
10552 sw_if_index = ~0;
10553 }
10554
10555 if (!vam->json_output)
10556 {
10557 print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10558 "sw_if_index", "src_address", "dst_address",
10559 "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10560 }
10561
10562 /* Get list of vxlan-tunnel interfaces */
10563 M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10564
10565 mp->sw_if_index = htonl (sw_if_index);
10566
10567 S;
10568
10569 /* Use a control ping for synchronization */
10570 {
10571 vl_api_control_ping_t *mp;
10572 M (CONTROL_PING, control_ping);
10573 S;
10574 }
10575 W;
10576}
10577
10578static int
10579api_gre_add_del_tunnel (vat_main_t * vam)
10580{
10581 unformat_input_t *line_input = vam->input;
10582 vl_api_gre_add_del_tunnel_t *mp;
10583 f64 timeout;
10584 ip4_address_t src4, dst4;
10585 u8 is_add = 1;
10586 u8 teb = 0;
10587 u8 src_set = 0;
10588 u8 dst_set = 0;
10589 u32 outer_fib_id = 0;
10590
10591 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10592 {
10593 if (unformat (line_input, "del"))
10594 is_add = 0;
10595 else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10596 src_set = 1;
10597 else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10598 dst_set = 1;
10599 else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10600 ;
10601 else if (unformat (line_input, "teb"))
10602 teb = 1;
10603 else
10604 {
10605 errmsg ("parse error '%U'", format_unformat_error, line_input);
10606 return -99;
10607 }
10608 }
10609
10610 if (src_set == 0)
10611 {
10612 errmsg ("tunnel src address not specified");
10613 return -99;
10614 }
10615 if (dst_set == 0)
10616 {
10617 errmsg ("tunnel dst address not specified");
10618 return -99;
10619 }
10620
10621
10622 M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10623
10624 clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10625 clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10626 mp->outer_fib_id = ntohl (outer_fib_id);
10627 mp->is_add = is_add;
10628 mp->teb = teb;
10629
10630 S;
10631 W;
10632 /* NOTREACHED */
10633 return 0;
10634}
10635
10636static void vl_api_gre_tunnel_details_t_handler
10637 (vl_api_gre_tunnel_details_t * mp)
10638{
10639 vat_main_t *vam = &vat_main;
10640
10641 print (vam->ofp, "%11d%15U%15U%6d%14d",
10642 ntohl (mp->sw_if_index),
10643 format_ip4_address, &mp->src_address,
10644 format_ip4_address, &mp->dst_address,
10645 mp->teb, ntohl (mp->outer_fib_id));
10646}
10647
10648static void vl_api_gre_tunnel_details_t_handler_json
10649 (vl_api_gre_tunnel_details_t * mp)
10650{
10651 vat_main_t *vam = &vat_main;
10652 vat_json_node_t *node = NULL;
10653 struct in_addr ip4;
10654
10655 if (VAT_JSON_ARRAY != vam->json_tree.type)
10656 {
10657 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10658 vat_json_init_array (&vam->json_tree);
10659 }
10660 node = vat_json_array_add (&vam->json_tree);
10661
10662 vat_json_init_object (node);
10663 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10664 clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10665 vat_json_object_add_ip4 (node, "src_address", ip4);
10666 clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10667 vat_json_object_add_ip4 (node, "dst_address", ip4);
10668 vat_json_object_add_uint (node, "teb", mp->teb);
10669 vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10670}
10671
10672static int
10673api_gre_tunnel_dump (vat_main_t * vam)
10674{
10675 unformat_input_t *i = vam->input;
10676 vl_api_gre_tunnel_dump_t *mp;
10677 f64 timeout;
10678 u32 sw_if_index;
10679 u8 sw_if_index_set = 0;
10680
10681 /* Parse args required to build the message */
10682 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10683 {
10684 if (unformat (i, "sw_if_index %d", &sw_if_index))
10685 sw_if_index_set = 1;
10686 else
10687 break;
10688 }
10689
10690 if (sw_if_index_set == 0)
10691 {
10692 sw_if_index = ~0;
10693 }
10694
10695 if (!vam->json_output)
10696 {
10697 print (vam->ofp, "%11s%15s%15s%6s%14s",
10698 "sw_if_index", "src_address", "dst_address", "teb",
10699 "outer_fib_id");
10700 }
10701
10702 /* Get list of gre-tunnel interfaces */
10703 M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10704
10705 mp->sw_if_index = htonl (sw_if_index);
10706
10707 S;
10708
10709 /* Use a control ping for synchronization */
10710 {
10711 vl_api_control_ping_t *mp;
10712 M (CONTROL_PING, control_ping);
10713 S;
10714 }
10715 W;
10716}
10717
10718static int
10719api_l2_fib_clear_table (vat_main_t * vam)
10720{
10721// unformat_input_t * i = vam->input;
10722 vl_api_l2_fib_clear_table_t *mp;
10723 f64 timeout;
10724
10725 M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10726
10727 S;
10728 W;
10729 /* NOTREACHED */
10730 return 0;
10731}
10732
10733static int
10734api_l2_interface_efp_filter (vat_main_t * vam)
10735{
10736 unformat_input_t *i = vam->input;
10737 vl_api_l2_interface_efp_filter_t *mp;
10738 f64 timeout;
10739 u32 sw_if_index;
10740 u8 enable = 1;
10741 u8 sw_if_index_set = 0;
10742
10743 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10744 {
10745 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10746 sw_if_index_set = 1;
10747 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10748 sw_if_index_set = 1;
10749 else if (unformat (i, "enable"))
10750 enable = 1;
10751 else if (unformat (i, "disable"))
10752 enable = 0;
10753 else
10754 {
10755 clib_warning ("parse error '%U'", format_unformat_error, i);
10756 return -99;
10757 }
10758 }
10759
10760 if (sw_if_index_set == 0)
10761 {
10762 errmsg ("missing sw_if_index");
10763 return -99;
10764 }
10765
10766 M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10767
10768 mp->sw_if_index = ntohl (sw_if_index);
10769 mp->enable_disable = enable;
10770
10771 S;
10772 W;
10773 /* NOTREACHED */
10774 return 0;
10775}
10776
10777#define foreach_vtr_op \
10778_("disable", L2_VTR_DISABLED) \
10779_("push-1", L2_VTR_PUSH_1) \
10780_("push-2", L2_VTR_PUSH_2) \
10781_("pop-1", L2_VTR_POP_1) \
10782_("pop-2", L2_VTR_POP_2) \
10783_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
10784_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
10785_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
10786_("translate-2-2", L2_VTR_TRANSLATE_2_2)
10787
10788static int
10789api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10790{
10791 unformat_input_t *i = vam->input;
10792 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10793 f64 timeout;
10794 u32 sw_if_index;
10795 u8 sw_if_index_set = 0;
10796 u8 vtr_op_set = 0;
10797 u32 vtr_op = 0;
10798 u32 push_dot1q = 1;
10799 u32 tag1 = ~0;
10800 u32 tag2 = ~0;
10801
10802 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10803 {
10804 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10805 sw_if_index_set = 1;
10806 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10807 sw_if_index_set = 1;
10808 else if (unformat (i, "vtr_op %d", &vtr_op))
10809 vtr_op_set = 1;
10810#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10811 foreach_vtr_op
10812#undef _
10813 else if (unformat (i, "push_dot1q %d", &push_dot1q))
10814 ;
10815 else if (unformat (i, "tag1 %d", &tag1))
10816 ;
10817 else if (unformat (i, "tag2 %d", &tag2))
10818 ;
10819 else
10820 {
10821 clib_warning ("parse error '%U'", format_unformat_error, i);
10822 return -99;
10823 }
10824 }
10825
10826 if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10827 {
10828 errmsg ("missing vtr operation or sw_if_index");
10829 return -99;
10830 }
10831
10832 M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10833 mp->sw_if_index = ntohl (sw_if_index);
10834 mp->vtr_op = ntohl (vtr_op);
10835 mp->push_dot1q = ntohl (push_dot1q);
10836 mp->tag1 = ntohl (tag1);
10837 mp->tag2 = ntohl (tag2);
10838
10839 S;
10840 W;
10841 /* NOTREACHED */
10842 return 0;
10843}
10844
10845static int
10846api_create_vhost_user_if (vat_main_t * vam)
10847{
10848 unformat_input_t *i = vam->input;
10849 vl_api_create_vhost_user_if_t *mp;
10850 f64 timeout;
10851 u8 *file_name;
10852 u8 is_server = 0;
10853 u8 file_name_set = 0;
10854 u32 custom_dev_instance = ~0;
10855 u8 hwaddr[6];
10856 u8 use_custom_mac = 0;
10857 u8 *tag = 0;
10858
10859 /* Shut up coverity */
10860 memset (hwaddr, 0, sizeof (hwaddr));
10861
10862 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10863 {
10864 if (unformat (i, "socket %s", &file_name))
10865 {
10866 file_name_set = 1;
10867 }
10868 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10869 ;
10870 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10871 use_custom_mac = 1;
10872 else if (unformat (i, "server"))
10873 is_server = 1;
10874 else if (unformat (i, "tag %s", &tag))
10875 ;
10876 else
10877 break;
10878 }
10879
10880 if (file_name_set == 0)
10881 {
10882 errmsg ("missing socket file name");
10883 return -99;
10884 }
10885
10886 if (vec_len (file_name) > 255)
10887 {
10888 errmsg ("socket file name too long");
10889 return -99;
10890 }
10891 vec_add1 (file_name, 0);
10892
10893 M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10894
10895 mp->is_server = is_server;
10896 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10897 vec_free (file_name);
10898 if (custom_dev_instance != ~0)
10899 {
10900 mp->renumber = 1;
10901 mp->custom_dev_instance = ntohl (custom_dev_instance);
10902 }
10903 mp->use_custom_mac = use_custom_mac;
10904 clib_memcpy (mp->mac_address, hwaddr, 6);
10905 if (tag)
10906 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10907 vec_free (tag);
10908
10909 S;
10910 W;
10911 /* NOTREACHED */
10912 return 0;
10913}
10914
10915static int
10916api_modify_vhost_user_if (vat_main_t * vam)
10917{
10918 unformat_input_t *i = vam->input;
10919 vl_api_modify_vhost_user_if_t *mp;
10920 f64 timeout;
10921 u8 *file_name;
10922 u8 is_server = 0;
10923 u8 file_name_set = 0;
10924 u32 custom_dev_instance = ~0;
10925 u8 sw_if_index_set = 0;
10926 u32 sw_if_index = (u32) ~ 0;
10927
10928 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10929 {
10930 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10931 sw_if_index_set = 1;
10932 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10933 sw_if_index_set = 1;
10934 else if (unformat (i, "socket %s", &file_name))
10935 {
10936 file_name_set = 1;
10937 }
10938 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10939 ;
10940 else if (unformat (i, "server"))
10941 is_server = 1;
10942 else
10943 break;
10944 }
10945
10946 if (sw_if_index_set == 0)
10947 {
10948 errmsg ("missing sw_if_index or interface name");
10949 return -99;
10950 }
10951
10952 if (file_name_set == 0)
10953 {
10954 errmsg ("missing socket file name");
10955 return -99;
10956 }
10957
10958 if (vec_len (file_name) > 255)
10959 {
10960 errmsg ("socket file name too long");
10961 return -99;
10962 }
10963 vec_add1 (file_name, 0);
10964
10965 M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10966
10967 mp->sw_if_index = ntohl (sw_if_index);
10968 mp->is_server = is_server;
10969 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10970 vec_free (file_name);
10971 if (custom_dev_instance != ~0)
10972 {
10973 mp->renumber = 1;
10974 mp->custom_dev_instance = ntohl (custom_dev_instance);
10975 }
10976
10977 S;
10978 W;
10979 /* NOTREACHED */
10980 return 0;
10981}
10982
10983static int
10984api_delete_vhost_user_if (vat_main_t * vam)
10985{
10986 unformat_input_t *i = vam->input;
10987 vl_api_delete_vhost_user_if_t *mp;
10988 f64 timeout;
10989 u32 sw_if_index = ~0;
10990 u8 sw_if_index_set = 0;
10991
10992 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10993 {
10994 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10995 sw_if_index_set = 1;
10996 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10997 sw_if_index_set = 1;
10998 else
10999 break;
11000 }
11001
11002 if (sw_if_index_set == 0)
11003 {
11004 errmsg ("missing sw_if_index or interface name");
11005 return -99;
11006 }
11007
11008
11009 M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
11010
11011 mp->sw_if_index = ntohl (sw_if_index);
11012
11013 S;
11014 W;
11015 /* NOTREACHED */
11016 return 0;
11017}
11018
11019static void vl_api_sw_interface_vhost_user_details_t_handler
11020 (vl_api_sw_interface_vhost_user_details_t * mp)
11021{
11022 vat_main_t *vam = &vat_main;
11023
11024 print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11025 (char *) mp->interface_name,
11026 ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11027 clib_net_to_host_u64 (mp->features), mp->is_server,
11028 ntohl (mp->num_regions), (char *) mp->sock_filename);
11029 print (vam->ofp, " Status: '%s'", strerror (ntohl (mp->sock_errno)));
11030}
11031
11032static void vl_api_sw_interface_vhost_user_details_t_handler_json
11033 (vl_api_sw_interface_vhost_user_details_t * mp)
11034{
11035 vat_main_t *vam = &vat_main;
11036 vat_json_node_t *node = NULL;
11037
11038 if (VAT_JSON_ARRAY != vam->json_tree.type)
11039 {
11040 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11041 vat_json_init_array (&vam->json_tree);
11042 }
11043 node = vat_json_array_add (&vam->json_tree);
11044
11045 vat_json_init_object (node);
11046 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11047 vat_json_object_add_string_copy (node, "interface_name",
11048 mp->interface_name);
11049 vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11050 ntohl (mp->virtio_net_hdr_sz));
11051 vat_json_object_add_uint (node, "features",
11052 clib_net_to_host_u64 (mp->features));
11053 vat_json_object_add_uint (node, "is_server", mp->is_server);
11054 vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11055 vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11056 vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11057}
11058
11059static int
11060api_sw_interface_vhost_user_dump (vat_main_t * vam)
11061{
11062 vl_api_sw_interface_vhost_user_dump_t *mp;
11063 f64 timeout;
11064 print (vam->ofp,
11065 "Interface name idx hdr_sz features server regions filename");
11066
11067 /* Get list of vhost-user interfaces */
11068 M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
11069 S;
11070
11071 /* Use a control ping for synchronization */
11072 {
11073 vl_api_control_ping_t *mp;
11074 M (CONTROL_PING, control_ping);
11075 S;
11076 }
11077 W;
11078}
11079
11080static int
11081api_show_version (vat_main_t * vam)
11082{
11083 vl_api_show_version_t *mp;
11084 f64 timeout;
11085
11086 M (SHOW_VERSION, show_version);
11087
11088 S;
11089 W;
11090 /* NOTREACHED */
11091 return 0;
11092}
11093
11094
11095static int
11096api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11097{
11098 unformat_input_t *line_input = vam->input;
11099 vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11100 f64 timeout;
11101 ip4_address_t local4, remote4;
11102 ip6_address_t local6, remote6;
11103 u8 is_add = 1;
11104 u8 ipv4_set = 0, ipv6_set = 0;
11105 u8 local_set = 0;
11106 u8 remote_set = 0;
11107 u32 encap_vrf_id = 0;
11108 u32 decap_vrf_id = 0;
11109 u8 protocol = ~0;
11110 u32 vni;
11111 u8 vni_set = 0;
11112
11113 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11114 {
11115 if (unformat (line_input, "del"))
11116 is_add = 0;
11117 else if (unformat (line_input, "local %U",
11118 unformat_ip4_address, &local4))
11119 {
11120 local_set = 1;
11121 ipv4_set = 1;
11122 }
11123 else if (unformat (line_input, "remote %U",
11124 unformat_ip4_address, &remote4))
11125 {
11126 remote_set = 1;
11127 ipv4_set = 1;
11128 }
11129 else if (unformat (line_input, "local %U",
11130 unformat_ip6_address, &local6))
11131 {
11132 local_set = 1;
11133 ipv6_set = 1;
11134 }
11135 else if (unformat (line_input, "remote %U",
11136 unformat_ip6_address, &remote6))
11137 {
11138 remote_set = 1;
11139 ipv6_set = 1;
11140 }
11141 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11142 ;
11143 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11144 ;
11145 else if (unformat (line_input, "vni %d", &vni))
11146 vni_set = 1;
11147 else if (unformat (line_input, "next-ip4"))
11148 protocol = 1;
11149 else if (unformat (line_input, "next-ip6"))
11150 protocol = 2;
11151 else if (unformat (line_input, "next-ethernet"))
11152 protocol = 3;
11153 else if (unformat (line_input, "next-nsh"))
11154 protocol = 4;
11155 else
11156 {
11157 errmsg ("parse error '%U'", format_unformat_error, line_input);
11158 return -99;
11159 }
11160 }
11161
11162 if (local_set == 0)
11163 {
11164 errmsg ("tunnel local address not specified");
11165 return -99;
11166 }
11167 if (remote_set == 0)
11168 {
11169 errmsg ("tunnel remote address not specified");
11170 return -99;
11171 }
11172 if (ipv4_set && ipv6_set)
11173 {
11174 errmsg ("both IPv4 and IPv6 addresses specified");
11175 return -99;
11176 }
11177
11178 if (vni_set == 0)
11179 {
11180 errmsg ("vni not specified");
11181 return -99;
11182 }
11183
11184 M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
11185
11186
11187 if (ipv6_set)
11188 {
11189 clib_memcpy (&mp->local, &local6, sizeof (local6));
11190 clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11191 }
11192 else
11193 {
11194 clib_memcpy (&mp->local, &local4, sizeof (local4));
11195 clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11196 }
11197
11198 mp->encap_vrf_id = ntohl (encap_vrf_id);
11199 mp->decap_vrf_id = ntohl (decap_vrf_id);
11200 mp->protocol = protocol;
11201 mp->vni = ntohl (vni);
11202 mp->is_add = is_add;
11203 mp->is_ipv6 = ipv6_set;
11204
11205 S;
11206 W;
11207 /* NOTREACHED */
11208 return 0;
11209}
11210
11211static void vl_api_vxlan_gpe_tunnel_details_t_handler
11212 (vl_api_vxlan_gpe_tunnel_details_t * mp)
11213{
11214 vat_main_t *vam = &vat_main;
11215
11216 print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11217 ntohl (mp->sw_if_index),
11218 format_ip46_address, &(mp->local[0]),
11219 format_ip46_address, &(mp->remote[0]),
11220 ntohl (mp->vni),
11221 ntohl (mp->protocol),
11222 ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11223}
11224
11225static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11226 (vl_api_vxlan_gpe_tunnel_details_t * mp)
11227{
11228 vat_main_t *vam = &vat_main;
11229 vat_json_node_t *node = NULL;
11230 struct in_addr ip4;
11231 struct in6_addr ip6;
11232
11233 if (VAT_JSON_ARRAY != vam->json_tree.type)
11234 {
11235 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11236 vat_json_init_array (&vam->json_tree);
11237 }
11238 node = vat_json_array_add (&vam->json_tree);
11239
11240 vat_json_init_object (node);
11241 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11242 if (mp->is_ipv6)
11243 {
11244 clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11245 vat_json_object_add_ip6 (node, "local", ip6);
11246 clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11247 vat_json_object_add_ip6 (node, "remote", ip6);
11248 }
11249 else
11250 {
11251 clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11252 vat_json_object_add_ip4 (node, "local", ip4);
11253 clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11254 vat_json_object_add_ip4 (node, "remote", ip4);
11255 }
11256 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11257 vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11258 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11259 vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11260 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11261}
11262
11263static int
11264api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11265{
11266 unformat_input_t *i = vam->input;
11267 vl_api_vxlan_gpe_tunnel_dump_t *mp;
11268 f64 timeout;
11269 u32 sw_if_index;
11270 u8 sw_if_index_set = 0;
11271
11272 /* Parse args required to build the message */
11273 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11274 {
11275 if (unformat (i, "sw_if_index %d", &sw_if_index))
11276 sw_if_index_set = 1;
11277 else
11278 break;
11279 }
11280
11281 if (sw_if_index_set == 0)
11282 {
11283 sw_if_index = ~0;
11284 }
11285
11286 if (!vam->json_output)
11287 {
11288 print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11289 "sw_if_index", "local", "remote", "vni",
11290 "protocol", "encap_vrf_id", "decap_vrf_id");
11291 }
11292
11293 /* Get list of vxlan-tunnel interfaces */
11294 M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11295
11296 mp->sw_if_index = htonl (sw_if_index);
11297
11298 S;
11299
11300 /* Use a control ping for synchronization */
11301 {
11302 vl_api_control_ping_t *mp;
11303 M (CONTROL_PING, control_ping);
11304 S;
11305 }
11306 W;
11307}
11308
11309u8 *
11310format_l2_fib_mac_address (u8 * s, va_list * args)
11311{
11312 u8 *a = va_arg (*args, u8 *);
11313
11314 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11315 a[2], a[3], a[4], a[5], a[6], a[7]);
11316}
11317
11318static void vl_api_l2_fib_table_entry_t_handler
11319 (vl_api_l2_fib_table_entry_t * mp)
11320{
11321 vat_main_t *vam = &vat_main;
11322
11323 print (vam->ofp, "%3" PRIu32 " %U %3" PRIu32
11324 " %d %d %d",
11325 ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11326 ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11327 mp->bvi_mac);
11328}
11329
11330static void vl_api_l2_fib_table_entry_t_handler_json
11331 (vl_api_l2_fib_table_entry_t * mp)
11332{
11333 vat_main_t *vam = &vat_main;
11334 vat_json_node_t *node = NULL;
11335
11336 if (VAT_JSON_ARRAY != vam->json_tree.type)
11337 {
11338 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11339 vat_json_init_array (&vam->json_tree);
11340 }
11341 node = vat_json_array_add (&vam->json_tree);
11342
11343 vat_json_init_object (node);
11344 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11345 vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11346 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11347 vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11348 vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11349 vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11350}
11351
11352static int
11353api_l2_fib_table_dump (vat_main_t * vam)
11354{
11355 unformat_input_t *i = vam->input;
11356 vl_api_l2_fib_table_dump_t *mp;
11357 f64 timeout;
11358 u32 bd_id;
11359 u8 bd_id_set = 0;
11360
11361 /* Parse args required to build the message */
11362 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11363 {
11364 if (unformat (i, "bd_id %d", &bd_id))
11365 bd_id_set = 1;
11366 else
11367 break;
11368 }
11369
11370 if (bd_id_set == 0)
11371 {
11372 errmsg ("missing bridge domain");
11373 return -99;
11374 }
11375
11376 print (vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI");
11377
11378 /* Get list of l2 fib entries */
11379 M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11380
11381 mp->bd_id = ntohl (bd_id);
11382 S;
11383
11384 /* Use a control ping for synchronization */
11385 {
11386 vl_api_control_ping_t *mp;
11387 M (CONTROL_PING, control_ping);
11388 S;
11389 }
11390 W;
11391}
11392
11393
11394static int
11395api_interface_name_renumber (vat_main_t * vam)
11396{
11397 unformat_input_t *line_input = vam->input;
11398 vl_api_interface_name_renumber_t *mp;
11399 u32 sw_if_index = ~0;
11400 f64 timeout;
11401 u32 new_show_dev_instance = ~0;
11402
11403 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11404 {
11405 if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11406 &sw_if_index))
11407 ;
11408 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11409 ;
11410 else if (unformat (line_input, "new_show_dev_instance %d",
11411 &new_show_dev_instance))
11412 ;
11413 else
11414 break;
11415 }
11416
11417 if (sw_if_index == ~0)
11418 {
11419 errmsg ("missing interface name or sw_if_index");
11420 return -99;
11421 }
11422
11423 if (new_show_dev_instance == ~0)
11424 {
11425 errmsg ("missing new_show_dev_instance");
11426 return -99;
11427 }
11428
11429 M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11430
11431 mp->sw_if_index = ntohl (sw_if_index);
11432 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11433
11434 S;
11435 W;
11436}
11437
11438static int
11439api_want_ip4_arp_events (vat_main_t * vam)
11440{
11441 unformat_input_t *line_input = vam->input;
11442 vl_api_want_ip4_arp_events_t *mp;
11443 f64 timeout;
11444 ip4_address_t address;
11445 int address_set = 0;
11446 u32 enable_disable = 1;
11447
11448 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11449 {
11450 if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11451 address_set = 1;
11452 else if (unformat (line_input, "del"))
11453 enable_disable = 0;
11454 else
11455 break;
11456 }
11457
11458 if (address_set == 0)
11459 {
11460 errmsg ("missing addresses");
11461 return -99;
11462 }
11463
11464 M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11465 mp->enable_disable = enable_disable;
11466 mp->pid = getpid ();
11467 mp->address = address.as_u32;
11468
11469 S;
11470 W;
11471}
11472
11473static int
11474api_want_ip6_nd_events (vat_main_t * vam)
11475{
11476 unformat_input_t *line_input = vam->input;
11477 vl_api_want_ip6_nd_events_t *mp;
11478 f64 timeout;
11479 ip6_address_t address;
11480 int address_set = 0;
11481 u32 enable_disable = 1;
11482
11483 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11484 {
11485 if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11486 address_set = 1;
11487 else if (unformat (line_input, "del"))
11488 enable_disable = 0;
11489 else
11490 break;
11491 }
11492
11493 if (address_set == 0)
11494 {
11495 errmsg ("missing addresses");
11496 return -99;
11497 }
11498
11499 M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11500 mp->enable_disable = enable_disable;
11501 mp->pid = getpid ();
11502 clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11503
11504 S;
11505 W;
11506}
11507
11508static int
11509api_input_acl_set_interface (vat_main_t * vam)
11510{
11511 unformat_input_t *i = vam->input;
11512 vl_api_input_acl_set_interface_t *mp;
11513 f64 timeout;
11514 u32 sw_if_index;
11515 int sw_if_index_set;
11516 u32 ip4_table_index = ~0;
11517 u32 ip6_table_index = ~0;
11518 u32 l2_table_index = ~0;
11519 u8 is_add = 1;
11520
11521 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11522 {
11523 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11524 sw_if_index_set = 1;
11525 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11526 sw_if_index_set = 1;
11527 else if (unformat (i, "del"))
11528 is_add = 0;
11529 else if (unformat (i, "ip4-table %d", &ip4_table_index))
11530 ;
11531 else if (unformat (i, "ip6-table %d", &ip6_table_index))
11532 ;
11533 else if (unformat (i, "l2-table %d", &l2_table_index))
11534 ;
11535 else
11536 {
11537 clib_warning ("parse error '%U'", format_unformat_error, i);
11538 return -99;
11539 }
11540 }
11541
11542 if (sw_if_index_set == 0)
11543 {
11544 errmsg ("missing interface name or sw_if_index");
11545 return -99;
11546 }
11547
11548 M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11549
11550 mp->sw_if_index = ntohl (sw_if_index);
11551 mp->ip4_table_index = ntohl (ip4_table_index);
11552 mp->ip6_table_index = ntohl (ip6_table_index);
11553 mp->l2_table_index = ntohl (l2_table_index);
11554 mp->is_add = is_add;
11555
11556 S;
11557 W;
11558 /* NOTREACHED */
11559 return 0;
11560}
11561
11562static int
11563api_ip_address_dump (vat_main_t * vam)
11564{
11565 unformat_input_t *i = vam->input;
11566 vl_api_ip_address_dump_t *mp;
11567 u32 sw_if_index = ~0;
11568 u8 sw_if_index_set = 0;
11569 u8 ipv4_set = 0;
11570 u8 ipv6_set = 0;
11571 f64 timeout;
11572
11573 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11574 {
11575 if (unformat (i, "sw_if_index %d", &sw_if_index))
11576 sw_if_index_set = 1;
11577 else
11578 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11579 sw_if_index_set = 1;
11580 else if (unformat (i, "ipv4"))
11581 ipv4_set = 1;
11582 else if (unformat (i, "ipv6"))
11583 ipv6_set = 1;
11584 else
11585 break;
11586 }
11587
11588 if (ipv4_set && ipv6_set)
11589 {
11590 errmsg ("ipv4 and ipv6 flags cannot be both set");
11591 return -99;
11592 }
11593
11594 if ((!ipv4_set) && (!ipv6_set))
11595 {
11596 errmsg ("no ipv4 nor ipv6 flag set");
11597 return -99;
11598 }
11599
11600 if (sw_if_index_set == 0)
11601 {
11602 errmsg ("missing interface name or sw_if_index");
11603 return -99;
11604 }
11605
11606 vam->current_sw_if_index = sw_if_index;
11607 vam->is_ipv6 = ipv6_set;
11608
11609 M (IP_ADDRESS_DUMP, ip_address_dump);
11610 mp->sw_if_index = ntohl (sw_if_index);
11611 mp->is_ipv6 = ipv6_set;
11612 S;
11613
11614 /* Use a control ping for synchronization */
11615 {
11616 vl_api_control_ping_t *mp;
11617 M (CONTROL_PING, control_ping);
11618 S;
11619 }
11620 W;
11621}
11622
11623static int
11624api_ip_dump (vat_main_t * vam)
11625{
11626 vl_api_ip_dump_t *mp;
11627 unformat_input_t *in = vam->input;
11628 int ipv4_set = 0;
11629 int ipv6_set = 0;
11630 int is_ipv6;
11631 f64 timeout;
11632 int i;
11633
11634 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11635 {
11636 if (unformat (in, "ipv4"))
11637 ipv4_set = 1;
11638 else if (unformat (in, "ipv6"))
11639 ipv6_set = 1;
11640 else
11641 break;
11642 }
11643
11644 if (ipv4_set && ipv6_set)
11645 {
11646 errmsg ("ipv4 and ipv6 flags cannot be both set");
11647 return -99;
11648 }
11649
11650 if ((!ipv4_set) && (!ipv6_set))
11651 {
11652 errmsg ("no ipv4 nor ipv6 flag set");
11653 return -99;
11654 }
11655
11656 is_ipv6 = ipv6_set;
11657 vam->is_ipv6 = is_ipv6;
11658
11659 /* free old data */
11660 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11661 {
11662 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11663 }
11664 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11665
11666 M (IP_DUMP, ip_dump);
11667 mp->is_ipv6 = ipv6_set;
11668 S;
11669
11670 /* Use a control ping for synchronization */
11671 {
11672 vl_api_control_ping_t *mp;
11673 M (CONTROL_PING, control_ping);
11674 S;
11675 }
11676 W;
11677}
11678
11679static int
11680api_ipsec_spd_add_del (vat_main_t * vam)
11681{
11682 unformat_input_t *i = vam->input;
11683 vl_api_ipsec_spd_add_del_t *mp;
11684 f64 timeout;
11685 u32 spd_id = ~0;
11686 u8 is_add = 1;
11687
11688 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11689 {
11690 if (unformat (i, "spd_id %d", &spd_id))
11691 ;
11692 else if (unformat (i, "del"))
11693 is_add = 0;
11694 else
11695 {
11696 clib_warning ("parse error '%U'", format_unformat_error, i);
11697 return -99;
11698 }
11699 }
11700 if (spd_id == ~0)
11701 {
11702 errmsg ("spd_id must be set");
11703 return -99;
11704 }
11705
11706 M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11707
11708 mp->spd_id = ntohl (spd_id);
11709 mp->is_add = is_add;
11710
11711 S;
11712 W;
11713 /* NOTREACHED */
11714 return 0;
11715}
11716
11717static int
11718api_ipsec_interface_add_del_spd (vat_main_t * vam)
11719{
11720 unformat_input_t *i = vam->input;
11721 vl_api_ipsec_interface_add_del_spd_t *mp;
11722 f64 timeout;
11723 u32 sw_if_index;
11724 u8 sw_if_index_set = 0;
11725 u32 spd_id = (u32) ~ 0;
11726 u8 is_add = 1;
11727
11728 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11729 {
11730 if (unformat (i, "del"))
11731 is_add = 0;
11732 else if (unformat (i, "spd_id %d", &spd_id))
11733 ;
11734 else
11735 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11736 sw_if_index_set = 1;
11737 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11738 sw_if_index_set = 1;
11739 else
11740 {
11741 clib_warning ("parse error '%U'", format_unformat_error, i);
11742 return -99;
11743 }
11744
11745 }
11746
11747 if (spd_id == (u32) ~ 0)
11748 {
11749 errmsg ("spd_id must be set");
11750 return -99;
11751 }
11752
11753 if (sw_if_index_set == 0)
11754 {
11755 errmsg ("missing interface name or sw_if_index");
11756 return -99;
11757 }
11758
11759 M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11760
11761 mp->spd_id = ntohl (spd_id);
11762 mp->sw_if_index = ntohl (sw_if_index);
11763 mp->is_add = is_add;
11764
11765 S;
11766 W;
11767 /* NOTREACHED */
11768 return 0;
11769}
11770
11771static int
11772api_ipsec_spd_add_del_entry (vat_main_t * vam)
11773{
11774 unformat_input_t *i = vam->input;
11775 vl_api_ipsec_spd_add_del_entry_t *mp;
11776 f64 timeout;
11777 u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11778 u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11779 i32 priority = 0;
11780 u32 rport_start = 0, rport_stop = (u32) ~ 0;
11781 u32 lport_start = 0, lport_stop = (u32) ~ 0;
11782 ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11783 ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11784
11785 laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11786 laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11787 laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11788 laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11789 laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11790 laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11791
11792 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11793 {
11794 if (unformat (i, "del"))
11795 is_add = 0;
11796 if (unformat (i, "outbound"))
11797 is_outbound = 1;
11798 if (unformat (i, "inbound"))
11799 is_outbound = 0;
11800 else if (unformat (i, "spd_id %d", &spd_id))
11801 ;
11802 else if (unformat (i, "sa_id %d", &sa_id))
11803 ;
11804 else if (unformat (i, "priority %d", &priority))
11805 ;
11806 else if (unformat (i, "protocol %d", &protocol))
11807 ;
11808 else if (unformat (i, "lport_start %d", &lport_start))
11809 ;
11810 else if (unformat (i, "lport_stop %d", &lport_stop))
11811 ;
11812 else if (unformat (i, "rport_start %d", &rport_start))
11813 ;
11814 else if (unformat (i, "rport_stop %d", &rport_stop))
11815 ;
11816 else
11817 if (unformat
11818 (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11819 {
11820 is_ipv6 = 0;
11821 is_ip_any = 0;
11822 }
11823 else
11824 if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11825 {
11826 is_ipv6 = 0;
11827 is_ip_any = 0;
11828 }
11829 else
11830 if (unformat
11831 (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11832 {
11833 is_ipv6 = 0;
11834 is_ip_any = 0;
11835 }
11836 else
11837 if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11838 {
11839 is_ipv6 = 0;
11840 is_ip_any = 0;
11841 }
11842 else
11843 if (unformat
11844 (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11845 {
11846 is_ipv6 = 1;
11847 is_ip_any = 0;
11848 }
11849 else
11850 if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11851 {
11852 is_ipv6 = 1;
11853 is_ip_any = 0;
11854 }
11855 else
11856 if (unformat
11857 (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11858 {
11859 is_ipv6 = 1;
11860 is_ip_any = 0;
11861 }
11862 else
11863 if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11864 {
11865 is_ipv6 = 1;
11866 is_ip_any = 0;
11867 }
11868 else
11869 if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11870 {
11871 if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11872 {
11873 clib_warning ("unsupported action: 'resolve'");
11874 return -99;
11875 }
11876 }
11877 else
11878 {
11879 clib_warning ("parse error '%U'", format_unformat_error, i);
11880 return -99;
11881 }
11882
11883 }
11884
11885 M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11886
11887 mp->spd_id = ntohl (spd_id);
11888 mp->priority = ntohl (priority);
11889 mp->is_outbound = is_outbound;
11890
11891 mp->is_ipv6 = is_ipv6;
11892 if (is_ipv6 || is_ip_any)
11893 {
11894 clib_memcpy (mp->remote_address_start, &raddr6_start,
11895 sizeof (ip6_address_t));
11896 clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11897 sizeof (ip6_address_t));
11898 clib_memcpy (mp->local_address_start, &laddr6_start,
11899 sizeof (ip6_address_t));
11900 clib_memcpy (mp->local_address_stop, &laddr6_stop,
11901 sizeof (ip6_address_t));
11902 }
11903 else
11904 {
11905 clib_memcpy (mp->remote_address_start, &raddr4_start,
11906 sizeof (ip4_address_t));
11907 clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11908 sizeof (ip4_address_t));
11909 clib_memcpy (mp->local_address_start, &laddr4_start,
11910 sizeof (ip4_address_t));
11911 clib_memcpy (mp->local_address_stop, &laddr4_stop,
11912 sizeof (ip4_address_t));
11913 }
11914 mp->protocol = (u8) protocol;
11915 mp->local_port_start = ntohs ((u16) lport_start);
11916 mp->local_port_stop = ntohs ((u16) lport_stop);
11917 mp->remote_port_start = ntohs ((u16) rport_start);
11918 mp->remote_port_stop = ntohs ((u16) rport_stop);
11919 mp->policy = (u8) policy;
11920 mp->sa_id = ntohl (sa_id);
11921 mp->is_add = is_add;
11922 mp->is_ip_any = is_ip_any;
11923 S;
11924 W;
11925 /* NOTREACHED */
11926 return 0;
11927}
11928
11929static int
11930api_ipsec_sad_add_del_entry (vat_main_t * vam)
11931{
11932 unformat_input_t *i = vam->input;
11933 vl_api_ipsec_sad_add_del_entry_t *mp;
11934 f64 timeout;
11935 u32 sad_id = 0, spi = 0;
11936 u8 *ck = 0, *ik = 0;
11937 u8 is_add = 1;
11938
11939 u8 protocol = IPSEC_PROTOCOL_AH;
11940 u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11941 u32 crypto_alg = 0, integ_alg = 0;
11942 ip4_address_t tun_src4;
11943 ip4_address_t tun_dst4;
11944 ip6_address_t tun_src6;
11945 ip6_address_t tun_dst6;
11946
11947 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11948 {
11949 if (unformat (i, "del"))
11950 is_add = 0;
11951 else if (unformat (i, "sad_id %d", &sad_id))
11952 ;
11953 else if (unformat (i, "spi %d", &spi))
11954 ;
11955 else if (unformat (i, "esp"))
11956 protocol = IPSEC_PROTOCOL_ESP;
11957 else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11958 {
11959 is_tunnel = 1;
11960 is_tunnel_ipv6 = 0;
11961 }
11962 else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11963 {
11964 is_tunnel = 1;
11965 is_tunnel_ipv6 = 0;
11966 }
11967 else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11968 {
11969 is_tunnel = 1;
11970 is_tunnel_ipv6 = 1;
11971 }
11972 else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11973 {
11974 is_tunnel = 1;
11975 is_tunnel_ipv6 = 1;
11976 }
11977 else
11978 if (unformat
11979 (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11980 {
11981 if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11982 crypto_alg >= IPSEC_CRYPTO_N_ALG)
11983 {
11984 clib_warning ("unsupported crypto-alg: '%U'",
11985 format_ipsec_crypto_alg, crypto_alg);
11986 return -99;
11987 }
11988 }
11989 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11990 ;
11991 else
11992 if (unformat
11993 (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11994 {
11995#if DPDK_CRYPTO==1
11996 if (integ_alg < IPSEC_INTEG_ALG_NONE ||
11997#else
11998 if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11999#endif
12000 integ_alg >= IPSEC_INTEG_N_ALG)
12001 {
12002 clib_warning ("unsupported integ-alg: '%U'",
12003 format_ipsec_integ_alg, integ_alg);
12004 return -99;
12005 }
12006 }
12007 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12008 ;
12009 else
12010 {
12011 clib_warning ("parse error '%U'", format_unformat_error, i);
12012 return -99;
12013 }
12014
12015 }
12016
12017#if DPDK_CRYPTO==1
12018 /*Special cases, aes-gcm-128 encryption */
12019 if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
12020 {
12021 if (integ_alg != IPSEC_INTEG_ALG_NONE
12022 && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
12023 {
12024 clib_warning
12025 ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
12026 return -99;
12027 }
12028 else /*set integ-alg internally to aes-gcm-128 */
12029 integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
12030 }
12031 else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
12032 {
12033 clib_warning ("unsupported integ-alg: aes-gcm-128");
12034 return -99;
12035 }
12036 else if (integ_alg == IPSEC_INTEG_ALG_NONE)
12037 {
12038 clib_warning ("unsupported integ-alg: none");
12039 return -99;
12040 }
12041#endif
12042
12043
12044 M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
12045
12046 mp->sad_id = ntohl (sad_id);
12047 mp->is_add = is_add;
12048 mp->protocol = protocol;
12049 mp->spi = ntohl (spi);
12050 mp->is_tunnel = is_tunnel;
12051 mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12052 mp->crypto_algorithm = crypto_alg;
12053 mp->integrity_algorithm = integ_alg;
12054 mp->crypto_key_length = vec_len (ck);
12055 mp->integrity_key_length = vec_len (ik);
12056
12057 if (mp->crypto_key_length > sizeof (mp->crypto_key))
12058 mp->crypto_key_length = sizeof (mp->crypto_key);
12059
12060 if (mp->integrity_key_length > sizeof (mp->integrity_key))
12061 mp->integrity_key_length = sizeof (mp->integrity_key);
12062
12063 if (ck)
12064 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12065 if (ik)
12066 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12067
12068 if (is_tunnel)
12069 {
12070 if (is_tunnel_ipv6)
12071 {
12072 clib_memcpy (mp->tunnel_src_address, &tun_src6,
12073 sizeof (ip6_address_t));
12074 clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12075 sizeof (ip6_address_t));
12076 }
12077 else
12078 {
12079 clib_memcpy (mp->tunnel_src_address, &tun_src4,
12080 sizeof (ip4_address_t));
12081 clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12082 sizeof (ip4_address_t));
12083 }
12084 }
12085
12086 S;
12087 W;
12088 /* NOTREACHED */
12089 return 0;
12090}
12091
12092static int
12093api_ipsec_sa_set_key (vat_main_t * vam)
12094{
12095 unformat_input_t *i = vam->input;
12096 vl_api_ipsec_sa_set_key_t *mp;
12097 f64 timeout;
12098 u32 sa_id;
12099 u8 *ck = 0, *ik = 0;
12100
12101 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12102 {
12103 if (unformat (i, "sa_id %d", &sa_id))
12104 ;
12105 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12106 ;
12107 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12108 ;
12109 else
12110 {
12111 clib_warning ("parse error '%U'", format_unformat_error, i);
12112 return -99;
12113 }
12114 }
12115
12116 M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
12117
12118 mp->sa_id = ntohl (sa_id);
12119 mp->crypto_key_length = vec_len (ck);
12120 mp->integrity_key_length = vec_len (ik);
12121
12122 if (mp->crypto_key_length > sizeof (mp->crypto_key))
12123 mp->crypto_key_length = sizeof (mp->crypto_key);
12124
12125 if (mp->integrity_key_length > sizeof (mp->integrity_key))
12126 mp->integrity_key_length = sizeof (mp->integrity_key);
12127
12128 if (ck)
12129 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12130 if (ik)
12131 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12132
12133 S;
12134 W;
12135 /* NOTREACHED */
12136 return 0;
12137}
12138
12139static int
12140api_ikev2_profile_add_del (vat_main_t * vam)
12141{
12142 unformat_input_t *i = vam->input;
12143 vl_api_ikev2_profile_add_del_t *mp;
12144 f64 timeout;
12145 u8 is_add = 1;
12146 u8 *name = 0;
12147
12148 const char *valid_chars = "a-zA-Z0-9_";
12149
12150 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12151 {
12152 if (unformat (i, "del"))
12153 is_add = 0;
12154 else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12155 vec_add1 (name, 0);
12156 else
12157 {
12158 errmsg ("parse error '%U'", format_unformat_error, i);
12159 return -99;
12160 }
12161 }
12162
12163 if (!vec_len (name))
12164 {
12165 errmsg ("profile name must be specified");
12166 return -99;
12167 }
12168
12169 if (vec_len (name) > 64)
12170 {
12171 errmsg ("profile name too long");
12172 return -99;
12173 }
12174
12175 M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
12176
12177 clib_memcpy (mp->name, name, vec_len (name));
12178 mp->is_add = is_add;
12179 vec_free (name);
12180
12181 S;
12182 W;
12183 /* NOTREACHED */
12184 return 0;
12185}
12186
12187static int
12188api_ikev2_profile_set_auth (vat_main_t * vam)
12189{
12190 unformat_input_t *i = vam->input;
12191 vl_api_ikev2_profile_set_auth_t *mp;
12192 f64 timeout;
12193 u8 *name = 0;
12194 u8 *data = 0;
12195 u32 auth_method = 0;
12196 u8 is_hex = 0;
12197
12198 const char *valid_chars = "a-zA-Z0-9_";
12199
12200 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12201 {
12202 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12203 vec_add1 (name, 0);
12204 else if (unformat (i, "auth_method %U",
12205 unformat_ikev2_auth_method, &auth_method))
12206 ;
12207 else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12208 is_hex = 1;
12209 else if (unformat (i, "auth_data %v", &data))
12210 ;
12211 else
12212 {
12213 errmsg ("parse error '%U'", format_unformat_error, i);
12214 return -99;
12215 }
12216 }
12217
12218 if (!vec_len (name))
12219 {
12220 errmsg ("profile name must be specified");
12221 return -99;
12222 }
12223
12224 if (vec_len (name) > 64)
12225 {
12226 errmsg ("profile name too long");
12227 return -99;
12228 }
12229
12230 if (!vec_len (data))
12231 {
12232 errmsg ("auth_data must be specified");
12233 return -99;
12234 }
12235
12236 if (!auth_method)
12237 {
12238 errmsg ("auth_method must be specified");
12239 return -99;
12240 }
12241
12242 M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12243
12244 mp->is_hex = is_hex;
12245 mp->auth_method = (u8) auth_method;
12246 mp->data_len = vec_len (data);
12247 clib_memcpy (mp->name, name, vec_len (name));
12248 clib_memcpy (mp->data, data, vec_len (data));
12249 vec_free (name);
12250 vec_free (data);
12251
12252 S;
12253 W;
12254 /* NOTREACHED */
12255 return 0;
12256}
12257
12258static int
12259api_ikev2_profile_set_id (vat_main_t * vam)
12260{
12261 unformat_input_t *i = vam->input;
12262 vl_api_ikev2_profile_set_id_t *mp;
12263 f64 timeout;
12264 u8 *name = 0;
12265 u8 *data = 0;
12266 u8 is_local = 0;
12267 u32 id_type = 0;
12268 ip4_address_t ip4;
12269
12270 const char *valid_chars = "a-zA-Z0-9_";
12271
12272 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12273 {
12274 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12275 vec_add1 (name, 0);
12276 else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12277 ;
12278 else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12279 {
12280 data = vec_new (u8, 4);
12281 clib_memcpy (data, ip4.as_u8, 4);
12282 }
12283 else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12284 ;
12285 else if (unformat (i, "id_data %v", &data))
12286 ;
12287 else if (unformat (i, "local"))
12288 is_local = 1;
12289 else if (unformat (i, "remote"))
12290 is_local = 0;
12291 else
12292 {
12293 errmsg ("parse error '%U'", format_unformat_error, i);
12294 return -99;
12295 }
12296 }
12297
12298 if (!vec_len (name))
12299 {
12300 errmsg ("profile name must be specified");
12301 return -99;
12302 }
12303
12304 if (vec_len (name) > 64)
12305 {
12306 errmsg ("profile name too long");
12307 return -99;
12308 }
12309
12310 if (!vec_len (data))
12311 {
12312 errmsg ("id_data must be specified");
12313 return -99;
12314 }
12315
12316 if (!id_type)
12317 {
12318 errmsg ("id_type must be specified");
12319 return -99;
12320 }
12321
12322 M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12323
12324 mp->is_local = is_local;
12325 mp->id_type = (u8) id_type;
12326 mp->data_len = vec_len (data);
12327 clib_memcpy (mp->name, name, vec_len (name));
12328 clib_memcpy (mp->data, data, vec_len (data));
12329 vec_free (name);
12330 vec_free (data);
12331
12332 S;
12333 W;
12334 /* NOTREACHED */
12335 return 0;
12336}
12337
12338static int
12339api_ikev2_profile_set_ts (vat_main_t * vam)
12340{
12341 unformat_input_t *i = vam->input;
12342 vl_api_ikev2_profile_set_ts_t *mp;
12343 f64 timeout;
12344 u8 *name = 0;
12345 u8 is_local = 0;
12346 u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12347 ip4_address_t start_addr, end_addr;
12348
12349 const char *valid_chars = "a-zA-Z0-9_";
12350
12351 start_addr.as_u32 = 0;
12352 end_addr.as_u32 = (u32) ~ 0;
12353
12354 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12355 {
12356 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12357 vec_add1 (name, 0);
12358 else if (unformat (i, "protocol %d", &proto))
12359 ;
12360 else if (unformat (i, "start_port %d", &start_port))
12361 ;
12362 else if (unformat (i, "end_port %d", &end_port))
12363 ;
12364 else
12365 if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12366 ;
12367 else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12368 ;
12369 else if (unformat (i, "local"))
12370 is_local = 1;
12371 else if (unformat (i, "remote"))
12372 is_local = 0;
12373 else
12374 {
12375 errmsg ("parse error '%U'", format_unformat_error, i);
12376 return -99;
12377 }
12378 }
12379
12380 if (!vec_len (name))
12381 {
12382 errmsg ("profile name must be specified");
12383 return -99;
12384 }
12385
12386 if (vec_len (name) > 64)
12387 {
12388 errmsg ("profile name too long");
12389 return -99;
12390 }
12391
12392 M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12393
12394 mp->is_local = is_local;
12395 mp->proto = (u8) proto;
12396 mp->start_port = (u16) start_port;
12397 mp->end_port = (u16) end_port;
12398 mp->start_addr = start_addr.as_u32;
12399 mp->end_addr = end_addr.as_u32;
12400 clib_memcpy (mp->name, name, vec_len (name));
12401 vec_free (name);
12402
12403 S;
12404 W;
12405 /* NOTREACHED */
12406 return 0;
12407}
12408
12409static int
12410api_ikev2_set_local_key (vat_main_t * vam)
12411{
12412 unformat_input_t *i = vam->input;
12413 vl_api_ikev2_set_local_key_t *mp;
12414 f64 timeout;
12415 u8 *file = 0;
12416
12417 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12418 {
12419 if (unformat (i, "file %v", &file))
12420 vec_add1 (file, 0);
12421 else
12422 {
12423 errmsg ("parse error '%U'", format_unformat_error, i);
12424 return -99;
12425 }
12426 }
12427
12428 if (!vec_len (file))
12429 {
12430 errmsg ("RSA key file must be specified");
12431 return -99;
12432 }
12433
12434 if (vec_len (file) > 256)
12435 {
12436 errmsg ("file name too long");
12437 return -99;
12438 }
12439
12440 M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12441
12442 clib_memcpy (mp->key_file, file, vec_len (file));
12443 vec_free (file);
12444
12445 S;
12446 W;
12447 /* NOTREACHED */
12448 return 0;
12449}
12450
12451/*
12452 * MAP
12453 */
12454static int
12455api_map_add_domain (vat_main_t * vam)
12456{
12457 unformat_input_t *i = vam->input;
12458 vl_api_map_add_domain_t *mp;
12459 f64 timeout;
12460
12461 ip4_address_t ip4_prefix;
12462 ip6_address_t ip6_prefix;
12463 ip6_address_t ip6_src;
12464 u32 num_m_args = 0;
12465 u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12466 0, psid_length = 0;
12467 u8 is_translation = 0;
12468 u32 mtu = 0;
12469 u32 ip6_src_len = 128;
12470
12471 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12472 {
12473 if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12474 &ip4_prefix, &ip4_prefix_len))
12475 num_m_args++;
12476 else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12477 &ip6_prefix, &ip6_prefix_len))
12478 num_m_args++;
12479 else
12480 if (unformat
12481 (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12482 &ip6_src_len))
12483 num_m_args++;
12484 else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12485 num_m_args++;
12486 else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12487 num_m_args++;
12488 else if (unformat (i, "psid-offset %d", &psid_offset))
12489 num_m_args++;
12490 else if (unformat (i, "psid-len %d", &psid_length))
12491 num_m_args++;
12492 else if (unformat (i, "mtu %d", &mtu))
12493 num_m_args++;
12494 else if (unformat (i, "map-t"))
12495 is_translation = 1;
12496 else
12497 {
12498 clib_warning ("parse error '%U'", format_unformat_error, i);
12499 return -99;
12500 }
12501 }
12502
12503 if (num_m_args < 3)
12504 {
12505 errmsg ("mandatory argument(s) missing");
12506 return -99;
12507 }
12508
12509 /* Construct the API message */
12510 M (MAP_ADD_DOMAIN, map_add_domain);
12511
12512 clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12513 mp->ip4_prefix_len = ip4_prefix_len;
12514
12515 clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12516 mp->ip6_prefix_len = ip6_prefix_len;
12517
12518 clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12519 mp->ip6_src_prefix_len = ip6_src_len;
12520
12521 mp->ea_bits_len = ea_bits_len;
12522 mp->psid_offset = psid_offset;
12523 mp->psid_length = psid_length;
12524 mp->is_translation = is_translation;
12525 mp->mtu = htons (mtu);
12526
12527 /* send it... */
12528 S;
12529
12530 /* Wait for a reply, return good/bad news */
12531 W;
12532}
12533
12534static int
12535api_map_del_domain (vat_main_t * vam)
12536{
12537 unformat_input_t *i = vam->input;
12538 vl_api_map_del_domain_t *mp;
12539 f64 timeout;
12540
12541 u32 num_m_args = 0;
12542 u32 index;
12543
12544 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12545 {
12546 if (unformat (i, "index %d", &index))
12547 num_m_args++;
12548 else
12549 {
12550 clib_warning ("parse error '%U'", format_unformat_error, i);
12551 return -99;
12552 }
12553 }
12554
12555 if (num_m_args != 1)
12556 {
12557 errmsg ("mandatory argument(s) missing");
12558 return -99;
12559 }
12560
12561 /* Construct the API message */
12562 M (MAP_DEL_DOMAIN, map_del_domain);
12563
12564 mp->index = ntohl (index);
12565
12566 /* send it... */
12567 S;
12568
12569 /* Wait for a reply, return good/bad news */
12570 W;
12571}
12572
12573static int
12574api_map_add_del_rule (vat_main_t * vam)
12575{
12576 unformat_input_t *i = vam->input;
12577 vl_api_map_add_del_rule_t *mp;
12578 f64 timeout;
12579 u8 is_add = 1;
12580 ip6_address_t ip6_dst;
12581 u32 num_m_args = 0, index, psid = 0;
12582
12583 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12584 {
12585 if (unformat (i, "index %d", &index))
12586 num_m_args++;
12587 else if (unformat (i, "psid %d", &psid))
12588 num_m_args++;
12589 else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12590 num_m_args++;
12591 else if (unformat (i, "del"))
12592 {
12593 is_add = 0;
12594 }
12595 else
12596 {
12597 clib_warning ("parse error '%U'", format_unformat_error, i);
12598 return -99;
12599 }
12600 }
12601
12602 /* Construct the API message */
12603 M (MAP_ADD_DEL_RULE, map_add_del_rule);
12604
12605 mp->index = ntohl (index);
12606 mp->is_add = is_add;
12607 clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12608 mp->psid = ntohs (psid);
12609
12610 /* send it... */
12611 S;
12612
12613 /* Wait for a reply, return good/bad news */
12614 W;
12615}
12616
12617static int
12618api_map_domain_dump (vat_main_t * vam)
12619{
12620 vl_api_map_domain_dump_t *mp;
12621 f64 timeout;
12622
12623 /* Construct the API message */
12624 M (MAP_DOMAIN_DUMP, map_domain_dump);
12625
12626 /* send it... */
12627 S;
12628
12629 /* Use a control ping for synchronization */
12630 {
12631 vl_api_control_ping_t *mp;
12632 M (CONTROL_PING, control_ping);
12633 S;
12634 }
12635 W;
12636}
12637
12638static int
12639api_map_rule_dump (vat_main_t * vam)
12640{
12641 unformat_input_t *i = vam->input;
12642 vl_api_map_rule_dump_t *mp;
12643 f64 timeout;
12644 u32 domain_index = ~0;
12645
12646 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12647 {
12648 if (unformat (i, "index %u", &domain_index))
12649 ;
12650 else
12651 break;
12652 }
12653
12654 if (domain_index == ~0)
12655 {
12656 clib_warning ("parse error: domain index expected");
12657 return -99;
12658 }
12659
12660 /* Construct the API message */
12661 M (MAP_RULE_DUMP, map_rule_dump);
12662
12663 mp->domain_index = htonl (domain_index);
12664
12665 /* send it... */
12666 S;
12667
12668 /* Use a control ping for synchronization */
12669 {
12670 vl_api_control_ping_t *mp;
12671 M (CONTROL_PING, control_ping);
12672 S;
12673 }
12674 W;
12675}
12676
12677static void vl_api_map_add_domain_reply_t_handler
12678 (vl_api_map_add_domain_reply_t * mp)
12679{
12680 vat_main_t *vam = &vat_main;
12681 i32 retval = ntohl (mp->retval);
12682
12683 if (vam->async_mode)
12684 {
12685 vam->async_errors += (retval < 0);
12686 }
12687 else
12688 {
12689 vam->retval = retval;
12690 vam->result_ready = 1;
12691 }
12692}
12693
12694static void vl_api_map_add_domain_reply_t_handler_json
12695 (vl_api_map_add_domain_reply_t * mp)
12696{
12697 vat_main_t *vam = &vat_main;
12698 vat_json_node_t node;
12699
12700 vat_json_init_object (&node);
12701 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12702 vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12703
12704 vat_json_print (vam->ofp, &node);
12705 vat_json_free (&node);
12706
12707 vam->retval = ntohl (mp->retval);
12708 vam->result_ready = 1;
12709}
12710
12711static int
12712api_get_first_msg_id (vat_main_t * vam)
12713{
12714 vl_api_get_first_msg_id_t *mp;
12715 f64 timeout;
12716 unformat_input_t *i = vam->input;
12717 u8 *name;
12718 u8 name_set = 0;
12719
12720 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12721 {
12722 if (unformat (i, "client %s", &name))
12723 name_set = 1;
12724 else
12725 break;
12726 }
12727
12728 if (name_set == 0)
12729 {
12730 errmsg ("missing client name");
12731 return -99;
12732 }
12733 vec_add1 (name, 0);
12734
12735 if (vec_len (name) > 63)
12736 {
12737 errmsg ("client name too long");
12738 return -99;
12739 }
12740
12741 M (GET_FIRST_MSG_ID, get_first_msg_id);
12742 clib_memcpy (mp->name, name, vec_len (name));
12743 S;
12744 W;
12745 /* NOTREACHED */
12746 return 0;
12747}
12748
12749static int
12750api_cop_interface_enable_disable (vat_main_t * vam)
12751{
12752 unformat_input_t *line_input = vam->input;
12753 vl_api_cop_interface_enable_disable_t *mp;
12754 f64 timeout;
12755 u32 sw_if_index = ~0;
12756 u8 enable_disable = 1;
12757
12758 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12759 {
12760 if (unformat (line_input, "disable"))
12761 enable_disable = 0;
12762 if (unformat (line_input, "enable"))
12763 enable_disable = 1;
12764 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12765 vam, &sw_if_index))
12766 ;
12767 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12768 ;
12769 else
12770 break;
12771 }
12772
12773 if (sw_if_index == ~0)
12774 {
12775 errmsg ("missing interface name or sw_if_index");
12776 return -99;
12777 }
12778
12779 /* Construct the API message */
12780 M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12781 mp->sw_if_index = ntohl (sw_if_index);
12782 mp->enable_disable = enable_disable;
12783
12784 /* send it... */
12785 S;
12786 /* Wait for the reply */
12787 W;
12788}
12789
12790static int
12791api_cop_whitelist_enable_disable (vat_main_t * vam)
12792{
12793 unformat_input_t *line_input = vam->input;
12794 vl_api_cop_whitelist_enable_disable_t *mp;
12795 f64 timeout;
12796 u32 sw_if_index = ~0;
12797 u8 ip4 = 0, ip6 = 0, default_cop = 0;
12798 u32 fib_id = 0;
12799
12800 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12801 {
12802 if (unformat (line_input, "ip4"))
12803 ip4 = 1;
12804 else if (unformat (line_input, "ip6"))
12805 ip6 = 1;
12806 else if (unformat (line_input, "default"))
12807 default_cop = 1;
12808 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12809 vam, &sw_if_index))
12810 ;
12811 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12812 ;
12813 else if (unformat (line_input, "fib-id %d", &fib_id))
12814 ;
12815 else
12816 break;
12817 }
12818
12819 if (sw_if_index == ~0)
12820 {
12821 errmsg ("missing interface name or sw_if_index");
12822 return -99;
12823 }
12824
12825 /* Construct the API message */
12826 M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12827 mp->sw_if_index = ntohl (sw_if_index);
12828 mp->fib_id = ntohl (fib_id);
12829 mp->ip4 = ip4;
12830 mp->ip6 = ip6;
12831 mp->default_cop = default_cop;
12832
12833 /* send it... */
12834 S;
12835 /* Wait for the reply */
12836 W;
12837}
12838
12839static int
12840api_get_node_graph (vat_main_t * vam)
12841{
12842 vl_api_get_node_graph_t *mp;
12843 f64 timeout;
12844
12845 M (GET_NODE_GRAPH, get_node_graph);
12846
12847 /* send it... */
12848 S;
12849 /* Wait for the reply */
12850 W;
12851}
12852
12853/* *INDENT-OFF* */
12854/** Used for parsing LISP eids */
12855typedef CLIB_PACKED(struct{
12856 u8 addr[16]; /**< eid address */
12857 u32 len; /**< prefix length if IP */
12858 u8 type; /**< type of eid */
12859}) lisp_eid_vat_t;
12860/* *INDENT-ON* */
12861
12862static uword
12863unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12864{
12865 lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12866
12867 memset (a, 0, sizeof (a[0]));
12868
12869 if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12870 {
12871 a->type = 0; /* ipv4 type */
12872 }
12873 else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12874 {
12875 a->type = 1; /* ipv6 type */
12876 }
12877 else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12878 {
12879 a->type = 2; /* mac type */
12880 }
12881 else
12882 {
12883 return 0;
12884 }
12885
12886 if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12887 {
12888 return 0;
12889 }
12890
12891 return 1;
12892}
12893
12894static int
12895lisp_eid_size_vat (u8 type)
12896{
12897 switch (type)
12898 {
12899 case 0:
12900 return 4;
12901 case 1:
12902 return 16;
12903 case 2:
12904 return 6;
12905 }
12906 return 0;
12907}
12908
12909static void
12910lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12911{
12912 clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12913}
12914
12915/* *INDENT-OFF* */
12916/** Used for transferring locators via VPP API */
12917typedef CLIB_PACKED(struct
12918{
12919 u32 sw_if_index; /**< locator sw_if_index */
12920 u8 priority; /**< locator priority */
12921 u8 weight; /**< locator weight */
12922}) ls_locator_t;
12923/* *INDENT-ON* */
12924
12925static int
12926api_lisp_add_del_locator_set (vat_main_t * vam)
12927{
12928 unformat_input_t *input = vam->input;
12929 vl_api_lisp_add_del_locator_set_t *mp;
12930 f64 timeout = ~0;
12931 u8 is_add = 1;
12932 u8 *locator_set_name = NULL;
12933 u8 locator_set_name_set = 0;
12934 ls_locator_t locator, *locators = 0;
12935 u32 sw_if_index, priority, weight;
12936 u32 data_len = 0;
12937
12938 /* Parse args required to build the message */
12939 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12940 {
12941 if (unformat (input, "del"))
12942 {
12943 is_add = 0;
12944 }
12945 else if (unformat (input, "locator-set %s", &locator_set_name))
12946 {
12947 locator_set_name_set = 1;
12948 }
12949 else if (unformat (input, "sw_if_index %u p %u w %u",
12950 &sw_if_index, &priority, &weight))
12951 {
12952 locator.sw_if_index = htonl (sw_if_index);
12953 locator.priority = priority;
12954 locator.weight = weight;
12955 vec_add1 (locators, locator);
12956 }
12957 else
12958 if (unformat
12959 (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
12960 &sw_if_index, &priority, &weight))
12961 {
12962 locator.sw_if_index = htonl (sw_if_index);
12963 locator.priority = priority;
12964 locator.weight = weight;
12965 vec_add1 (locators, locator);
12966 }
12967 else
12968 break;
12969 }
12970
12971 if (locator_set_name_set == 0)
12972 {
12973 errmsg ("missing locator-set name");
12974 vec_free (locators);
12975 return -99;
12976 }
12977
12978 if (vec_len (locator_set_name) > 64)
12979 {
12980 errmsg ("locator-set name too long");
12981 vec_free (locator_set_name);
12982 vec_free (locators);
12983 return -99;
12984 }
12985 vec_add1 (locator_set_name, 0);
12986
12987 data_len = sizeof (ls_locator_t) * vec_len (locators);
12988
12989 /* Construct the API message */
12990 M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12991
12992 mp->is_add = is_add;
12993 clib_memcpy (mp->locator_set_name, locator_set_name,
12994 vec_len (locator_set_name));
12995 vec_free (locator_set_name);
12996
12997 mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12998 if (locators)
12999 clib_memcpy (mp->locators, locators, data_len);
13000 vec_free (locators);
13001
13002 /* send it... */
13003 S;
13004
13005 /* Wait for a reply... */
13006 W;
13007
13008 /* NOTREACHED */
13009 return 0;
13010}
13011
13012static int
13013api_lisp_add_del_locator (vat_main_t * vam)
13014{
13015 unformat_input_t *input = vam->input;
13016 vl_api_lisp_add_del_locator_t *mp;
13017 f64 timeout = ~0;
13018 u32 tmp_if_index = ~0;
13019 u32 sw_if_index = ~0;
13020 u8 sw_if_index_set = 0;
13021 u8 sw_if_index_if_name_set = 0;
13022 u32 priority = ~0;
13023 u8 priority_set = 0;
13024 u32 weight = ~0;
13025 u8 weight_set = 0;
13026 u8 is_add = 1;
13027 u8 *locator_set_name = NULL;
13028 u8 locator_set_name_set = 0;
13029
13030 /* Parse args required to build the message */
13031 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13032 {
13033 if (unformat (input, "del"))
13034 {
13035 is_add = 0;
13036 }
13037 else if (unformat (input, "locator-set %s", &locator_set_name))
13038 {
13039 locator_set_name_set = 1;
13040 }
13041 else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13042 &tmp_if_index))
13043 {
13044 sw_if_index_if_name_set = 1;
13045 sw_if_index = tmp_if_index;
13046 }
13047 else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13048 {
13049 sw_if_index_set = 1;
13050 sw_if_index = tmp_if_index;
13051 }
13052 else if (unformat (input, "p %d", &priority))
13053 {
13054 priority_set = 1;
13055 }
13056 else if (unformat (input, "w %d", &weight))
13057 {
13058 weight_set = 1;
13059 }
13060 else
13061 break;
13062 }
13063
13064 if (locator_set_name_set == 0)
13065 {
13066 errmsg ("missing locator-set name");
13067 return -99;
13068 }
13069
13070 if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13071 {
13072 errmsg ("missing sw_if_index");
13073 vec_free (locator_set_name);
13074 return -99;
13075 }
13076
13077 if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13078 {
13079 errmsg ("cannot use both params interface name and sw_if_index");
13080 vec_free (locator_set_name);
13081 return -99;
13082 }
13083
13084 if (priority_set == 0)
13085 {
13086 errmsg ("missing locator-set priority");
13087 vec_free (locator_set_name);
13088 return -99;
13089 }
13090
13091 if (weight_set == 0)
13092 {
13093 errmsg ("missing locator-set weight");
13094 vec_free (locator_set_name);
13095 return -99;
13096 }
13097
13098 if (vec_len (locator_set_name) > 64)
13099 {
13100 errmsg ("locator-set name too long");
13101 vec_free (locator_set_name);
13102 return -99;
13103 }
13104 vec_add1 (locator_set_name, 0);
13105
13106 /* Construct the API message */
13107 M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
13108
13109 mp->is_add = is_add;
13110 mp->sw_if_index = ntohl (sw_if_index);
13111 mp->priority = priority;
13112 mp->weight = weight;
13113 clib_memcpy (mp->locator_set_name, locator_set_name,
13114 vec_len (locator_set_name));
13115 vec_free (locator_set_name);
13116
13117 /* send it... */
13118 S;
13119
13120 /* Wait for a reply... */
13121 W;
13122
13123 /* NOTREACHED */
13124 return 0;
13125}
13126
13127uword
13128unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13129{
13130 u32 *key_id = va_arg (*args, u32 *);
13131 u8 *s = 0;
13132
13133 if (unformat (input, "%s", &s))
13134 {
13135 if (!strcmp ((char *) s, "sha1"))
13136 key_id[0] = HMAC_SHA_1_96;
13137 else if (!strcmp ((char *) s, "sha256"))
13138 key_id[0] = HMAC_SHA_256_128;
13139 else
13140 {
13141 clib_warning ("invalid key_id: '%s'", s);
13142 key_id[0] = HMAC_NO_KEY;
13143 }
13144 }
13145 else
13146 return 0;
13147
13148 vec_free (s);
13149 return 1;
13150}
13151
13152static int
13153api_lisp_add_del_local_eid (vat_main_t * vam)
13154{
13155 unformat_input_t *input = vam->input;
13156 vl_api_lisp_add_del_local_eid_t *mp;
13157 f64 timeout = ~0;
13158 u8 is_add = 1;
13159 u8 eid_set = 0;
13160 lisp_eid_vat_t _eid, *eid = &_eid;
13161 u8 *locator_set_name = 0;
13162 u8 locator_set_name_set = 0;
13163 u32 vni = 0;
13164 u16 key_id = 0;
13165 u8 *key = 0;
13166
13167 /* Parse args required to build the message */
13168 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13169 {
13170 if (unformat (input, "del"))
13171 {
13172 is_add = 0;
13173 }
13174 else if (unformat (input, "vni %d", &vni))
13175 {
13176 ;
13177 }
13178 else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13179 {
13180 eid_set = 1;
13181 }
13182 else if (unformat (input, "locator-set %s", &locator_set_name))
13183 {
13184 locator_set_name_set = 1;
13185 }
13186 else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13187 ;
13188 else if (unformat (input, "secret-key %_%v%_", &key))
13189 ;
13190 else
13191 break;
13192 }
13193
13194 if (locator_set_name_set == 0)
13195 {
13196 errmsg ("missing locator-set name");
13197 return -99;
13198 }
13199
13200 if (0 == eid_set)
13201 {
13202 errmsg ("EID address not set!");
13203 vec_free (locator_set_name);
13204 return -99;
13205 }
13206
13207 if (key && (0 == key_id))
13208 {
13209 errmsg ("invalid key_id!");
13210 return -99;
13211 }
13212
13213 if (vec_len (key) > 64)
13214 {
13215 errmsg ("key too long");
13216 vec_free (key);
13217 return -99;
13218 }
13219
13220 if (vec_len (locator_set_name) > 64)
13221 {
13222 errmsg ("locator-set name too long");
13223 vec_free (locator_set_name);
13224 return -99;
13225 }
13226 vec_add1 (locator_set_name, 0);
13227
13228 /* Construct the API message */
13229 M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
13230
13231 mp->is_add = is_add;
13232 lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13233 mp->eid_type = eid->type;
13234 mp->prefix_len = eid->len;
13235 mp->vni = clib_host_to_net_u32 (vni);
13236 mp->key_id = clib_host_to_net_u16 (key_id);
13237 clib_memcpy (mp->locator_set_name, locator_set_name,
13238 vec_len (locator_set_name));
13239 clib_memcpy (mp->key, key, vec_len (key));
13240
13241 vec_free (locator_set_name);
13242 vec_free (key);
13243
13244 /* send it... */
13245 S;
13246
13247 /* Wait for a reply... */
13248 W;
13249
13250 /* NOTREACHED */
13251 return 0;
13252}
13253
13254/* *INDENT-OFF* */
13255/** Used for transferring locators via VPP API */
13256typedef CLIB_PACKED(struct
13257{
13258 u8 is_ip4; /**< is locator an IPv4 address? */
13259 u8 priority; /**< locator priority */
13260 u8 weight; /**< locator weight */
13261 u8 addr[16]; /**< IPv4/IPv6 address */
13262}) rloc_t;
13263/* *INDENT-ON* */
13264
13265static int
13266api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13267{
13268 unformat_input_t *input = vam->input;
13269 vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13270 f64 timeout = ~0;
13271 u8 is_add = 1;
13272 lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13273 lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13274 u8 rmt_eid_set = 0, lcl_eid_set = 0;
13275 u32 action = ~0, p, w;
13276 ip4_address_t rmt_rloc4, lcl_rloc4;
13277 ip6_address_t rmt_rloc6, lcl_rloc6;
13278 rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13279
13280 memset (&rloc, 0, sizeof (rloc));
13281
13282 /* Parse args required to build the message */
13283 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13284 {
13285 if (unformat (input, "del"))
13286 {
13287 is_add = 0;
13288 }
13289 else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
13290 {
13291 rmt_eid_set = 1;
13292 }
13293 else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
13294 {
13295 lcl_eid_set = 1;
13296 }
13297 else if (unformat (input, "p %d w %d", &p, &w))
13298 {
13299 if (!curr_rloc)
13300 {
13301 errmsg ("No RLOC configured for setting priority/weight!");
13302 return -99;
13303 }
13304 curr_rloc->priority = p;
13305 curr_rloc->weight = w;
13306 }
13307 else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13308 &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13309 {
13310 rloc.is_ip4 = 1;
13311
13312 clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13313 rloc.priority = rloc.weight = 0;
13314 vec_add1 (lcl_locs, rloc);
13315
13316 clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13317 vec_add1 (rmt_locs, rloc);
13318 /* priority and weight saved in rmt loc */
13319 curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13320 }
13321 else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13322 &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13323 {
13324 rloc.is_ip4 = 0;
13325 clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13326 rloc.priority = rloc.weight = 0;
13327 vec_add1 (lcl_locs, rloc);
13328
13329 clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13330 vec_add1 (rmt_locs, rloc);
13331 /* priority and weight saved in rmt loc */
13332 curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13333 }
13334 else if (unformat (input, "action %d", &action))
13335 {
13336 ;
13337 }
13338 else
13339 {
13340 clib_warning ("parse error '%U'", format_unformat_error, input);
13341 return -99;
13342 }
13343 }
13344
13345 if (!rmt_eid_set)
13346 {
13347 errmsg ("remote eid addresses not set");
13348 return -99;
13349 }
13350
13351 if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13352 {
13353 errmsg ("eid types don't match");
13354 return -99;
13355 }
13356
13357 if (0 == rmt_locs && (u32) ~ 0 == action)
13358 {
13359 errmsg ("action not set for negative mapping");
13360 return -99;
13361 }
13362
13363 /* Construct the API message */
13364 M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13365
13366 mp->is_add = is_add;
13367 lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13368 lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13369 mp->eid_type = rmt_eid->type;
13370 mp->rmt_len = rmt_eid->len;
13371 mp->lcl_len = lcl_eid->len;
13372 mp->action = action;
13373
13374 if (0 != rmt_locs && 0 != lcl_locs)
13375 {
13376 mp->loc_num = vec_len (rmt_locs);
13377 clib_memcpy (mp->lcl_locs, lcl_locs,
13378 (sizeof (rloc_t) * vec_len (lcl_locs)));
13379 clib_memcpy (mp->rmt_locs, rmt_locs,
13380 (sizeof (rloc_t) * vec_len (rmt_locs)));
13381 }
13382 vec_free (lcl_locs);
13383 vec_free (rmt_locs);
13384
13385 /* send it... */
13386 S;
13387
13388 /* Wait for a reply... */
13389 W;
13390
13391 /* NOTREACHED */
13392 return 0;
13393}
13394
13395static int
13396api_lisp_add_del_map_server (vat_main_t * vam)
13397{
13398 unformat_input_t *input = vam->input;
13399 vl_api_lisp_add_del_map_server_t *mp;
13400 f64 timeout = ~0;
13401 u8 is_add = 1;
13402 u8 ipv4_set = 0;
13403 u8 ipv6_set = 0;
13404 ip4_address_t ipv4;
13405 ip6_address_t ipv6;
13406
13407 /* Parse args required to build the message */
13408 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13409 {
13410 if (unformat (input, "del"))
13411 {
13412 is_add = 0;
13413 }
13414 else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13415 {
13416 ipv4_set = 1;
13417 }
13418 else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13419 {
13420 ipv6_set = 1;
13421 }
13422 else
13423 break;
13424 }
13425
13426 if (ipv4_set && ipv6_set)
13427 {
13428 errmsg ("both eid v4 and v6 addresses set");
13429 return -99;
13430 }
13431
13432 if (!ipv4_set && !ipv6_set)
13433 {
13434 errmsg ("eid addresses not set");
13435 return -99;
13436 }
13437
13438 /* Construct the API message */
13439 M (LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server);
13440
13441 mp->is_add = is_add;
13442 if (ipv6_set)
13443 {
13444 mp->is_ipv6 = 1;
13445 clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13446 }
13447 else
13448 {
13449 mp->is_ipv6 = 0;
13450 clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13451 }
13452
13453 /* send it... */
13454 S;
13455
13456 /* Wait for a reply... */
13457 W;
13458
13459 /* NOTREACHED */
13460 return 0;
13461}
13462
13463static int
13464api_lisp_add_del_map_resolver (vat_main_t * vam)
13465{
13466 unformat_input_t *input = vam->input;
13467 vl_api_lisp_add_del_map_resolver_t *mp;
13468 f64 timeout = ~0;
13469 u8 is_add = 1;
13470 u8 ipv4_set = 0;
13471 u8 ipv6_set = 0;
13472 ip4_address_t ipv4;
13473 ip6_address_t ipv6;
13474
13475 /* Parse args required to build the message */
13476 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13477 {
13478 if (unformat (input, "del"))
13479 {
13480 is_add = 0;
13481 }
13482 else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13483 {
13484 ipv4_set = 1;
13485 }
13486 else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13487 {
13488 ipv6_set = 1;
13489 }
13490 else
13491 break;
13492 }
13493
13494 if (ipv4_set && ipv6_set)
13495 {
13496 errmsg ("both eid v4 and v6 addresses set");
13497 return -99;
13498 }
13499
13500 if (!ipv4_set && !ipv6_set)
13501 {
13502 errmsg ("eid addresses not set");
13503 return -99;
13504 }
13505
13506 /* Construct the API message */
13507 M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13508
13509 mp->is_add = is_add;
13510 if (ipv6_set)
13511 {
13512 mp->is_ipv6 = 1;
13513 clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13514 }
13515 else
13516 {
13517 mp->is_ipv6 = 0;
13518 clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13519 }
13520
13521 /* send it... */
13522 S;
13523
13524 /* Wait for a reply... */
13525 W;
13526
13527 /* NOTREACHED */
13528 return 0;
13529}
13530
13531static int
13532api_lisp_gpe_enable_disable (vat_main_t * vam)
13533{
13534 unformat_input_t *input = vam->input;
13535 vl_api_lisp_gpe_enable_disable_t *mp;
13536 f64 timeout = ~0;
13537 u8 is_set = 0;
13538 u8 is_en = 1;
13539
13540 /* Parse args required to build the message */
13541 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13542 {
13543 if (unformat (input, "enable"))
13544 {
13545 is_set = 1;
13546 is_en = 1;
13547 }
13548 else if (unformat (input, "disable"))
13549 {
13550 is_set = 1;
13551 is_en = 0;
13552 }
13553 else
13554 break;
13555 }
13556
13557 if (is_set == 0)
13558 {
13559 errmsg ("Value not set");
13560 return -99;
13561 }
13562
13563 /* Construct the API message */
13564 M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13565
13566 mp->is_en = is_en;
13567
13568 /* send it... */
13569 S;
13570
13571 /* Wait for a reply... */
13572 W;
13573
13574 /* NOTREACHED */
13575 return 0;
13576}
13577
13578static int
13579api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
13580{
13581 unformat_input_t *input = vam->input;
13582 vl_api_lisp_rloc_probe_enable_disable_t *mp;
13583 f64 timeout = ~0;
13584 u8 is_set = 0;
13585 u8 is_en = 0;
13586
13587 /* Parse args required to build the message */
13588 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13589 {
13590 if (unformat (input, "enable"))
13591 {
13592 is_set = 1;
13593 is_en = 1;
13594 }
13595 else if (unformat (input, "disable"))
13596 is_set = 1;
13597 else
13598 break;
13599 }
13600
13601 if (!is_set)
13602 {
13603 errmsg ("Value not set");
13604 return -99;
13605 }
13606
13607 /* Construct the API message */
13608 M (LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable);
13609
13610 mp->is_enabled = is_en;
13611
13612 /* send it... */
13613 S;
13614
13615 /* Wait for a reply... */
13616 W;
13617
13618 /* NOTREACHED */
13619 return 0;
13620}
13621
13622static int
13623api_lisp_map_register_enable_disable (vat_main_t * vam)
13624{
13625 unformat_input_t *input = vam->input;
13626 vl_api_lisp_map_register_enable_disable_t *mp;
13627 f64 timeout = ~0;
13628 u8 is_set = 0;
13629 u8 is_en = 0;
13630
13631 /* Parse args required to build the message */
13632 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13633 {
13634 if (unformat (input, "enable"))
13635 {
13636 is_set = 1;
13637 is_en = 1;
13638 }
13639 else if (unformat (input, "disable"))
13640 is_set = 1;
13641 else
13642 break;
13643 }
13644
13645 if (!is_set)
13646 {
13647 errmsg ("Value not set");
13648 return -99;
13649 }
13650
13651 /* Construct the API message */
13652 M (LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable);
13653
13654 mp->is_enabled = is_en;
13655
13656 /* send it... */
13657 S;
13658
13659 /* Wait for a reply... */
13660 W;
13661
13662 /* NOTREACHED */
13663 return 0;
13664}
13665
13666static int
13667api_lisp_enable_disable (vat_main_t * vam)
13668{
13669 unformat_input_t *input = vam->input;
13670 vl_api_lisp_enable_disable_t *mp;
13671 f64 timeout = ~0;
13672 u8 is_set = 0;
13673 u8 is_en = 0;
13674
13675 /* Parse args required to build the message */
13676 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13677 {
13678 if (unformat (input, "enable"))
13679 {
13680 is_set = 1;
13681 is_en = 1;
13682 }
13683 else if (unformat (input, "disable"))
13684 {
13685 is_set = 1;
13686 }
13687 else
13688 break;
13689 }
13690
13691 if (!is_set)
13692 {
13693 errmsg ("Value not set");
13694 return -99;
13695 }
13696
13697 /* Construct the API message */
13698 M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13699
13700 mp->is_en = is_en;
13701
13702 /* send it... */
13703 S;
13704
13705 /* Wait for a reply... */
13706 W;
13707
13708 /* NOTREACHED */
13709 return 0;
13710}
13711
13712static int
13713api_show_lisp_map_register_state (vat_main_t * vam)
13714{
13715 f64 timeout = ~0;
13716 vl_api_show_lisp_map_register_state_t *mp;
13717
13718 M (SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state);
13719
13720 /* send */
13721 S;
13722
13723 /* wait for reply */
13724 W;
13725
13726 return 0;
13727}
13728
13729static int
13730api_show_lisp_rloc_probe_state (vat_main_t * vam)
13731{
13732 f64 timeout = ~0;
13733 vl_api_show_lisp_rloc_probe_state_t *mp;
13734
13735 M (SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state);
13736
13737 /* send */
13738 S;
13739
13740 /* wait for reply */
13741 W;
13742
13743 return 0;
13744}
13745
13746static int
13747api_show_lisp_map_request_mode (vat_main_t * vam)
13748{
13749 f64 timeout = ~0;
13750 vl_api_show_lisp_map_request_mode_t *mp;
13751
13752 M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13753
13754 /* send */
13755 S;
13756
13757 /* wait for reply */
13758 W;
13759
13760 return 0;
13761}
13762
13763static int
13764api_lisp_map_request_mode (vat_main_t * vam)
13765{
13766 f64 timeout = ~0;
13767 unformat_input_t *input = vam->input;
13768 vl_api_lisp_map_request_mode_t *mp;
13769 u8 mode = 0;
13770
13771 /* Parse args required to build the message */
13772 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13773 {
13774 if (unformat (input, "dst-only"))
13775 mode = 0;
13776 else if (unformat (input, "src-dst"))
13777 mode = 1;
13778 else
13779 {
13780 errmsg ("parse error '%U'", format_unformat_error, input);
13781 return -99;
13782 }
13783 }
13784
13785 M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13786
13787 mp->mode = mode;
13788
13789 /* send */
13790 S;
13791
13792 /* wait for reply */
13793 W;
13794
13795 /* notreached */
13796 return 0;
13797}
13798
13799/**
13800 * Enable/disable LISP proxy ITR.
13801 *
13802 * @param vam vpp API test context
13803 * @return return code
13804 */
13805static int
13806api_lisp_pitr_set_locator_set (vat_main_t * vam)
13807{
13808 f64 timeout = ~0;
13809 u8 ls_name_set = 0;
13810 unformat_input_t *input = vam->input;
13811 vl_api_lisp_pitr_set_locator_set_t *mp;
13812 u8 is_add = 1;
13813 u8 *ls_name = 0;
13814
13815 /* Parse args required to build the message */
13816 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13817 {
13818 if (unformat (input, "del"))
13819 is_add = 0;
13820 else if (unformat (input, "locator-set %s", &ls_name))
13821 ls_name_set = 1;
13822 else
13823 {
13824 errmsg ("parse error '%U'", format_unformat_error, input);
13825 return -99;
13826 }
13827 }
13828
13829 if (!ls_name_set)
13830 {
13831 errmsg ("locator-set name not set!");
13832 return -99;
13833 }
13834
13835 M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13836
13837 mp->is_add = is_add;
13838 clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13839 vec_free (ls_name);
13840
13841 /* send */
13842 S;
13843
13844 /* wait for reply */
13845 W;
13846
13847 /* notreached */
13848 return 0;
13849}
13850
13851static int
13852api_show_lisp_pitr (vat_main_t * vam)
13853{
13854 vl_api_show_lisp_pitr_t *mp;
13855 f64 timeout = ~0;
13856
13857 if (!vam->json_output)
13858 {
13859 print (vam->ofp, "%=20s", "lisp status:");
13860 }
13861
13862 M (SHOW_LISP_PITR, show_lisp_pitr);
13863 /* send it... */
13864 S;
13865
13866 /* Wait for a reply... */
13867 W;
13868
13869 /* NOTREACHED */
13870 return 0;
13871}
13872
13873/**
13874 * Add/delete mapping between vni and vrf
13875 */
13876static int
13877api_lisp_eid_table_add_del_map (vat_main_t * vam)
13878{
13879 f64 timeout = ~0;
13880 unformat_input_t *input = vam->input;
13881 vl_api_lisp_eid_table_add_del_map_t *mp;
13882 u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13883 u32 vni, vrf, bd_index;
13884
13885 /* Parse args required to build the message */
13886 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13887 {
13888 if (unformat (input, "del"))
13889 is_add = 0;
13890 else if (unformat (input, "vrf %d", &vrf))
13891 vrf_set = 1;
13892 else if (unformat (input, "bd_index %d", &bd_index))
13893 bd_index_set = 1;
13894 else if (unformat (input, "vni %d", &vni))
13895 vni_set = 1;
13896 else
13897 break;
13898 }
13899
13900 if (!vni_set || (!vrf_set && !bd_index_set))
13901 {
13902 errmsg ("missing arguments!");
13903 return -99;
13904 }
13905
13906 if (vrf_set && bd_index_set)
13907 {
13908 errmsg ("error: both vrf and bd entered!");
13909 return -99;
13910 }
13911
13912 M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13913
13914 mp->is_add = is_add;
13915 mp->vni = htonl (vni);
13916 mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13917 mp->is_l2 = bd_index_set;
13918
13919 /* send */
13920 S;
13921
13922 /* wait for reply */
13923 W;
13924
13925 /* notreached */
13926 return 0;
13927}
13928
13929uword
13930unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13931{
13932 u32 *action = va_arg (*args, u32 *);
13933 u8 *s = 0;
13934
13935 if (unformat (input, "%s", &s))
13936 {
13937 if (!strcmp ((char *) s, "no-action"))
13938 action[0] = 0;
13939 else if (!strcmp ((char *) s, "natively-forward"))
13940 action[0] = 1;
13941 else if (!strcmp ((char *) s, "send-map-request"))
13942 action[0] = 2;
13943 else if (!strcmp ((char *) s, "drop"))
13944 action[0] = 3;
13945 else
13946 {
13947 clib_warning ("invalid action: '%s'", s);
13948 action[0] = 3;
13949 }
13950 }
13951 else
13952 return 0;
13953
13954 vec_free (s);
13955 return 1;
13956}
13957
13958/**
13959 * Add/del remote mapping to/from LISP control plane
13960 *
13961 * @param vam vpp API test context
13962 * @return return code
13963 */
13964static int
13965api_lisp_add_del_remote_mapping (vat_main_t * vam)
13966{
13967 unformat_input_t *input = vam->input;
13968 vl_api_lisp_add_del_remote_mapping_t *mp;
13969 f64 timeout = ~0;
13970 u32 vni = 0;
13971 lisp_eid_vat_t _eid, *eid = &_eid;
13972 lisp_eid_vat_t _seid, *seid = &_seid;
13973 u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13974 u32 action = ~0, p, w, data_len;
13975 ip4_address_t rloc4;
13976 ip6_address_t rloc6;
13977 rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13978
13979 memset (&rloc, 0, sizeof (rloc));
13980
13981 /* Parse args required to build the message */
13982 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13983 {
13984 if (unformat (input, "del-all"))
13985 {
13986 del_all = 1;
13987 }
13988 else if (unformat (input, "del"))
13989 {
13990 is_add = 0;
13991 }
13992 else if (unformat (input, "add"))
13993 {
13994 is_add = 1;
13995 }
13996 else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13997 {
13998 eid_set = 1;
13999 }
14000 else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14001 {
14002 seid_set = 1;
14003 }
14004 else if (unformat (input, "vni %d", &vni))
14005 {
14006 ;
14007 }
14008 else if (unformat (input, "p %d w %d", &p, &w))
14009 {
14010 if (!curr_rloc)
14011 {
14012 errmsg ("No RLOC configured for setting priority/weight!");
14013 return -99;
14014 }
14015 curr_rloc->priority = p;
14016 curr_rloc->weight = w;
14017 }
14018 else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14019 {
14020 rloc.is_ip4 = 1;
14021 clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14022 vec_add1 (rlocs, rloc);
14023 curr_rloc = &rlocs[vec_len (rlocs) - 1];
14024 }
14025 else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14026 {
14027 rloc.is_ip4 = 0;
14028 clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14029 vec_add1 (rlocs, rloc);
14030 curr_rloc = &rlocs[vec_len (rlocs) - 1];
14031 }
14032 else if (unformat (input, "action %U",
14033 unformat_negative_mapping_action, &action))
14034 {
14035 ;
14036 }
14037 else
14038 {
14039 clib_warning ("parse error '%U'", format_unformat_error, input);
14040 return -99;
14041 }
14042 }
14043
14044 if (0 == eid_set)
14045 {
14046 errmsg ("missing params!");
14047 return -99;
14048 }
14049
14050 if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14051 {
14052 errmsg ("no action set for negative map-reply!");
14053 return -99;
14054 }
14055
14056 data_len = vec_len (rlocs) * sizeof (rloc_t);
14057
14058 M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
14059 mp->is_add = is_add;
14060 mp->vni = htonl (vni);
14061 mp->action = (u8) action;
14062 mp->is_src_dst = seid_set;
14063 mp->eid_len = eid->len;
14064 mp->seid_len = seid->len;
14065 mp->del_all = del_all;
14066 mp->eid_type = eid->type;
14067 lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14068 lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14069
14070 mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14071 clib_memcpy (mp->rlocs, rlocs, data_len);
14072 vec_free (rlocs);
14073
14074 /* send it... */
14075 S;
14076
14077 /* Wait for a reply... */
14078 W;
14079
14080 /* NOTREACHED */
14081 return 0;
14082}
14083
14084/**
14085 * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14086 * forwarding entries in data-plane accordingly.
14087 *
14088 * @param vam vpp API test context
14089 * @return return code
14090 */
14091static int
14092api_lisp_add_del_adjacency (vat_main_t * vam)
14093{
14094 unformat_input_t *input = vam->input;
14095 vl_api_lisp_add_del_adjacency_t *mp;
14096 f64 timeout = ~0;
14097 u32 vni = 0;
14098 ip4_address_t leid4, reid4;
14099 ip6_address_t leid6, reid6;
14100 u8 reid_mac[6] = { 0 };
14101 u8 leid_mac[6] = { 0 };
14102 u8 reid_type, leid_type;
14103 u32 leid_len = 0, reid_len = 0, len;
14104 u8 is_add = 1;
14105
14106 leid_type = reid_type = (u8) ~ 0;
14107
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, "add"))
14116 {
14117 is_add = 1;
14118 }
14119 else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14120 &reid4, &len))
14121 {
14122 reid_type = 0; /* ipv4 */
14123 reid_len = len;
14124 }
14125 else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14126 &reid6, &len))
14127 {
14128 reid_type = 1; /* ipv6 */
14129 reid_len = len;
14130 }
14131 else if (unformat (input, "reid %U", unformat_ethernet_address,
14132 reid_mac))
14133 {
14134 reid_type = 2; /* mac */
14135 }
14136 else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14137 &leid4, &len))
14138 {
14139 leid_type = 0; /* ipv4 */
14140 leid_len = len;
14141 }
14142 else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14143 &leid6, &len))
14144 {
14145 leid_type = 1; /* ipv6 */
14146 leid_len = len;
14147 }
14148 else if (unformat (input, "leid %U", unformat_ethernet_address,
14149 leid_mac))
14150 {
14151 leid_type = 2; /* mac */
14152 }
14153 else if (unformat (input, "vni %d", &vni))
14154 {
14155 ;
14156 }
14157 else
14158 {
14159 errmsg ("parse error '%U'", format_unformat_error, input);
14160 return -99;
14161 }
14162 }
14163
14164 if ((u8) ~ 0 == reid_type)
14165 {
14166 errmsg ("missing params!");
14167 return -99;
14168 }
14169
14170 if (leid_type != reid_type)
14171 {
14172 errmsg ("remote and local EIDs are of different types!");
14173 return -99;
14174 }
14175
14176 M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
14177 mp->is_add = is_add;
14178 mp->vni = htonl (vni);
14179 mp->leid_len = leid_len;
14180 mp->reid_len = reid_len;
14181 mp->eid_type = reid_type;
14182
14183 switch (mp->eid_type)
14184 {
14185 case 0:
14186 clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14187 clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14188 break;
14189 case 1:
14190 clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14191 clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14192 break;
14193 case 2:
14194 clib_memcpy (mp->leid, leid_mac, 6);
14195 clib_memcpy (mp->reid, reid_mac, 6);
14196 break;
14197 default:
14198 errmsg ("unknown EID type %d!", mp->eid_type);
14199 return 0;
14200 }
14201
14202 /* send it... */
14203 S;
14204
14205 /* Wait for a reply... */
14206 W;
14207
14208 /* NOTREACHED */
14209 return 0;
14210}
14211
14212static int
14213api_lisp_gpe_add_del_iface (vat_main_t * vam)
14214{
14215 unformat_input_t *input = vam->input;
14216 vl_api_lisp_gpe_add_del_iface_t *mp;
14217 f64 timeout = ~0;
14218 u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14219 u32 dp_table = 0, vni = 0;
14220
14221 /* Parse args required to build the message */
14222 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14223 {
14224 if (unformat (input, "up"))
14225 {
14226 action_set = 1;
14227 is_add = 1;
14228 }
14229 else if (unformat (input, "down"))
14230 {
14231 action_set = 1;
14232 is_add = 0;
14233 }
14234 else if (unformat (input, "table_id %d", &dp_table))
14235 {
14236 dp_table_set = 1;
14237 }
14238 else if (unformat (input, "bd_id %d", &dp_table))
14239 {
14240 dp_table_set = 1;
14241 is_l2 = 1;
14242 }
14243 else if (unformat (input, "vni %d", &vni))
14244 {
14245 vni_set = 1;
14246 }
14247 else
14248 break;
14249 }
14250
14251 if (action_set == 0)
14252 {
14253 errmsg ("Action not set");
14254 return -99;
14255 }
14256 if (dp_table_set == 0 || vni_set == 0)
14257 {
14258 errmsg ("vni and dp_table must be set");
14259 return -99;
14260 }
14261
14262 /* Construct the API message */
14263 M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
14264
14265 mp->is_add = is_add;
14266 mp->dp_table = dp_table;
14267 mp->is_l2 = is_l2;
14268 mp->vni = vni;
14269
14270 /* send it... */
14271 S;
14272
14273 /* Wait for a reply... */
14274 W;
14275
14276 /* NOTREACHED */
14277 return 0;
14278}
14279
14280/**
14281 * Add/del map request itr rlocs from LISP control plane and updates
14282 *
14283 * @param vam vpp API test context
14284 * @return return code
14285 */
14286static int
14287api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14288{
14289 unformat_input_t *input = vam->input;
14290 vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14291 f64 timeout = ~0;
14292 u8 *locator_set_name = 0;
14293 u8 locator_set_name_set = 0;
14294 u8 is_add = 1;
14295
14296 /* Parse args required to build the message */
14297 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14298 {
14299 if (unformat (input, "del"))
14300 {
14301 is_add = 0;
14302 }
14303 else if (unformat (input, "%_%v%_", &locator_set_name))
14304 {
14305 locator_set_name_set = 1;
14306 }
14307 else
14308 {
14309 clib_warning ("parse error '%U'", format_unformat_error, input);
14310 return -99;
14311 }
14312 }
14313
14314 if (is_add && !locator_set_name_set)
14315 {
14316 errmsg ("itr-rloc is not set!");
14317 return -99;
14318 }
14319
14320 if (is_add && vec_len (locator_set_name) > 64)
14321 {
14322 errmsg ("itr-rloc locator-set name too long");
14323 vec_free (locator_set_name);
14324 return -99;
14325 }
14326
14327 M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
14328 mp->is_add = is_add;
14329 if (is_add)
14330 {
14331 clib_memcpy (mp->locator_set_name, locator_set_name,
14332 vec_len (locator_set_name));
14333 }
14334 else
14335 {
14336 memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14337 }
14338 vec_free (locator_set_name);
14339
14340 /* send it... */
14341 S;
14342
14343 /* Wait for a reply... */
14344 W;
14345
14346 /* NOTREACHED */
14347 return 0;
14348}
14349
14350static int
14351api_lisp_locator_dump (vat_main_t * vam)
14352{
14353 unformat_input_t *input = vam->input;
14354 vl_api_lisp_locator_dump_t *mp;
14355 f64 timeout = ~0;
14356 u8 is_index_set = 0, is_name_set = 0;
14357 u8 *ls_name = 0;
14358 u32 ls_index = ~0;
14359
14360 /* Parse args required to build the message */
14361 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14362 {
14363 if (unformat (input, "ls_name %_%v%_", &ls_name))
14364 {
14365 is_name_set = 1;
14366 }
14367 else if (unformat (input, "ls_index %d", &ls_index))
14368 {
14369 is_index_set = 1;
14370 }
14371 else
14372 {
14373 errmsg ("parse error '%U'", format_unformat_error, input);
14374 return -99;
14375 }
14376 }
14377
14378 if (!is_index_set && !is_name_set)
14379 {
14380 errmsg ("error: expected one of index or name!");
14381 return -99;
14382 }
14383
14384 if (is_index_set && is_name_set)
14385 {
14386 errmsg ("error: only one param expected!");
14387 return -99;
14388 }
14389
14390 if (vec_len (ls_name) > 62)
14391 {
14392 errmsg ("error: locator set name too long!");
14393 return -99;
14394 }
14395
14396 if (!vam->json_output)
14397 {
14398 print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14399 }
14400
14401 M (LISP_LOCATOR_DUMP, lisp_locator_dump);
14402 mp->is_index_set = is_index_set;
14403
14404 if (is_index_set)
14405 mp->ls_index = clib_host_to_net_u32 (ls_index);
14406 else
14407 {
14408 vec_add1 (ls_name, 0);
14409 strncpy ((char *) mp->ls_name, (char *) ls_name,
14410 sizeof (mp->ls_name) - 1);
14411 }
14412
14413 /* send it... */
14414 S;
14415
14416 /* Use a control ping for synchronization */
14417 {
14418 vl_api_control_ping_t *mp;
14419 M (CONTROL_PING, control_ping);
14420 S;
14421 }
14422 /* Wait for a reply... */
14423 W;
14424
14425 /* NOTREACHED */
14426 return 0;
14427}
14428
14429static int
14430api_lisp_locator_set_dump (vat_main_t * vam)
14431{
14432 vl_api_lisp_locator_set_dump_t *mp;
14433 unformat_input_t *input = vam->input;
14434 f64 timeout = ~0;
14435 u8 filter = 0;
14436
14437 /* Parse args required to build the message */
14438 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14439 {
14440 if (unformat (input, "local"))
14441 {
14442 filter = 1;
14443 }
14444 else if (unformat (input, "remote"))
14445 {
14446 filter = 2;
14447 }
14448 else
14449 {
14450 errmsg ("parse error '%U'", format_unformat_error, input);
14451 return -99;
14452 }
14453 }
14454
14455 if (!vam->json_output)
14456 {
14457 print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14458 }
14459
14460 M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14461
14462 mp->filter = filter;
14463
14464 /* send it... */
14465 S;
14466
14467 /* Use a control ping for synchronization */
14468 {
14469 vl_api_control_ping_t *mp;
14470 M (CONTROL_PING, control_ping);
14471 S;
14472 }
14473 /* Wait for a reply... */
14474 W;
14475
14476 /* NOTREACHED */
14477 return 0;
14478}
14479
14480static int
14481api_lisp_eid_table_map_dump (vat_main_t * vam)
14482{
14483 u8 is_l2 = 0;
14484 u8 mode_set = 0;
14485 unformat_input_t *input = vam->input;
14486 vl_api_lisp_eid_table_map_dump_t *mp;
14487 f64 timeout = ~0;
14488
14489 /* Parse args required to build the message */
14490 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14491 {
14492 if (unformat (input, "l2"))
14493 {
14494 is_l2 = 1;
14495 mode_set = 1;
14496 }
14497 else if (unformat (input, "l3"))
14498 {
14499 is_l2 = 0;
14500 mode_set = 1;
14501 }
14502 else
14503 {
14504 errmsg ("parse error '%U'", format_unformat_error, input);
14505 return -99;
14506 }
14507 }
14508
14509 if (!mode_set)
14510 {
14511 errmsg ("expected one of 'l2' or 'l3' parameter!");
14512 return -99;
14513 }
14514
14515 if (!vam->json_output)
14516 {
14517 print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
14518 }
14519
14520 M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14521 mp->is_l2 = is_l2;
14522
14523 /* send it... */
14524 S;
14525
14526 /* Use a control ping for synchronization */
14527 {
14528 vl_api_control_ping_t *mp;
14529 M (CONTROL_PING, control_ping);
14530 S;
14531 }
14532 /* Wait for a reply... */
14533 W;
14534
14535 /* NOTREACHED */
14536 return 0;
14537}
14538
14539static int
14540api_lisp_eid_table_vni_dump (vat_main_t * vam)
14541{
14542 vl_api_lisp_eid_table_vni_dump_t *mp;
14543 f64 timeout = ~0;
14544
14545 if (!vam->json_output)
14546 {
14547 print (vam->ofp, "VNI");
14548 }
14549
14550 M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14551
14552 /* send it... */
14553 S;
14554
14555 /* Use a control ping for synchronization */
14556 {
14557 vl_api_control_ping_t *mp;
14558 M (CONTROL_PING, control_ping);
14559 S;
14560 }
14561 /* Wait for a reply... */
14562 W;
14563
14564 /* NOTREACHED */
14565 return 0;
14566}
14567
14568static int
14569api_lisp_eid_table_dump (vat_main_t * vam)
14570{
14571 unformat_input_t *i = vam->input;
14572 vl_api_lisp_eid_table_dump_t *mp;
14573 f64 timeout = ~0;
14574 struct in_addr ip4;
14575 struct in6_addr ip6;
14576 u8 mac[6];
14577 u8 eid_type = ~0, eid_set = 0;
14578 u32 prefix_length = ~0, t, vni = 0;
14579 u8 filter = 0;
14580
14581 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14582 {
14583 if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14584 {
14585 eid_set = 1;
14586 eid_type = 0;
14587 prefix_length = t;
14588 }
14589 else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14590 {
14591 eid_set = 1;
14592 eid_type = 1;
14593 prefix_length = t;
14594 }
14595 else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14596 {
14597 eid_set = 1;
14598 eid_type = 2;
14599 }
14600 else if (unformat (i, "vni %d", &t))
14601 {
14602 vni = t;
14603 }
14604 else if (unformat (i, "local"))
14605 {
14606 filter = 1;
14607 }
14608 else if (unformat (i, "remote"))
14609 {
14610 filter = 2;
14611 }
14612 else
14613 {
14614 errmsg ("parse error '%U'", format_unformat_error, i);
14615 return -99;
14616 }
14617 }
14618
14619 if (!vam->json_output)
14620 {
14621 print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
14622 "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14623 }
14624
14625 M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14626
14627 mp->filter = filter;
14628 if (eid_set)
14629 {
14630 mp->eid_set = 1;
14631 mp->vni = htonl (vni);
14632 mp->eid_type = eid_type;
14633 switch (eid_type)
14634 {
14635 case 0:
14636 mp->prefix_length = prefix_length;
14637 clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14638 break;
14639 case 1:
14640 mp->prefix_length = prefix_length;
14641 clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14642 break;
14643 case 2:
14644 clib_memcpy (mp->eid, mac, sizeof (mac));
14645 break;
14646 default:
14647 errmsg ("unknown EID type %d!", eid_type);
14648 return -99;
14649 }
14650 }
14651
14652 /* send it... */
14653 S;
14654
14655 /* Use a control ping for synchronization */
14656 {
14657 vl_api_control_ping_t *mp;
14658 M (CONTROL_PING, control_ping);
14659 S;
14660 }
14661
14662 /* Wait for a reply... */
14663 W;
14664
14665 /* NOTREACHED */
14666 return 0;
14667}
14668
14669static int
14670api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14671{
14672 vl_api_lisp_gpe_tunnel_dump_t *mp;
14673 f64 timeout = ~0;
14674
14675 if (!vam->json_output)
14676 {
14677 print (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14678 "%=16s%=16s%=16s%=16s%=16s",
14679 "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14680 "Decap next", "Lisp version", "Flags", "Next protocol",
14681 "ver_res", "res", "iid");
14682 }
14683
14684 M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14685 /* send it... */
14686 S;
14687
14688 /* Use a control ping for synchronization */
14689 {
14690 vl_api_control_ping_t *mp;
14691 M (CONTROL_PING, control_ping);
14692 S;
14693 }
14694 /* Wait for a reply... */
14695 W;
14696
14697 /* NOTREACHED */
14698 return 0;
14699}
14700
14701static int
14702api_lisp_adjacencies_get (vat_main_t * vam)
14703{
14704 unformat_input_t *i = vam->input;
14705 vl_api_lisp_adjacencies_get_t *mp;
14706 f64 timeout = ~0;
14707 u8 vni_set = 0;
14708 u32 vni = ~0;
14709
14710 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14711 {
14712 if (unformat (i, "vni %d", &vni))
14713 {
14714 vni_set = 1;
14715 }
14716 else
14717 {
14718 errmsg ("parse error '%U'", format_unformat_error, i);
14719 return -99;
14720 }
14721 }
14722
14723 if (!vni_set)
14724 {
14725 errmsg ("vni not set!");
14726 return -99;
14727 }
14728
14729 if (!vam->json_output)
14730 {
14731 print (vam->ofp, "%s %40s", "leid", "reid");
14732 }
14733
14734 M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14735 mp->vni = clib_host_to_net_u32 (vni);
14736
14737 /* send it... */
14738 S;
14739
14740 /* Wait for a reply... */
14741 W;
14742
14743 /* NOTREACHED */
14744 return 0;
14745}
14746
14747static int
14748api_lisp_map_server_dump (vat_main_t * vam)
14749{
14750 vl_api_lisp_map_server_dump_t *mp;
14751 f64 timeout = ~0;
14752
14753 if (!vam->json_output)
14754 {
14755 print (vam->ofp, "%=20s", "Map server");
14756 }
14757
14758 M (LISP_MAP_SERVER_DUMP, lisp_map_server_dump);
14759 /* send it... */
14760 S;
14761
14762 /* Use a control ping for synchronization */
14763 {
14764 vl_api_control_ping_t *mp;
14765 M (CONTROL_PING, control_ping);
14766 S;
14767 }
14768 /* Wait for a reply... */
14769 W;
14770
14771 /* NOTREACHED */
14772 return 0;
14773}
14774
14775static int
14776api_lisp_map_resolver_dump (vat_main_t * vam)
14777{
14778 vl_api_lisp_map_resolver_dump_t *mp;
14779 f64 timeout = ~0;
14780
14781 if (!vam->json_output)
14782 {
14783 print (vam->ofp, "%=20s", "Map resolver");
14784 }
14785
14786 M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14787 /* send it... */
14788 S;
14789
14790 /* Use a control ping for synchronization */
14791 {
14792 vl_api_control_ping_t *mp;
14793 M (CONTROL_PING, control_ping);
14794 S;
14795 }
14796 /* Wait for a reply... */
14797 W;
14798
14799 /* NOTREACHED */
14800 return 0;
14801}
14802
14803static int
14804api_show_lisp_status (vat_main_t * vam)
14805{
14806 vl_api_show_lisp_status_t *mp;
14807 f64 timeout = ~0;
14808
14809 if (!vam->json_output)
14810 {
14811 print (vam->ofp, "%-20s%-16s", "lisp status", "locator-set");
14812 }
14813
14814 M (SHOW_LISP_STATUS, show_lisp_status);
14815 /* send it... */
14816 S;
14817 /* Wait for a reply... */
14818 W;
14819
14820 /* NOTREACHED */
14821 return 0;
14822}
14823
14824static int
14825api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14826{
14827 vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14828 f64 timeout = ~0;
14829
14830 if (!vam->json_output)
14831 {
14832 print (vam->ofp, "%=20s", "itr-rlocs:");
14833 }
14834
14835 M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14836 /* send it... */
14837 S;
14838 /* Wait for a reply... */
14839 W;
14840
14841 /* NOTREACHED */
14842 return 0;
14843}
14844
14845static int
14846api_af_packet_create (vat_main_t * vam)
14847{
14848 unformat_input_t *i = vam->input;
14849 vl_api_af_packet_create_t *mp;
14850 f64 timeout;
14851 u8 *host_if_name = 0;
14852 u8 hw_addr[6];
14853 u8 random_hw_addr = 1;
14854
14855 memset (hw_addr, 0, sizeof (hw_addr));
14856
14857 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14858 {
14859 if (unformat (i, "name %s", &host_if_name))
14860 vec_add1 (host_if_name, 0);
14861 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14862 random_hw_addr = 0;
14863 else
14864 break;
14865 }
14866
14867 if (!vec_len (host_if_name))
14868 {
14869 errmsg ("host-interface name must be specified");
14870 return -99;
14871 }
14872
14873 if (vec_len (host_if_name) > 64)
14874 {
14875 errmsg ("host-interface name too long");
14876 return -99;
14877 }
14878
14879 M (AF_PACKET_CREATE, af_packet_create);
14880
14881 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14882 clib_memcpy (mp->hw_addr, hw_addr, 6);
14883 mp->use_random_hw_addr = random_hw_addr;
14884 vec_free (host_if_name);
14885
14886 S;
14887 W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14888 /* NOTREACHED */
14889 return 0;
14890}
14891
14892static int
14893api_af_packet_delete (vat_main_t * vam)
14894{
14895 unformat_input_t *i = vam->input;
14896 vl_api_af_packet_delete_t *mp;
14897 f64 timeout;
14898 u8 *host_if_name = 0;
14899
14900 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14901 {
14902 if (unformat (i, "name %s", &host_if_name))
14903 vec_add1 (host_if_name, 0);
14904 else
14905 break;
14906 }
14907
14908 if (!vec_len (host_if_name))
14909 {
14910 errmsg ("host-interface name must be specified");
14911 return -99;
14912 }
14913
14914 if (vec_len (host_if_name) > 64)
14915 {
14916 errmsg ("host-interface name too long");
14917 return -99;
14918 }
14919
14920 M (AF_PACKET_DELETE, af_packet_delete);
14921
14922 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14923 vec_free (host_if_name);
14924
14925 S;
14926 W;
14927 /* NOTREACHED */
14928 return 0;
14929}
14930
14931static int
14932api_policer_add_del (vat_main_t * vam)
14933{
14934 unformat_input_t *i = vam->input;
14935 vl_api_policer_add_del_t *mp;
14936 f64 timeout;
14937 u8 is_add = 1;
14938 u8 *name = 0;
14939 u32 cir = 0;
14940 u32 eir = 0;
14941 u64 cb = 0;
14942 u64 eb = 0;
14943 u8 rate_type = 0;
14944 u8 round_type = 0;
14945 u8 type = 0;
14946 u8 color_aware = 0;
14947 sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14948
14949 conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14950 conform_action.dscp = 0;
14951 exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14952 exceed_action.dscp = 0;
14953 violate_action.action_type = SSE2_QOS_ACTION_DROP;
14954 violate_action.dscp = 0;
14955
14956 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14957 {
14958 if (unformat (i, "del"))
14959 is_add = 0;
14960 else if (unformat (i, "name %s", &name))
14961 vec_add1 (name, 0);
14962 else if (unformat (i, "cir %u", &cir))
14963 ;
14964 else if (unformat (i, "eir %u", &eir))
14965 ;
14966 else if (unformat (i, "cb %u", &cb))
14967 ;
14968 else if (unformat (i, "eb %u", &eb))
14969 ;
14970 else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14971 &rate_type))
14972 ;
14973 else if (unformat (i, "round_type %U", unformat_policer_round_type,
14974 &round_type))
14975 ;
14976 else if (unformat (i, "type %U", unformat_policer_type, &type))
14977 ;
14978 else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14979 &conform_action))
14980 ;
14981 else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14982 &exceed_action))
14983 ;
14984 else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14985 &violate_action))
14986 ;
14987 else if (unformat (i, "color-aware"))
14988 color_aware = 1;
14989 else
14990 break;
14991 }
14992
14993 if (!vec_len (name))
14994 {
14995 errmsg ("policer name must be specified");
14996 return -99;
14997 }
14998
14999 if (vec_len (name) > 64)
15000 {
15001 errmsg ("policer name too long");
15002 return -99;
15003 }
15004
15005 M (POLICER_ADD_DEL, policer_add_del);
15006
15007 clib_memcpy (mp->name, name, vec_len (name));
15008 vec_free (name);
15009 mp->is_add = is_add;
15010 mp->cir = cir;
15011 mp->eir = eir;
15012 mp->cb = cb;
15013 mp->eb = eb;
15014 mp->rate_type = rate_type;
15015 mp->round_type = round_type;
15016 mp->type = type;
15017 mp->conform_action_type = conform_action.action_type;
15018 mp->conform_dscp = conform_action.dscp;
15019 mp->exceed_action_type = exceed_action.action_type;
15020 mp->exceed_dscp = exceed_action.dscp;
15021 mp->violate_action_type = violate_action.action_type;
15022 mp->violate_dscp = violate_action.dscp;
15023 mp->color_aware = color_aware;
15024
15025 S;
15026 W;
15027 /* NOTREACHED */
15028 return 0;
15029}
15030
15031static int
15032api_policer_dump (vat_main_t * vam)
15033{
15034 unformat_input_t *i = vam->input;
15035 vl_api_policer_dump_t *mp;
15036 f64 timeout = ~0;
15037 u8 *match_name = 0;
15038 u8 match_name_valid = 0;
15039
15040 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15041 {
15042 if (unformat (i, "name %s", &match_name))
15043 {
15044 vec_add1 (match_name, 0);
15045 match_name_valid = 1;
15046 }
15047 else
15048 break;
15049 }
15050
15051 M (POLICER_DUMP, policer_dump);
15052 mp->match_name_valid = match_name_valid;
15053 clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15054 vec_free (match_name);
15055 /* send it... */
15056 S;
15057
15058 /* Use a control ping for synchronization */
15059 {
15060 vl_api_control_ping_t *mp;
15061 M (CONTROL_PING, control_ping);
15062 S;
15063 }
15064 /* Wait for a reply... */
15065 W;
15066
15067 /* NOTREACHED */
15068 return 0;
15069}
15070
15071static int
15072api_policer_classify_set_interface (vat_main_t * vam)
15073{
15074 unformat_input_t *i = vam->input;
15075 vl_api_policer_classify_set_interface_t *mp;
15076 f64 timeout;
15077 u32 sw_if_index;
15078 int sw_if_index_set;
15079 u32 ip4_table_index = ~0;
15080 u32 ip6_table_index = ~0;
15081 u32 l2_table_index = ~0;
15082 u8 is_add = 1;
15083
15084 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15085 {
15086 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15087 sw_if_index_set = 1;
15088 else if (unformat (i, "sw_if_index %d", &sw_if_index))
15089 sw_if_index_set = 1;
15090 else if (unformat (i, "del"))
15091 is_add = 0;
15092 else if (unformat (i, "ip4-table %d", &ip4_table_index))
15093 ;
15094 else if (unformat (i, "ip6-table %d", &ip6_table_index))
15095 ;
15096 else if (unformat (i, "l2-table %d", &l2_table_index))
15097 ;
15098 else
15099 {
15100 clib_warning ("parse error '%U'", format_unformat_error, i);
15101 return -99;
15102 }
15103 }
15104
15105 if (sw_if_index_set == 0)
15106 {
15107 errmsg ("missing interface name or sw_if_index");
15108 return -99;
15109 }
15110
15111 M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
15112
15113 mp->sw_if_index = ntohl (sw_if_index);
15114 mp->ip4_table_index = ntohl (ip4_table_index);
15115 mp->ip6_table_index = ntohl (ip6_table_index);
15116 mp->l2_table_index = ntohl (l2_table_index);
15117 mp->is_add = is_add;
15118
15119 S;
15120 W;
15121 /* NOTREACHED */
15122 return 0;
15123}
15124
15125static int
15126api_policer_classify_dump (vat_main_t * vam)
15127{
15128 unformat_input_t *i = vam->input;
15129 vl_api_policer_classify_dump_t *mp;
15130 f64 timeout = ~0;
15131 u8 type = POLICER_CLASSIFY_N_TABLES;
15132
15133 if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15134 ;
15135 else
15136 {
15137 errmsg ("classify table type must be specified");
15138 return -99;
15139 }
15140
15141 if (!vam->json_output)
15142 {
15143 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15144 }
15145
15146 M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
15147 mp->type = type;
15148 /* send it... */
15149 S;
15150
15151 /* Use a control ping for synchronization */
15152 {
15153 vl_api_control_ping_t *mp;
15154 M (CONTROL_PING, control_ping);
15155 S;
15156 }
15157 /* Wait for a reply... */
15158 W;
15159
15160 /* NOTREACHED */
15161 return 0;
15162}
15163
15164static int
15165api_netmap_create (vat_main_t * vam)
15166{
15167 unformat_input_t *i = vam->input;
15168 vl_api_netmap_create_t *mp;
15169 f64 timeout;
15170 u8 *if_name = 0;
15171 u8 hw_addr[6];
15172 u8 random_hw_addr = 1;
15173 u8 is_pipe = 0;
15174 u8 is_master = 0;
15175
15176 memset (hw_addr, 0, sizeof (hw_addr));
15177
15178 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15179 {
15180 if (unformat (i, "name %s", &if_name))
15181 vec_add1 (if_name, 0);
15182 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15183 random_hw_addr = 0;
15184 else if (unformat (i, "pipe"))
15185 is_pipe = 1;
15186 else if (unformat (i, "master"))
15187 is_master = 1;
15188 else if (unformat (i, "slave"))
15189 is_master = 0;
15190 else
15191 break;
15192 }
15193
15194 if (!vec_len (if_name))
15195 {
15196 errmsg ("interface name must be specified");
15197 return -99;
15198 }
15199
15200 if (vec_len (if_name) > 64)
15201 {
15202 errmsg ("interface name too long");
15203 return -99;
15204 }
15205
15206 M (NETMAP_CREATE, netmap_create);
15207
15208 clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15209 clib_memcpy (mp->hw_addr, hw_addr, 6);
15210 mp->use_random_hw_addr = random_hw_addr;
15211 mp->is_pipe = is_pipe;
15212 mp->is_master = is_master;
15213 vec_free (if_name);
15214
15215 S;
15216 W;
15217 /* NOTREACHED */
15218 return 0;
15219}
15220
15221static int
15222api_netmap_delete (vat_main_t * vam)
15223{
15224 unformat_input_t *i = vam->input;
15225 vl_api_netmap_delete_t *mp;
15226 f64 timeout;
15227 u8 *if_name = 0;
15228
15229 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15230 {
15231 if (unformat (i, "name %s", &if_name))
15232 vec_add1 (if_name, 0);
15233 else
15234 break;
15235 }
15236
15237 if (!vec_len (if_name))
15238 {
15239 errmsg ("interface name must be specified");
15240 return -99;
15241 }
15242
15243 if (vec_len (if_name) > 64)
15244 {
15245 errmsg ("interface name too long");
15246 return -99;
15247 }
15248
15249 M (NETMAP_DELETE, netmap_delete);
15250
15251 clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15252 vec_free (if_name);
15253
15254 S;
15255 W;
15256 /* NOTREACHED */
15257 return 0;
15258}
15259
15260static void vl_api_mpls_tunnel_details_t_handler
15261 (vl_api_mpls_tunnel_details_t * mp)
15262{
15263 vat_main_t *vam = &vat_main;
15264 i32 len = mp->mt_next_hop_n_labels;
15265 i32 i;
15266
15267 print (vam->ofp, "[%d]: via %U %d labels ",
15268 mp->tunnel_index,
15269 format_ip4_address, mp->mt_next_hop,
15270 ntohl (mp->mt_next_hop_sw_if_index));
15271 for (i = 0; i < len; i++)
15272 {
15273 print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15274 }
15275 print (vam->ofp, "");
15276}
15277
15278static void vl_api_mpls_tunnel_details_t_handler_json
15279 (vl_api_mpls_tunnel_details_t * mp)
15280{
15281 vat_main_t *vam = &vat_main;
15282 vat_json_node_t *node = NULL;
15283 struct in_addr ip4;
15284 i32 i;
15285 i32 len = mp->mt_next_hop_n_labels;
15286
15287 if (VAT_JSON_ARRAY != vam->json_tree.type)
15288 {
15289 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15290 vat_json_init_array (&vam->json_tree);
15291 }
15292 node = vat_json_array_add (&vam->json_tree);
15293
15294 vat_json_init_object (node);
15295 vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15296 clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15297 vat_json_object_add_ip4 (node, "next_hop", ip4);
15298 vat_json_object_add_uint (node, "next_hop_sw_if_index",
15299 ntohl (mp->mt_next_hop_sw_if_index));
15300 vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15301 vat_json_object_add_uint (node, "label_count", len);
15302 for (i = 0; i < len; i++)
15303 {
15304 vat_json_object_add_uint (node, "label",
15305 ntohl (mp->mt_next_hop_out_labels[i]));
15306 }
15307}
15308
15309static int
15310api_mpls_tunnel_dump (vat_main_t * vam)
15311{
15312 vl_api_mpls_tunnel_dump_t *mp;
15313 f64 timeout;
15314 i32 index = -1;
15315
15316 /* Parse args required to build the message */
15317 while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15318 {
15319 if (!unformat (vam->input, "tunnel_index %d", &index))
15320 {
15321 index = -1;
15322 break;
15323 }
15324 }
15325
15326 print (vam->ofp, " tunnel_index %d", index);
15327
15328 M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
15329 mp->tunnel_index = htonl (index);
15330 S;
15331
15332 /* Use a control ping for synchronization */
15333 {
15334 vl_api_control_ping_t *mp;
15335 M (CONTROL_PING, control_ping);
15336 S;
15337 }
15338 W;
15339}
15340
15341#define vl_api_mpls_fib_details_t_endian vl_noop_handler
15342#define vl_api_mpls_fib_details_t_print vl_noop_handler
15343
15344static void
15345vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15346{
15347 vat_main_t *vam = &vat_main;
15348 int count = ntohl (mp->count);
15349 vl_api_fib_path2_t *fp;
15350 int i;
15351
15352 print (vam->ofp,
15353 "table-id %d, label %u, ess_bit %u",
15354 ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15355 fp = mp->path;
15356 for (i = 0; i < count; i++)
15357 {
15358 if (fp->afi == IP46_TYPE_IP6)
15359 print (vam->ofp,
15360 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15361 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15362 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15363 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15364 format_ip6_address, fp->next_hop);
15365 else if (fp->afi == IP46_TYPE_IP4)
15366 print (vam->ofp,
15367 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15368 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15369 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15370 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15371 format_ip4_address, fp->next_hop);
15372 fp++;
15373 }
15374}
15375
15376static void vl_api_mpls_fib_details_t_handler_json
15377 (vl_api_mpls_fib_details_t * mp)
15378{
15379 vat_main_t *vam = &vat_main;
15380 int count = ntohl (mp->count);
15381 vat_json_node_t *node = NULL;
15382 struct in_addr ip4;
15383 struct in6_addr ip6;
15384 vl_api_fib_path2_t *fp;
15385 int i;
15386
15387 if (VAT_JSON_ARRAY != vam->json_tree.type)
15388 {
15389 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15390 vat_json_init_array (&vam->json_tree);
15391 }
15392 node = vat_json_array_add (&vam->json_tree);
15393
15394 vat_json_init_object (node);
15395 vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15396 vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15397 vat_json_object_add_uint (node, "label", ntohl (mp->label));
15398 vat_json_object_add_uint (node, "path_count", count);
15399 fp = mp->path;
15400 for (i = 0; i < count; i++)
15401 {
15402 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15403 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15404 vat_json_object_add_uint (node, "is_local", fp->is_local);
15405 vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15406 vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15407 vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15408 vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15409 if (fp->afi == IP46_TYPE_IP4)
15410 {
15411 clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15412 vat_json_object_add_ip4 (node, "next_hop", ip4);
15413 }
15414 else if (fp->afi == IP46_TYPE_IP6)
15415 {
15416 clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15417 vat_json_object_add_ip6 (node, "next_hop", ip6);
15418 }
15419 }
15420}
15421
15422static int
15423api_mpls_fib_dump (vat_main_t * vam)
15424{
15425 vl_api_mpls_fib_dump_t *mp;
15426 f64 timeout;
15427
15428 M (MPLS_FIB_DUMP, mpls_fib_dump);
15429 S;
15430
15431 /* Use a control ping for synchronization */
15432 {
15433 vl_api_control_ping_t *mp;
15434 M (CONTROL_PING, control_ping);
15435 S;
15436 }
15437 W;
15438}
15439
15440#define vl_api_ip_fib_details_t_endian vl_noop_handler
15441#define vl_api_ip_fib_details_t_print vl_noop_handler
15442
15443static void
15444vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15445{
15446 vat_main_t *vam = &vat_main;
15447 int count = ntohl (mp->count);
15448 vl_api_fib_path_t *fp;
15449 int i;
15450
15451 print (vam->ofp,
15452 "table-id %d, prefix %U/%d",
15453 ntohl (mp->table_id), format_ip4_address, mp->address,
15454 mp->address_length);
15455 fp = mp->path;
15456 for (i = 0; i < count; i++)
15457 {
15458 if (fp->afi == IP46_TYPE_IP6)
15459 print (vam->ofp,
15460 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15461 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15462 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15463 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15464 format_ip6_address, fp->next_hop);
15465 else if (fp->afi == IP46_TYPE_IP4)
15466 print (vam->ofp,
15467 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15468 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15469 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15470 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15471 format_ip4_address, fp->next_hop);
15472 fp++;
15473 }
15474}
15475
15476static void vl_api_ip_fib_details_t_handler_json
15477 (vl_api_ip_fib_details_t * mp)
15478{
15479 vat_main_t *vam = &vat_main;
15480 int count = ntohl (mp->count);
15481 vat_json_node_t *node = NULL;
15482 struct in_addr ip4;
15483 struct in6_addr ip6;
15484 vl_api_fib_path_t *fp;
15485 int i;
15486
15487 if (VAT_JSON_ARRAY != vam->json_tree.type)
15488 {
15489 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15490 vat_json_init_array (&vam->json_tree);
15491 }
15492 node = vat_json_array_add (&vam->json_tree);
15493
15494 vat_json_init_object (node);
15495 vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15496 clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15497 vat_json_object_add_ip4 (node, "prefix", ip4);
15498 vat_json_object_add_uint (node, "mask_length", mp->address_length);
15499 vat_json_object_add_uint (node, "path_count", count);
15500 fp = mp->path;
15501 for (i = 0; i < count; i++)
15502 {
15503 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15504 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15505 vat_json_object_add_uint (node, "is_local", fp->is_local);
15506 vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15507 vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15508 vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15509 vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15510 if (fp->afi == IP46_TYPE_IP4)
15511 {
15512 clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15513 vat_json_object_add_ip4 (node, "next_hop", ip4);
15514 }
15515 else if (fp->afi == IP46_TYPE_IP6)
15516 {
15517 clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15518 vat_json_object_add_ip6 (node, "next_hop", ip6);
15519 }
15520 }
15521}
15522
15523static int
15524api_ip_fib_dump (vat_main_t * vam)
15525{
15526 vl_api_ip_fib_dump_t *mp;
15527 f64 timeout;
15528
15529 M (IP_FIB_DUMP, ip_fib_dump);
15530 S;
15531
15532 /* Use a control ping for synchronization */
15533 {
15534 vl_api_control_ping_t *mp;
15535 M (CONTROL_PING, control_ping);
15536 S;
15537 }
15538 W;
15539}
15540
15541static void vl_api_ip_neighbor_details_t_handler
15542 (vl_api_ip_neighbor_details_t * mp)
15543{
15544 vat_main_t *vam = &vat_main;
15545
15546 print (vam->ofp, "%c %U %U",
15547 (mp->is_static) ? 'S' : 'D',
15548 format_ethernet_address, &mp->mac_address,
15549 (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15550 &mp->ip_address);
15551}
15552
15553static void vl_api_ip_neighbor_details_t_handler_json
15554 (vl_api_ip_neighbor_details_t * mp)
15555{
15556
15557 vat_main_t *vam = &vat_main;
15558 vat_json_node_t *node;
15559 struct in_addr ip4;
15560 struct in6_addr ip6;
15561
15562 if (VAT_JSON_ARRAY != vam->json_tree.type)
15563 {
15564 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15565 vat_json_init_array (&vam->json_tree);
15566 }
15567 node = vat_json_array_add (&vam->json_tree);
15568
15569 vat_json_init_object (node);
15570 vat_json_object_add_string_copy (node, "flag",
15571 (mp->is_static) ? (u8 *) "static" : (u8 *)
15572 "dynamic");
15573
15574 vat_json_object_add_string_copy (node, "link_layer",
15575 format (0, "%U", format_ethernet_address,
15576 &mp->mac_address));
15577
15578 if (mp->is_ipv6)
15579 {
15580 clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15581 vat_json_object_add_ip6 (node, "ip_address", ip6);
15582 }
15583 else
15584 {
15585 clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15586 vat_json_object_add_ip4 (node, "ip_address", ip4);
15587 }
15588}
15589
15590static int
15591api_ip_neighbor_dump (vat_main_t * vam)
15592{
15593 unformat_input_t *i = vam->input;
15594 vl_api_ip_neighbor_dump_t *mp;
15595 f64 timeout;
15596 u8 is_ipv6 = 0;
15597 u32 sw_if_index = ~0;
15598
15599 /* Parse args required to build the message */
15600 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15601 {
15602 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15603 ;
15604 else if (unformat (i, "sw_if_index %d", &sw_if_index))
15605 ;
15606 else if (unformat (i, "ip6"))
15607 is_ipv6 = 1;
15608 else
15609 break;
15610 }
15611
15612 if (sw_if_index == ~0)
15613 {
15614 errmsg ("missing interface name or sw_if_index");
15615 return -99;
15616 }
15617
15618 M (IP_NEIGHBOR_DUMP, ip_neighbor_dump);
15619 mp->is_ipv6 = (u8) is_ipv6;
15620 mp->sw_if_index = ntohl (sw_if_index);
15621 S;
15622
15623 /* Use a control ping for synchronization */
15624 {
15625 vl_api_control_ping_t *mp;
15626 M (CONTROL_PING, control_ping);
15627 S;
15628 }
15629 W;
15630}
15631
15632#define vl_api_ip6_fib_details_t_endian vl_noop_handler
15633#define vl_api_ip6_fib_details_t_print vl_noop_handler
15634
15635static void
15636vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15637{
15638 vat_main_t *vam = &vat_main;
15639 int count = ntohl (mp->count);
15640 vl_api_fib_path_t *fp;
15641 int i;
15642
15643 print (vam->ofp,
15644 "table-id %d, prefix %U/%d",
15645 ntohl (mp->table_id), format_ip6_address, mp->address,
15646 mp->address_length);
15647 fp = mp->path;
15648 for (i = 0; i < count; i++)
15649 {
15650 if (fp->afi == IP46_TYPE_IP6)
15651 print (vam->ofp,
15652 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15653 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15654 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15655 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15656 format_ip6_address, fp->next_hop);
15657 else if (fp->afi == IP46_TYPE_IP4)
15658 print (vam->ofp,
15659 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15660 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15661 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15662 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15663 format_ip4_address, fp->next_hop);
15664 fp++;
15665 }
15666}
15667
15668static void vl_api_ip6_fib_details_t_handler_json
15669 (vl_api_ip6_fib_details_t * mp)
15670{
15671 vat_main_t *vam = &vat_main;
15672 int count = ntohl (mp->count);
15673 vat_json_node_t *node = NULL;
15674 struct in_addr ip4;
15675 struct in6_addr ip6;
15676 vl_api_fib_path_t *fp;
15677 int i;
15678
15679 if (VAT_JSON_ARRAY != vam->json_tree.type)
15680 {
15681 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15682 vat_json_init_array (&vam->json_tree);
15683 }
15684 node = vat_json_array_add (&vam->json_tree);
15685
15686 vat_json_init_object (node);
15687 vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15688 clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15689 vat_json_object_add_ip6 (node, "prefix", ip6);
15690 vat_json_object_add_uint (node, "mask_length", mp->address_length);
15691 vat_json_object_add_uint (node, "path_count", count);
15692 fp = mp->path;
15693 for (i = 0; i < count; i++)
15694 {
15695 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15696 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15697 vat_json_object_add_uint (node, "is_local", fp->is_local);
15698 vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15699 vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15700 vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15701 vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15702 if (fp->afi == IP46_TYPE_IP4)
15703 {
15704 clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15705 vat_json_object_add_ip4 (node, "next_hop", ip4);
15706 }
15707 else if (fp->afi == IP46_TYPE_IP6)
15708 {
15709 clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15710 vat_json_object_add_ip6 (node, "next_hop", ip6);
15711 }
15712 }
15713}
15714
15715static int
15716api_ip6_fib_dump (vat_main_t * vam)
15717{
15718 vl_api_ip6_fib_dump_t *mp;
15719 f64 timeout;
15720
15721 M (IP6_FIB_DUMP, ip6_fib_dump);
15722 S;
15723
15724 /* Use a control ping for synchronization */
15725 {
15726 vl_api_control_ping_t *mp;
15727 M (CONTROL_PING, control_ping);
15728 S;
15729 }
15730 W;
15731}
15732
15733int
15734api_classify_table_ids (vat_main_t * vam)
15735{
15736 vl_api_classify_table_ids_t *mp;
15737 f64 timeout;
15738
15739 /* Construct the API message */
15740 M (CLASSIFY_TABLE_IDS, classify_table_ids);
15741 mp->context = 0;
15742
15743 S;
15744 W;
15745 /* NOTREACHED */
15746 return 0;
15747}
15748
15749int
15750api_classify_table_by_interface (vat_main_t * vam)
15751{
15752 unformat_input_t *input = vam->input;
15753 vl_api_classify_table_by_interface_t *mp;
15754 f64 timeout;
15755
15756 u32 sw_if_index = ~0;
15757 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15758 {
15759 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15760 ;
15761 else if (unformat (input, "sw_if_index %d", &sw_if_index))
15762 ;
15763 else
15764 break;
15765 }
15766 if (sw_if_index == ~0)
15767 {
15768 errmsg ("missing interface name or sw_if_index");
15769 return -99;
15770 }
15771
15772 /* Construct the API message */
15773 M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15774 mp->context = 0;
15775 mp->sw_if_index = ntohl (sw_if_index);
15776
15777 S;
15778 W;
15779 /* NOTREACHED */
15780 return 0;
15781}
15782
15783int
15784api_classify_table_info (vat_main_t * vam)
15785{
15786 unformat_input_t *input = vam->input;
15787 vl_api_classify_table_info_t *mp;
15788 f64 timeout;
15789
15790 u32 table_id = ~0;
15791 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15792 {
15793 if (unformat (input, "table_id %d", &table_id))
15794 ;
15795 else
15796 break;
15797 }
15798 if (table_id == ~0)
15799 {
15800 errmsg ("missing table id");
15801 return -99;
15802 }
15803
15804 /* Construct the API message */
15805 M (CLASSIFY_TABLE_INFO, classify_table_info);
15806 mp->context = 0;
15807 mp->table_id = ntohl (table_id);
15808
15809 S;
15810 W;
15811 /* NOTREACHED */
15812 return 0;
15813}
15814
15815int
15816api_classify_session_dump (vat_main_t * vam)
15817{
15818 unformat_input_t *input = vam->input;
15819 vl_api_classify_session_dump_t *mp;
15820 f64 timeout;
15821
15822 u32 table_id = ~0;
15823 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15824 {
15825 if (unformat (input, "table_id %d", &table_id))
15826 ;
15827 else
15828 break;
15829 }
15830 if (table_id == ~0)
15831 {
15832 errmsg ("missing table id");
15833 return -99;
15834 }
15835
15836 /* Construct the API message */
15837 M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15838 mp->context = 0;
15839 mp->table_id = ntohl (table_id);
15840 S;
15841
15842 /* Use a control ping for synchronization */
15843 {
15844 vl_api_control_ping_t *mp;
15845 M (CONTROL_PING, control_ping);
15846 S;
15847 }
15848 W;
15849 /* NOTREACHED */
15850 return 0;
15851}
15852
15853static void
15854vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15855{
15856 vat_main_t *vam = &vat_main;
15857
15858 print (vam->ofp, "collector_address %U, collector_port %d, "
15859 "src_address %U, vrf_id %d, path_mtu %u, "
15860 "template_interval %u, udp_checksum %d",
15861 format_ip4_address, mp->collector_address,
15862 ntohs (mp->collector_port),
15863 format_ip4_address, mp->src_address,
15864 ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15865 ntohl (mp->template_interval), mp->udp_checksum);
15866
15867 vam->retval = 0;
15868 vam->result_ready = 1;
15869}
15870
15871static void
15872 vl_api_ipfix_exporter_details_t_handler_json
15873 (vl_api_ipfix_exporter_details_t * mp)
15874{
15875 vat_main_t *vam = &vat_main;
15876 vat_json_node_t node;
15877 struct in_addr collector_address;
15878 struct in_addr src_address;
15879
15880 vat_json_init_object (&node);
15881 clib_memcpy (&collector_address, &mp->collector_address,
15882 sizeof (collector_address));
15883 vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15884 vat_json_object_add_uint (&node, "collector_port",
15885 ntohs (mp->collector_port));
15886 clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15887 vat_json_object_add_ip4 (&node, "src_address", src_address);
15888 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15889 vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15890 vat_json_object_add_uint (&node, "template_interval",
15891 ntohl (mp->template_interval));
15892 vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15893
15894 vat_json_print (vam->ofp, &node);
15895 vat_json_free (&node);
15896 vam->retval = 0;
15897 vam->result_ready = 1;
15898}
15899
15900int
15901api_ipfix_exporter_dump (vat_main_t * vam)
15902{
15903 vl_api_ipfix_exporter_dump_t *mp;
15904 f64 timeout;
15905
15906 /* Construct the API message */
15907 M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15908 mp->context = 0;
15909
15910 S;
15911 W;
15912 /* NOTREACHED */
15913 return 0;
15914}
15915
15916static int
15917api_ipfix_classify_stream_dump (vat_main_t * vam)
15918{
15919 vl_api_ipfix_classify_stream_dump_t *mp;
15920 f64 timeout;
15921
15922 /* Construct the API message */
15923 M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15924 mp->context = 0;
15925
15926 S;
15927 W;
15928 /* NOTREACHED */
15929 return 0;
15930}
15931
15932static void
15933 vl_api_ipfix_classify_stream_details_t_handler
15934 (vl_api_ipfix_classify_stream_details_t * mp)
15935{
15936 vat_main_t *vam = &vat_main;
15937 print (vam->ofp, "domain_id %d, src_port %d",
15938 ntohl (mp->domain_id), ntohs (mp->src_port));
15939 vam->retval = 0;
15940 vam->result_ready = 1;
15941}
15942
15943static void
15944 vl_api_ipfix_classify_stream_details_t_handler_json
15945 (vl_api_ipfix_classify_stream_details_t * mp)
15946{
15947 vat_main_t *vam = &vat_main;
15948 vat_json_node_t node;
15949
15950 vat_json_init_object (&node);
15951 vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15952 vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15953
15954 vat_json_print (vam->ofp, &node);
15955 vat_json_free (&node);
15956 vam->retval = 0;
15957 vam->result_ready = 1;
15958}
15959
15960static int
15961api_ipfix_classify_table_dump (vat_main_t * vam)
15962{
15963 vl_api_ipfix_classify_table_dump_t *mp;
15964 f64 timeout;
15965
15966 if (!vam->json_output)
15967 {
15968 print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
15969 "transport_protocol");
15970 }
15971
15972 /* Construct the API message */
15973 M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15974
15975 /* send it... */
15976 S;
15977
15978 /* Use a control ping for synchronization */
15979 {
15980 vl_api_control_ping_t *mp;
15981 M (CONTROL_PING, control_ping);
15982 S;
15983 }
15984 W;
15985}
15986
15987static void
15988 vl_api_ipfix_classify_table_details_t_handler
15989 (vl_api_ipfix_classify_table_details_t * mp)
15990{
15991 vat_main_t *vam = &vat_main;
15992 print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
15993 mp->transport_protocol);
15994}
15995
15996static void
15997 vl_api_ipfix_classify_table_details_t_handler_json
15998 (vl_api_ipfix_classify_table_details_t * mp)
15999{
16000 vat_json_node_t *node = NULL;
16001 vat_main_t *vam = &vat_main;
16002
16003 if (VAT_JSON_ARRAY != vam->json_tree.type)
16004 {
16005 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16006 vat_json_init_array (&vam->json_tree);
16007 }
16008
16009 node = vat_json_array_add (&vam->json_tree);
16010 vat_json_init_object (node);
16011
16012 vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16013 vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16014 vat_json_object_add_uint (node, "transport_protocol",
16015 mp->transport_protocol);
16016}
16017
16018static int
16019api_sw_interface_span_enable_disable (vat_main_t * vam)
16020{
16021 unformat_input_t *i = vam->input;
16022 vl_api_sw_interface_span_enable_disable_t *mp;
16023 f64 timeout;
16024 u32 src_sw_if_index = ~0;
16025 u32 dst_sw_if_index = ~0;
16026 u8 state = 3;
16027
16028 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16029 {
16030 if (unformat
16031 (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16032 ;
16033 else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16034 ;
16035 else
16036 if (unformat
16037 (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16038 ;
16039 else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16040 ;
16041 else if (unformat (i, "disable"))
16042 state = 0;
16043 else if (unformat (i, "rx"))
16044 state = 1;
16045 else if (unformat (i, "tx"))
16046 state = 2;
16047 else if (unformat (i, "both"))
16048 state = 3;
16049 else
16050 break;
16051 }
16052
16053 M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
16054
16055 mp->sw_if_index_from = htonl (src_sw_if_index);
16056 mp->sw_if_index_to = htonl (dst_sw_if_index);
16057 mp->state = state;
16058
16059 S;
16060 W;
16061 /* NOTREACHED */
16062 return 0;
16063}
16064
16065static void
16066vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16067 * mp)
16068{
16069 vat_main_t *vam = &vat_main;
16070 u8 *sw_if_from_name = 0;
16071 u8 *sw_if_to_name = 0;
16072 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16073 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16074 char *states[] = { "none", "rx", "tx", "both" };
16075 hash_pair_t *p;
16076
16077 /* *INDENT-OFF* */
16078 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16079 ({
16080 if ((u32) p->value[0] == sw_if_index_from)
16081 {
16082 sw_if_from_name = (u8 *)(p->key);
16083 if (sw_if_to_name)
16084 break;
16085 }
16086 if ((u32) p->value[0] == sw_if_index_to)
16087 {
16088 sw_if_to_name = (u8 *)(p->key);
16089 if (sw_if_from_name)
16090 break;
16091 }
16092 }));
16093 /* *INDENT-ON* */
16094 print (vam->ofp, "%20s => %20s (%s)",
16095 sw_if_from_name, sw_if_to_name, states[mp->state]);
16096}
16097
16098static void
16099 vl_api_sw_interface_span_details_t_handler_json
16100 (vl_api_sw_interface_span_details_t * mp)
16101{
16102 vat_main_t *vam = &vat_main;
16103 vat_json_node_t *node = NULL;
16104 u8 *sw_if_from_name = 0;
16105 u8 *sw_if_to_name = 0;
16106 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16107 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16108 hash_pair_t *p;
16109
16110 /* *INDENT-OFF* */
16111 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16112 ({
16113 if ((u32) p->value[0] == sw_if_index_from)
16114 {
16115 sw_if_from_name = (u8 *)(p->key);
16116 if (sw_if_to_name)
16117 break;
16118 }
16119 if ((u32) p->value[0] == sw_if_index_to)
16120 {
16121 sw_if_to_name = (u8 *)(p->key);
16122 if (sw_if_from_name)
16123 break;
16124 }
16125 }));
16126 /* *INDENT-ON* */
16127
16128 if (VAT_JSON_ARRAY != vam->json_tree.type)
16129 {
16130 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16131 vat_json_init_array (&vam->json_tree);
16132 }
16133 node = vat_json_array_add (&vam->json_tree);
16134
16135 vat_json_init_object (node);
16136 vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16137 vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16138 vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16139 vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16140 vat_json_object_add_uint (node, "state", mp->state);
16141}
16142
16143static int
16144api_sw_interface_span_dump (vat_main_t * vam)
16145{
16146 vl_api_sw_interface_span_dump_t *mp;
16147 f64 timeout;
16148
16149 M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
16150 S;
16151
16152 /* Use a control ping for synchronization */
16153 {
16154 vl_api_control_ping_t *mp;
16155 M (CONTROL_PING, control_ping);
16156 S;
16157 }
16158 W;
16159}
16160
16161int
16162api_pg_create_interface (vat_main_t * vam)
16163{
16164 unformat_input_t *input = vam->input;
16165 vl_api_pg_create_interface_t *mp;
16166 f64 timeout;
16167
16168 u32 if_id = ~0;
16169 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16170 {
16171 if (unformat (input, "if_id %d", &if_id))
16172 ;
16173 else
16174 break;
16175 }
16176 if (if_id == ~0)
16177 {
16178 errmsg ("missing pg interface index");
16179 return -99;
16180 }
16181
16182 /* Construct the API message */
16183 M (PG_CREATE_INTERFACE, pg_create_interface);
16184 mp->context = 0;
16185 mp->interface_id = ntohl (if_id);
16186
16187 S;
16188 W;
16189 /* NOTREACHED */
16190 return 0;
16191}
16192
16193int
16194api_pg_capture (vat_main_t * vam)
16195{
16196 unformat_input_t *input = vam->input;
16197 vl_api_pg_capture_t *mp;
16198 f64 timeout;
16199
16200 u32 if_id = ~0;
16201 u8 enable = 1;
16202 u32 count = 1;
16203 u8 pcap_file_set = 0;
16204 u8 *pcap_file = 0;
16205 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16206 {
16207 if (unformat (input, "if_id %d", &if_id))
16208 ;
16209 else if (unformat (input, "pcap %s", &pcap_file))
16210 pcap_file_set = 1;
16211 else if (unformat (input, "count %d", &count))
16212 ;
16213 else if (unformat (input, "disable"))
16214 enable = 0;
16215 else
16216 break;
16217 }
16218 if (if_id == ~0)
16219 {
16220 errmsg ("missing pg interface index");
16221 return -99;
16222 }
16223 if (pcap_file_set > 0)
16224 {
16225 if (vec_len (pcap_file) > 255)
16226 {
16227 errmsg ("pcap file name is too long");
16228 return -99;
16229 }
16230 }
16231
16232 u32 name_len = vec_len (pcap_file);
16233 /* Construct the API message */
16234 M (PG_CAPTURE, pg_capture);
16235 mp->context = 0;
16236 mp->interface_id = ntohl (if_id);
16237 mp->is_enabled = enable;
16238 mp->count = ntohl (count);
16239 mp->pcap_name_length = ntohl (name_len);
16240 if (pcap_file_set != 0)
16241 {
16242 clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16243 }
16244 vec_free (pcap_file);
16245
16246 S;
16247 W;
16248 /* NOTREACHED */
16249 return 0;
16250}
16251
16252int
16253api_pg_enable_disable (vat_main_t * vam)
16254{
16255 unformat_input_t *input = vam->input;
16256 vl_api_pg_enable_disable_t *mp;
16257 f64 timeout;
16258
16259 u8 enable = 1;
16260 u8 stream_name_set = 0;
16261 u8 *stream_name = 0;
16262 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16263 {
16264 if (unformat (input, "stream %s", &stream_name))
16265 stream_name_set = 1;
16266 else if (unformat (input, "disable"))
16267 enable = 0;
16268 else
16269 break;
16270 }
16271
16272 if (stream_name_set > 0)
16273 {
16274 if (vec_len (stream_name) > 255)
16275 {
16276 errmsg ("stream name too long");
16277 return -99;
16278 }
16279 }
16280
16281 u32 name_len = vec_len (stream_name);
16282 /* Construct the API message */
16283 M (PG_ENABLE_DISABLE, pg_enable_disable);
16284 mp->context = 0;
16285 mp->is_enabled = enable;
16286 if (stream_name_set != 0)
16287 {
16288 mp->stream_name_length = ntohl (name_len);
16289 clib_memcpy (mp->stream_name, stream_name, name_len);
16290 }
16291 vec_free (stream_name);
16292
16293 S;
16294 W;
16295 /* NOTREACHED */
16296 return 0;
16297}
16298
16299int
16300api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16301{
16302 unformat_input_t *input = vam->input;
16303 vl_api_ip_source_and_port_range_check_add_del_t *mp;
16304 f64 timeout;
16305
16306 u16 *low_ports = 0;
16307 u16 *high_ports = 0;
16308 u16 this_low;
16309 u16 this_hi;
16310 ip4_address_t ip4_addr;
16311 ip6_address_t ip6_addr;
16312 u32 length;
16313 u32 tmp, tmp2;
16314 u8 prefix_set = 0;
16315 u32 vrf_id = ~0;
16316 u8 is_add = 1;
16317 u8 is_ipv6 = 0;
16318
16319 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16320 {
16321 if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16322 {
16323 prefix_set = 1;
16324 }
16325 else
16326 if (unformat
16327 (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16328 {
16329 prefix_set = 1;
16330 is_ipv6 = 1;
16331 }
16332 else if (unformat (input, "vrf %d", &vrf_id))
16333 ;
16334 else if (unformat (input, "del"))
16335 is_add = 0;
16336 else if (unformat (input, "port %d", &tmp))
16337 {
16338 if (tmp == 0 || tmp > 65535)
16339 {
16340 errmsg ("port %d out of range", tmp);
16341 return -99;
16342 }
16343 this_low = tmp;
16344 this_hi = this_low + 1;
16345 vec_add1 (low_ports, this_low);
16346 vec_add1 (high_ports, this_hi);
16347 }
16348 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16349 {
16350 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16351 {
16352 errmsg ("incorrect range parameters");
16353 return -99;
16354 }
16355 this_low = tmp;
16356 /* Note: in debug CLI +1 is added to high before
16357 passing to real fn that does "the work"
16358 (ip_source_and_port_range_check_add_del).
16359 This fn is a wrapper around the binary API fn a
16360 control plane will call, which expects this increment
16361 to have occurred. Hence letting the binary API control
16362 plane fn do the increment for consistency between VAT
16363 and other control planes.
16364 */
16365 this_hi = tmp2;
16366 vec_add1 (low_ports, this_low);
16367 vec_add1 (high_ports, this_hi);
16368 }
16369 else
16370 break;
16371 }
16372
16373 if (prefix_set == 0)
16374 {
16375 errmsg ("<address>/<mask> not specified");
16376 return -99;
16377 }
16378
16379 if (vrf_id == ~0)
16380 {
16381 errmsg ("VRF ID required, not specified");
16382 return -99;
16383 }
16384
16385 if (vrf_id == 0)
16386 {
16387 errmsg
16388 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16389 return -99;
16390 }
16391
16392 if (vec_len (low_ports) == 0)
16393 {
16394 errmsg ("At least one port or port range required");
16395 return -99;
16396 }
16397
16398 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
16399 ip_source_and_port_range_check_add_del);
16400
16401 mp->is_add = is_add;
16402
16403 if (is_ipv6)
16404 {
16405 mp->is_ipv6 = 1;
16406 clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16407 }
16408 else
16409 {
16410 mp->is_ipv6 = 0;
16411 clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16412 }
16413
16414 mp->mask_length = length;
16415 mp->number_of_ranges = vec_len (low_ports);
16416
16417 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16418 vec_free (low_ports);
16419
16420 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16421 vec_free (high_ports);
16422
16423 mp->vrf_id = ntohl (vrf_id);
16424
16425 S;
16426 W;
16427 /* NOTREACHED */
16428 return 0;
16429}
16430
16431int
16432api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16433{
16434 unformat_input_t *input = vam->input;
16435 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16436 f64 timeout;
16437 u32 sw_if_index = ~0;
16438 int vrf_set = 0;
16439 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16440 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16441 u8 is_add = 1;
16442
16443 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16444 {
16445 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16446 ;
16447 else if (unformat (input, "sw_if_index %d", &sw_if_index))
16448 ;
16449 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16450 vrf_set = 1;
16451 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16452 vrf_set = 1;
16453 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16454 vrf_set = 1;
16455 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16456 vrf_set = 1;
16457 else if (unformat (input, "del"))
16458 is_add = 0;
16459 else
16460 break;
16461 }
16462
16463 if (sw_if_index == ~0)
16464 {
16465 errmsg ("Interface required but not specified");
16466 return -99;
16467 }
16468
16469 if (vrf_set == 0)
16470 {
16471 errmsg ("VRF ID required but not specified");
16472 return -99;
16473 }
16474
16475 if (tcp_out_vrf_id == 0
16476 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16477 {
16478 errmsg
16479 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16480 return -99;
16481 }
16482
16483 /* Construct the API message */
16484 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
16485 ip_source_and_port_range_check_interface_add_del);
16486
16487 mp->sw_if_index = ntohl (sw_if_index);
16488 mp->is_add = is_add;
16489 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16490 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16491 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16492 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16493
16494 /* send it... */
16495 S;
16496
16497 /* Wait for a reply... */
16498 W;
16499}
16500
16501static int
16502api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16503{
16504 unformat_input_t *i = vam->input;
16505 vl_api_ipsec_gre_add_del_tunnel_t *mp;
16506 f64 timeout;
16507 u32 local_sa_id = 0;
16508 u32 remote_sa_id = 0;
16509 ip4_address_t src_address;
16510 ip4_address_t dst_address;
16511 u8 is_add = 1;
16512
16513 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16514 {
16515 if (unformat (i, "local_sa %d", &local_sa_id))
16516 ;
16517 else if (unformat (i, "remote_sa %d", &remote_sa_id))
16518 ;
16519 else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16520 ;
16521 else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16522 ;
16523 else if (unformat (i, "del"))
16524 is_add = 0;
16525 else
16526 {
16527 clib_warning ("parse error '%U'", format_unformat_error, i);
16528 return -99;
16529 }
16530 }
16531
16532 M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
16533
16534 mp->local_sa_id = ntohl (local_sa_id);
16535 mp->remote_sa_id = ntohl (remote_sa_id);
16536 clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16537 clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16538 mp->is_add = is_add;
16539
16540 S;
16541 W;
16542 /* NOTREACHED */
16543 return 0;
16544}
16545
16546static int
16547api_punt (vat_main_t * vam)
16548{
16549 unformat_input_t *i = vam->input;
16550 vl_api_punt_t *mp;
16551 f64 timeout;
16552 u32 ipv = ~0;
16553 u32 protocol = ~0;
16554 u32 port = ~0;
16555 int is_add = 1;
16556
16557 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16558 {
16559 if (unformat (i, "ip %d", &ipv))
16560 ;
16561 else if (unformat (i, "protocol %d", &protocol))
16562 ;
16563 else if (unformat (i, "port %d", &port))
16564 ;
16565 else if (unformat (i, "del"))
16566 is_add = 0;
16567 else
16568 {
16569 clib_warning ("parse error '%U'", format_unformat_error, i);
16570 return -99;
16571 }
16572 }
16573
16574 M (PUNT, punt);
16575
16576 mp->is_add = (u8) is_add;
16577 mp->ipv = (u8) ipv;
16578 mp->l4_protocol = (u8) protocol;
16579 mp->l4_port = htons ((u16) port);
16580
16581 S;
16582 W;
16583 /* NOTREACHED */
16584 return 0;
16585}
16586
16587static void vl_api_ipsec_gre_tunnel_details_t_handler
16588 (vl_api_ipsec_gre_tunnel_details_t * mp)
16589{
16590 vat_main_t *vam = &vat_main;
16591
16592 print (vam->ofp, "%11d%15U%15U%14d%14d",
16593 ntohl (mp->sw_if_index),
16594 format_ip4_address, &mp->src_address,
16595 format_ip4_address, &mp->dst_address,
16596 ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16597}
16598
16599static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16600 (vl_api_ipsec_gre_tunnel_details_t * mp)
16601{
16602 vat_main_t *vam = &vat_main;
16603 vat_json_node_t *node = NULL;
16604 struct in_addr ip4;
16605
16606 if (VAT_JSON_ARRAY != vam->json_tree.type)
16607 {
16608 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16609 vat_json_init_array (&vam->json_tree);
16610 }
16611 node = vat_json_array_add (&vam->json_tree);
16612
16613 vat_json_init_object (node);
16614 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16615 clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16616 vat_json_object_add_ip4 (node, "src_address", ip4);
16617 clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16618 vat_json_object_add_ip4 (node, "dst_address", ip4);
16619 vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16620 vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16621}
16622
16623static int
16624api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16625{
16626 unformat_input_t *i = vam->input;
16627 vl_api_ipsec_gre_tunnel_dump_t *mp;
16628 f64 timeout;
16629 u32 sw_if_index;
16630 u8 sw_if_index_set = 0;
16631
16632 /* Parse args required to build the message */
16633 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16634 {
16635 if (unformat (i, "sw_if_index %d", &sw_if_index))
16636 sw_if_index_set = 1;
16637 else
16638 break;
16639 }
16640
16641 if (sw_if_index_set == 0)
16642 {
16643 sw_if_index = ~0;
16644 }
16645
16646 if (!vam->json_output)
16647 {
16648 print (vam->ofp, "%11s%15s%15s%14s%14s",
16649 "sw_if_index", "src_address", "dst_address",
16650 "local_sa_id", "remote_sa_id");
16651 }
16652
16653 /* Get list of gre-tunnel interfaces */
16654 M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16655
16656 mp->sw_if_index = htonl (sw_if_index);
16657
16658 S;
16659
16660 /* Use a control ping for synchronization */
16661 {
16662 vl_api_control_ping_t *mp;
16663 M (CONTROL_PING, control_ping);
16664 S;
16665 }
16666 W;
16667}
16668
16669static int
16670api_delete_subif (vat_main_t * vam)
16671{
16672 unformat_input_t *i = vam->input;
16673 vl_api_delete_subif_t *mp;
16674 f64 timeout;
16675 u32 sw_if_index = ~0;
16676
16677 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16678 {
16679 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16680 ;
16681 if (unformat (i, "sw_if_index %d", &sw_if_index))
16682 ;
16683 else
16684 break;
16685 }
16686
16687 if (sw_if_index == ~0)
16688 {
16689 errmsg ("missing sw_if_index");
16690 return -99;
16691 }
16692
16693 /* Construct the API message */
16694 M (DELETE_SUBIF, delete_subif);
16695 mp->sw_if_index = ntohl (sw_if_index);
16696
16697 S;
16698 W;
16699}
16700
16701#define foreach_pbb_vtr_op \
16702_("disable", L2_VTR_DISABLED) \
16703_("pop", L2_VTR_POP_2) \
16704_("push", L2_VTR_PUSH_2)
16705
16706static int
16707api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16708{
16709 unformat_input_t *i = vam->input;
16710 vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16711 f64 timeout;
16712 u32 sw_if_index = ~0, vtr_op = ~0;
16713 u16 outer_tag = ~0;
16714 u8 dmac[6], smac[6];
16715 u8 dmac_set = 0, smac_set = 0;
16716 u16 vlanid = 0;
16717 u32 sid = ~0;
16718 u32 tmp;
16719
16720 /* Shut up coverity */
16721 memset (dmac, 0, sizeof (dmac));
16722 memset (smac, 0, sizeof (smac));
16723
16724 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16725 {
16726 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16727 ;
16728 else if (unformat (i, "sw_if_index %d", &sw_if_index))
16729 ;
16730 else if (unformat (i, "vtr_op %d", &vtr_op))
16731 ;
16732#define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16733 foreach_pbb_vtr_op
16734#undef _
16735 else if (unformat (i, "translate_pbb_stag"))
16736 {
16737 if (unformat (i, "%d", &tmp))
16738 {
16739 vtr_op = L2_VTR_TRANSLATE_2_1;
16740 outer_tag = tmp;
16741 }
16742 else
16743 {
16744 errmsg
16745 ("translate_pbb_stag operation requires outer tag definition");
16746 return -99;
16747 }
16748 }
16749 else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16750 dmac_set++;
16751 else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16752 smac_set++;
16753 else if (unformat (i, "sid %d", &sid))
16754 ;
16755 else if (unformat (i, "vlanid %d", &tmp))
16756 vlanid = tmp;
16757 else
16758 {
16759 clib_warning ("parse error '%U'", format_unformat_error, i);
16760 return -99;
16761 }
16762 }
16763
16764 if ((sw_if_index == ~0) || (vtr_op == ~0))
16765 {
16766 errmsg ("missing sw_if_index or vtr operation");
16767 return -99;
16768 }
16769 if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16770 && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16771 {
16772 errmsg
16773 ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
16774 return -99;
16775 }
16776
16777 M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16778 mp->sw_if_index = ntohl (sw_if_index);
16779 mp->vtr_op = ntohl (vtr_op);
16780 mp->outer_tag = ntohs (outer_tag);
16781 clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16782 clib_memcpy (mp->b_smac, smac, sizeof (smac));
16783 mp->b_vlanid = ntohs (vlanid);
16784 mp->i_sid = ntohl (sid);
16785
16786 S;
16787 W;
16788 /* NOTREACHED */
16789 return 0;
16790}
16791
16792static int
16793api_flow_classify_set_interface (vat_main_t * vam)
16794{
16795 unformat_input_t *i = vam->input;
16796 vl_api_flow_classify_set_interface_t *mp;
16797 f64 timeout;
16798 u32 sw_if_index;
16799 int sw_if_index_set;
16800 u32 ip4_table_index = ~0;
16801 u32 ip6_table_index = ~0;
16802 u8 is_add = 1;
16803
16804 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16805 {
16806 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16807 sw_if_index_set = 1;
16808 else if (unformat (i, "sw_if_index %d", &sw_if_index))
16809 sw_if_index_set = 1;
16810 else if (unformat (i, "del"))
16811 is_add = 0;
16812 else if (unformat (i, "ip4-table %d", &ip4_table_index))
16813 ;
16814 else if (unformat (i, "ip6-table %d", &ip6_table_index))
16815 ;
16816 else
16817 {
16818 clib_warning ("parse error '%U'", format_unformat_error, i);
16819 return -99;
16820 }
16821 }
16822
16823 if (sw_if_index_set == 0)
16824 {
16825 errmsg ("missing interface name or sw_if_index");
16826 return -99;
16827 }
16828
16829 M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16830
16831 mp->sw_if_index = ntohl (sw_if_index);
16832 mp->ip4_table_index = ntohl (ip4_table_index);
16833 mp->ip6_table_index = ntohl (ip6_table_index);
16834 mp->is_add = is_add;
16835
16836 S;
16837 W;
16838 /* NOTREACHED */
16839 return 0;
16840}
16841
16842static int
16843api_flow_classify_dump (vat_main_t * vam)
16844{
16845 unformat_input_t *i = vam->input;
16846 vl_api_flow_classify_dump_t *mp;
16847 f64 timeout = ~0;
16848 u8 type = FLOW_CLASSIFY_N_TABLES;
16849
16850 if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16851 ;
16852 else
16853 {
16854 errmsg ("classify table type must be specified");
16855 return -99;
16856 }
16857
16858 if (!vam->json_output)
16859 {
16860 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16861 }
16862
16863 M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16864 mp->type = type;
16865 /* send it... */
16866 S;
16867
16868 /* Use a control ping for synchronization */
16869 {
16870 vl_api_control_ping_t *mp;
16871 M (CONTROL_PING, control_ping);
16872 S;
16873 }
16874 /* Wait for a reply... */
16875 W;
16876
16877 /* NOTREACHED */
16878 return 0;
16879}
16880
16881static int
16882api_feature_enable_disable (vat_main_t * vam)
16883{
16884 unformat_input_t *i = vam->input;
16885 vl_api_feature_enable_disable_t *mp;
16886 f64 timeout;
16887 u8 *arc_name = 0;
16888 u8 *feature_name = 0;
16889 u32 sw_if_index = ~0;
16890 u8 enable = 1;
16891
16892 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16893 {
16894 if (unformat (i, "arc_name %s", &arc_name))
16895 ;
16896 else if (unformat (i, "feature_name %s", &feature_name))
16897 ;
16898 else
16899 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16900 ;
16901 else if (unformat (i, "sw_if_index %d", &sw_if_index))
16902 ;
16903 else if (unformat (i, "disable"))
16904 enable = 0;
16905 else
16906 break;
16907 }
16908
16909 if (arc_name == 0)
16910 {
16911 errmsg ("missing arc name");
16912 return -99;
16913 }
16914 if (vec_len (arc_name) > 63)
16915 {
16916 errmsg ("arc name too long");
16917 }
16918
16919 if (feature_name == 0)
16920 {
16921 errmsg ("missing feature name");
16922 return -99;
16923 }
16924 if (vec_len (feature_name) > 63)
16925 {
16926 errmsg ("feature name too long");
16927 }
16928
16929 if (sw_if_index == ~0)
16930 {
16931 errmsg ("missing interface name or sw_if_index");
16932 return -99;
16933 }
16934
16935 /* Construct the API message */
16936 M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16937 mp->sw_if_index = ntohl (sw_if_index);
16938 mp->enable = enable;
16939 clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16940 clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16941 vec_free (arc_name);
16942 vec_free (feature_name);
16943
16944 S;
16945 W;
16946}
16947
16948static int
16949api_sw_interface_tag_add_del (vat_main_t * vam)
16950{
16951 unformat_input_t *i = vam->input;
16952 vl_api_sw_interface_tag_add_del_t *mp;
16953 f64 timeout;
16954 u32 sw_if_index = ~0;
16955 u8 *tag = 0;
16956 u8 enable = 1;
16957
16958 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16959 {
16960 if (unformat (i, "tag %s", &tag))
16961 ;
16962 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16963 ;
16964 else if (unformat (i, "sw_if_index %d", &sw_if_index))
16965 ;
16966 else if (unformat (i, "del"))
16967 enable = 0;
16968 else
16969 break;
16970 }
16971
16972 if (sw_if_index == ~0)
16973 {
16974 errmsg ("missing interface name or sw_if_index");
16975 return -99;
16976 }
16977
16978 if (enable && (tag == 0))
16979 {
16980 errmsg ("no tag specified");
16981 return -99;
16982 }
16983
16984 /* Construct the API message */
16985 M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
16986 mp->sw_if_index = ntohl (sw_if_index);
16987 mp->is_add = enable;
16988 if (enable)
16989 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
16990 vec_free (tag);
16991
16992 S;
16993 W;
16994}
16995
16996static void vl_api_l2_xconnect_details_t_handler
16997 (vl_api_l2_xconnect_details_t * mp)
16998{
16999 vat_main_t *vam = &vat_main;
17000
17001 print (vam->ofp, "%15d%15d",
17002 ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17003}
17004
17005static void vl_api_l2_xconnect_details_t_handler_json
17006 (vl_api_l2_xconnect_details_t * mp)
17007{
17008 vat_main_t *vam = &vat_main;
17009 vat_json_node_t *node = NULL;
17010
17011 if (VAT_JSON_ARRAY != vam->json_tree.type)
17012 {
17013 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17014 vat_json_init_array (&vam->json_tree);
17015 }
17016 node = vat_json_array_add (&vam->json_tree);
17017
17018 vat_json_init_object (node);
17019 vat_json_object_add_uint (node, "rx_sw_if_index",
17020 ntohl (mp->rx_sw_if_index));
17021 vat_json_object_add_uint (node, "tx_sw_if_index",
17022 ntohl (mp->tx_sw_if_index));
17023}
17024
17025static int
17026api_l2_xconnect_dump (vat_main_t * vam)
17027{
17028 vl_api_l2_xconnect_dump_t *mp;
17029 f64 timeout;
17030
17031 if (!vam->json_output)
17032 {
17033 print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17034 }
17035
17036 M (L2_XCONNECT_DUMP, l2_xconnect_dump);
17037
17038 S;
17039
17040 /* Use a control ping for synchronization */
17041 {
17042 vl_api_control_ping_t *mp;
17043 M (CONTROL_PING, control_ping);
17044 S;
17045 }
17046 W;
17047}
17048
17049static int
17050api_sw_interface_set_mtu (vat_main_t * vam)
17051{
17052 unformat_input_t *i = vam->input;
17053 vl_api_sw_interface_set_mtu_t *mp;
17054 f64 timeout;
17055 u32 sw_if_index = ~0;
17056 u32 mtu = 0;
17057
17058 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17059 {
17060 if (unformat (i, "mtu %d", &mtu))
17061 ;
17062 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17063 ;
17064 else if (unformat (i, "sw_if_index %d", &sw_if_index))
17065 ;
17066 else
17067 break;
17068 }
17069
17070 if (sw_if_index == ~0)
17071 {
17072 errmsg ("missing interface name or sw_if_index");
17073 return -99;
17074 }
17075
17076 if (mtu == 0)
17077 {
17078 errmsg ("no mtu specified");
17079 return -99;
17080 }
17081
17082 /* Construct the API message */
17083 M (SW_INTERFACE_SET_MTU, sw_interface_set_mtu);
17084 mp->sw_if_index = ntohl (sw_if_index);
17085 mp->mtu = ntohs ((u16) mtu);
17086
17087 S;
17088 W;
17089}
17090
17091
17092static int
17093q_or_quit (vat_main_t * vam)
17094{
17095 longjmp (vam->jump_buf, 1);
17096 return 0; /* not so much */
17097}
17098
17099static int
17100q (vat_main_t * vam)
17101{
17102 return q_or_quit (vam);
17103}
17104
17105static int
17106quit (vat_main_t * vam)
17107{
17108 return q_or_quit (vam);
17109}
17110
17111static int
17112comment (vat_main_t * vam)
17113{
17114 return 0;
17115}
17116
17117static int
17118cmd_cmp (void *a1, void *a2)
17119{
17120 u8 **c1 = a1;
17121 u8 **c2 = a2;
17122
17123 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17124}
17125
17126static int
17127help (vat_main_t * vam)
17128{
17129 u8 **cmds = 0;
17130 u8 *name = 0;
17131 hash_pair_t *p;
17132 unformat_input_t *i = vam->input;
17133 int j;
17134
17135 if (unformat (i, "%s", &name))
17136 {
17137 uword *hs;
17138
17139 vec_add1 (name, 0);
17140
17141 hs = hash_get_mem (vam->help_by_name, name);
17142 if (hs)
17143 print (vam->ofp, "usage: %s %s", name, hs[0]);
17144 else
17145 print (vam->ofp, "No such msg / command '%s'", name);
17146 vec_free (name);
17147 return 0;
17148 }
17149
17150 print (vam->ofp, "Help is available for the following:");
17151
17152 /* *INDENT-OFF* */
17153 hash_foreach_pair (p, vam->function_by_name,
17154 ({
17155 vec_add1 (cmds, (u8 *)(p->key));
17156 }));
17157 /* *INDENT-ON* */
17158
17159 vec_sort_with_function (cmds, cmd_cmp);
17160
17161 for (j = 0; j < vec_len (cmds); j++)
17162 print (vam->ofp, "%s", cmds[j]);
17163
17164 vec_free (cmds);
17165 return 0;
17166}
17167
17168static int
17169set (vat_main_t * vam)
17170{
17171 u8 *name = 0, *value = 0;
17172 unformat_input_t *i = vam->input;
17173
17174 if (unformat (i, "%s", &name))
17175 {
17176 /* The input buffer is a vector, not a string. */
17177 value = vec_dup (i->buffer);
17178 vec_delete (value, i->index, 0);
17179 /* Almost certainly has a trailing newline */
17180 if (value[vec_len (value) - 1] == '\n')
17181 value[vec_len (value) - 1] = 0;
17182 /* Make sure it's a proper string, one way or the other */
17183 vec_add1 (value, 0);
17184 (void) clib_macro_set_value (&vam->macro_main,
17185 (char *) name, (char *) value);
17186 }
17187 else
17188 errmsg ("usage: set <name> <value>");
17189
17190 vec_free (name);
17191 vec_free (value);
17192 return 0;
17193}
17194
17195static int
17196unset (vat_main_t * vam)
17197{
17198 u8 *name = 0;
17199
17200 if (unformat (vam->input, "%s", &name))
17201 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17202 errmsg ("unset: %s wasn't set", name);
17203 vec_free (name);
17204 return 0;
17205}
17206
17207typedef struct
17208{
17209 u8 *name;
17210 u8 *value;
17211} macro_sort_t;
17212
17213
17214static int
17215macro_sort_cmp (void *a1, void *a2)
17216{
17217 macro_sort_t *s1 = a1;
17218 macro_sort_t *s2 = a2;
17219
17220 return strcmp ((char *) (s1->name), (char *) (s2->name));
17221}
17222
17223static int
17224dump_macro_table (vat_main_t * vam)
17225{
17226 macro_sort_t *sort_me = 0, *sm;
17227 int i;
17228 hash_pair_t *p;
17229
17230 /* *INDENT-OFF* */
17231 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17232 ({
17233 vec_add2 (sort_me, sm, 1);
17234 sm->name = (u8 *)(p->key);
17235 sm->value = (u8 *) (p->value[0]);
17236 }));
17237 /* *INDENT-ON* */
17238
17239 vec_sort_with_function (sort_me, macro_sort_cmp);
17240
17241 if (vec_len (sort_me))
17242 print (vam->ofp, "%-15s%s", "Name", "Value");
17243 else
17244 print (vam->ofp, "The macro table is empty...");
17245
17246 for (i = 0; i < vec_len (sort_me); i++)
17247 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17248 return 0;
17249}
17250
17251static int
17252dump_node_table (vat_main_t * vam)
17253{
17254 int i, j;
17255 vlib_node_t *node, *next_node;
17256
17257 if (vec_len (vam->graph_nodes) == 0)
17258 {
17259 print (vam->ofp, "Node table empty, issue get_node_graph...");
17260 return 0;
17261 }
17262
17263 for (i = 0; i < vec_len (vam->graph_nodes); i++)
17264 {
17265 node = vam->graph_nodes[i];
17266 print (vam->ofp, "[%d] %s", i, node->name);
17267 for (j = 0; j < vec_len (node->next_nodes); j++)
17268 {
17269 if (node->next_nodes[j] != ~0)
17270 {
17271 next_node = vam->graph_nodes[node->next_nodes[j]];
17272 print (vam->ofp, " [%d] %s", j, next_node->name);
17273 }
17274 }
17275 }
17276 return 0;
17277}
17278
17279static int
17280value_sort_cmp (void *a1, void *a2)
17281{
17282 name_sort_t *n1 = a1;
17283 name_sort_t *n2 = a2;
17284
17285 if (n1->value < n2->value)
17286 return -1;
17287 if (n1->value > n2->value)
17288 return 1;
17289 return 0;
17290}
17291
17292
17293static int
17294dump_msg_api_table (vat_main_t * vam)
17295{
17296 api_main_t *am = &api_main;
17297 name_sort_t *nses = 0, *ns;
17298 hash_pair_t *hp;
17299 int i;
17300
17301 /* *INDENT-OFF* */
17302 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17303 ({
17304 vec_add2 (nses, ns, 1);
17305 ns->name = (u8 *)(hp->key);
17306 ns->value = (u32) hp->value[0];
17307 }));
17308 /* *INDENT-ON* */
17309
17310 vec_sort_with_function (nses, value_sort_cmp);
17311
17312 for (i = 0; i < vec_len (nses); i++)
17313 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17314 vec_free (nses);
17315 return 0;
17316}
17317
17318static int
17319get_msg_id (vat_main_t * vam)
17320{
17321 u8 *name_and_crc;
17322 u32 message_index;
17323
17324 if (unformat (vam->input, "%s", &name_and_crc))
17325 {
17326 message_index = vl_api_get_msg_index (name_and_crc);
17327 if (message_index == ~0)
17328 {
17329 print (vam->ofp, " '%s' not found", name_and_crc);
17330 return 0;
17331 }
17332 print (vam->ofp, " '%s' has message index %d",
17333 name_and_crc, message_index);
17334 return 0;
17335 }
17336 errmsg ("name_and_crc required...");
17337 return 0;
17338}
17339
17340static int
17341search_node_table (vat_main_t * vam)
17342{
17343 unformat_input_t *line_input = vam->input;
17344 u8 *node_to_find;
17345 int j;
17346 vlib_node_t *node, *next_node;
17347 uword *p;
17348
17349 if (vam->graph_node_index_by_name == 0)
17350 {
17351 print (vam->ofp, "Node table empty, issue get_node_graph...");
17352 return 0;
17353 }
17354
17355 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17356 {
17357 if (unformat (line_input, "%s", &node_to_find))
17358 {
17359 vec_add1 (node_to_find, 0);
17360 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17361 if (p == 0)
17362 {
17363 print (vam->ofp, "%s not found...", node_to_find);
17364 goto out;
17365 }
17366 node = vam->graph_nodes[p[0]];
17367 print (vam->ofp, "[%d] %s", p[0], node->name);
17368 for (j = 0; j < vec_len (node->next_nodes); j++)
17369 {
17370 if (node->next_nodes[j] != ~0)
17371 {
17372 next_node = vam->graph_nodes[node->next_nodes[j]];
17373 print (vam->ofp, " [%d] %s", j, next_node->name);
17374 }
17375 }
17376 }
17377
17378 else
17379 {
17380 clib_warning ("parse error '%U'", format_unformat_error,
17381 line_input);
17382 return -99;
17383 }
17384
17385 out:
17386 vec_free (node_to_find);
17387
17388 }
17389
17390 return 0;
17391}
17392
17393
17394static int
17395script (vat_main_t * vam)
17396{
17397#if (VPP_API_TEST_BUILTIN==0)
17398 u8 *s = 0;
17399 char *save_current_file;
17400 unformat_input_t save_input;
17401 jmp_buf save_jump_buf;
17402 u32 save_line_number;
17403
17404 FILE *new_fp, *save_ifp;
17405
17406 if (unformat (vam->input, "%s", &s))
17407 {
17408 new_fp = fopen ((char *) s, "r");
17409 if (new_fp == 0)
17410 {
17411 errmsg ("Couldn't open script file %s", s);
17412 vec_free (s);
17413 return -99;
17414 }
17415 }
17416 else
17417 {
17418 errmsg ("Missing script name");
17419 return -99;
17420 }
17421
17422 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17423 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17424 save_ifp = vam->ifp;
17425 save_line_number = vam->input_line_number;
17426 save_current_file = (char *) vam->current_file;
17427
17428 vam->input_line_number = 0;
17429 vam->ifp = new_fp;
17430 vam->current_file = s;
17431 do_one_file (vam);
17432
17433 clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17434 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17435 vam->ifp = save_ifp;
17436 vam->input_line_number = save_line_number;
17437 vam->current_file = (u8 *) save_current_file;
17438 vec_free (s);
17439
17440 return 0;
17441#else
17442 clib_warning ("use the exec command...");
17443 return -99;
17444#endif
17445}
17446
17447static int
17448echo (vat_main_t * vam)
17449{
17450 print (vam->ofp, "%v", vam->input->buffer);
17451 return 0;
17452}
17453
17454/* List of API message constructors, CLI names map to api_xxx */
17455#define foreach_vpe_api_msg \
17456_(create_loopback,"[mac <mac-addr>]") \
17457_(sw_interface_dump,"") \
17458_(sw_interface_set_flags, \
17459 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17460_(sw_interface_add_del_address, \
17461 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17462_(sw_interface_set_table, \
17463 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
17464_(sw_interface_set_mpls_enable, \
17465 "<intfc> | sw_if_index [disable | dis]") \
17466_(sw_interface_set_vpath, \
17467 "<intfc> | sw_if_index <id> enable | disable") \
17468_(sw_interface_set_vxlan_bypass, \
17469 "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable") \
17470_(sw_interface_set_l2_xconnect, \
17471 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17472 "enable | disable") \
17473_(sw_interface_set_l2_bridge, \
17474 "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n" \
17475 "[shg <split-horizon-group>] [bvi]\n" \
17476 "enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010017477_(bridge_domain_add_del, \
17478 "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
17479_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
17480_(l2fib_add_del, \
17481 "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17482_(l2_flags, \
17483 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
17484_(bridge_flags, \
17485 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17486_(tap_connect, \
17487 "tapname <name> mac <mac-addr> | random-mac [tag <string>]") \
17488_(tap_modify, \
17489 "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17490_(tap_delete, \
17491 "<vpp-if-name> | sw_if_index <id>") \
17492_(sw_interface_tap_dump, "") \
17493_(ip_add_del_route, \
17494 "<addr>/<mask> via <addr> [table-id <n>]\n" \
17495 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n" \
17496 "[weight <n>] [drop] [local] [classify <n>] [del]\n" \
17497 "[multipath] [count <n>]") \
17498_(mpls_route_add_del, \
17499 "<label> <eos> via <addr> [table-id <n>]\n" \
17500 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n" \
17501 "[weight <n>] [drop] [local] [classify <n>] [del]\n" \
17502 "[multipath] [count <n>]") \
17503_(mpls_ip_bind_unbind, \
17504 "<label> <addr/len>") \
17505_(mpls_tunnel_add_del, \
17506 " via <addr> [table-id <n>]\n" \
17507 "sw_if_index <id>] [l2] [del]") \
17508_(proxy_arp_add_del, \
17509 "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]") \
17510_(proxy_arp_intfc_enable_disable, \
17511 "<intfc> | sw_if_index <id> enable | disable") \
17512_(sw_interface_set_unnumbered, \
17513 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
17514_(ip_neighbor_add_del, \
17515 "(<intfc> | sw_if_index <id>) dst <ip46-address> " \
17516 "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]") \
17517_(reset_vrf, "vrf <id> [ipv6]") \
17518_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
17519_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
17520 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
17521 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
17522 "[outer_vlan_id_any][inner_vlan_id_any]") \
17523_(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]") \
17524_(reset_fib, "vrf <n> [ipv6]") \
17525_(dhcp_proxy_config, \
17526 "svr <v46-address> src <v46-address>\n" \
17527 "insert-cid <n> [del]") \
17528_(dhcp_proxy_config_2, \
17529 "svr <v46-address> src <v46-address>\n" \
17530 "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]") \
17531_(dhcp_proxy_set_vss, \
17532 "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]") \
17533_(dhcp_client_config, \
17534 "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17535_(set_ip_flow_hash, \
17536 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
17537_(sw_interface_ip6_enable_disable, \
17538 "<intfc> | sw_if_index <id> enable | disable") \
17539_(sw_interface_ip6_set_link_local_address, \
17540 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>") \
17541_(sw_interface_ip6nd_ra_prefix, \
17542 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n" \
17543 "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n" \
17544 "[nolink] [isno]") \
17545_(sw_interface_ip6nd_ra_config, \
17546 "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n" \
17547 "[life <n>] [count <n>] [interval <n>] [suppress]\n" \
17548 "[managed] [other] [ll] [send] [cease] [isno] [def]") \
17549_(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]") \
17550_(l2_patch_add_del, \
17551 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17552 "enable | disable") \
17553_(sr_tunnel_add_del, \
17554 "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n" \
17555 "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n" \
17556 "[policy <policy_name>]") \
17557_(sr_policy_add_del, \
17558 "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]") \
17559_(sr_multicast_map_add_del, \
17560 "address [ip6 multicast address] sr-policy [policy name] [del]") \
17561_(classify_add_del_table, \
17562 "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
17563 " [del] [del-chain] mask <mask-value>\n" \
17564 " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n" \
17565 " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]") \
17566_(classify_add_del_session, \
17567 "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n" \
17568 " table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n" \
17569 " [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n" \
17570 " [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]") \
17571_(classify_set_interface_ip_table, \
17572 "<intfc> | sw_if_index <nn> table <nn>") \
17573_(classify_set_interface_l2_tables, \
17574 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
17575 " [other-table <nn>]") \
17576_(get_node_index, "node <node-name") \
17577_(add_node_next, "node <node-name> next <next-node-name>") \
17578_(l2tpv3_create_tunnel, \
17579 "client_address <ip6-addr> our_address <ip6-addr>\n" \
17580 "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
17581 "[remote_cookie <nn>]\n[l2-sublayer-preset]\n") \
17582_(l2tpv3_set_tunnel_cookies, \
17583 "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n" \
17584 "[new_remote_cookie <nn>]\n") \
17585_(l2tpv3_interface_enable_disable, \
17586 "<intfc> | sw_if_index <nn> enable | disable") \
17587_(l2tpv3_set_lookup_key, \
17588 "lookup_v6_src | lookup_v6_dst | lookup_session_id") \
17589_(sw_if_l2tpv3_tunnel_dump, "") \
17590_(vxlan_add_del_tunnel, \
17591 "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n" \
17592 "{ <intfc> | mcast_sw_if_index <nn> } }\n" \
17593 "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]") \
17594_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
17595_(gre_add_del_tunnel, \
17596 "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n") \
17597_(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
17598_(l2_fib_clear_table, "") \
17599_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
17600_(l2_interface_vlan_tag_rewrite, \
17601 "<intfc> | sw_if_index <nn> \n" \
17602 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
17603 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
17604_(create_vhost_user_if, \
17605 "socket <filename> [server] [renumber <dev_instance>] " \
17606 "[mac <mac_address>]") \
17607_(modify_vhost_user_if, \
17608 "<intfc> | sw_if_index <nn> socket <filename>\n" \
17609 "[server] [renumber <dev_instance>]") \
17610_(delete_vhost_user_if, "<intfc> | sw_if_index <nn>") \
17611_(sw_interface_vhost_user_dump, "") \
17612_(show_version, "") \
17613_(vxlan_gpe_add_del_tunnel, \
17614 "local <addr> remote <addr> vni <nn>\n" \
17615 "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]" \
17616 "[next-ethernet] [next-nsh]\n") \
17617_(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
17618_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
17619_(interface_name_renumber, \
17620 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
17621_(input_acl_set_interface, \
17622 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
17623 " [l2-table <nn>] [del]") \
17624_(want_ip4_arp_events, "address <ip4-address> [del]") \
17625_(want_ip6_nd_events, "address <ip6-address> [del]") \
17626_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
17627_(ip_dump, "ipv4 | ipv6") \
17628_(ipsec_spd_add_del, "spd_id <n> [del]") \
17629_(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n" \
17630 " spid_id <n> ") \
17631_(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n" \
17632 " crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n" \
17633 " integ_alg <alg> integ_key <hex>") \
17634_(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n" \
17635 " (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n" \
17636 " laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
17637 " [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
17638_(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>") \
17639_(ikev2_profile_add_del, "name <profile_name> [del]") \
17640_(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n" \
17641 "(auth_data 0x<data> | auth_data <data>)") \
17642_(ikev2_profile_set_id, "name <profile_name> id_type <type>\n" \
17643 "(id_data 0x<data> | id_data <data>) (local|remote)") \
17644_(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n" \
17645 "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
17646 "(local|remote)") \
17647_(ikev2_set_local_key, "file <absolute_file_path>") \
17648_(delete_loopback,"sw_if_index <nn>") \
17649_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
17650_(map_add_domain, \
17651 "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> " \
17652 "ip6-src <ip6addr> " \
17653 "ea-bits-len <n> psid-offset <n> psid-len <n>") \
17654_(map_del_domain, "index <n>") \
17655_(map_add_del_rule, \
17656 "index <n> psid <n> dst <ip6addr> [del]") \
17657_(map_domain_dump, "") \
17658_(map_rule_dump, "index <map-domain>") \
17659_(want_interface_events, "enable|disable") \
17660_(want_stats,"enable|disable") \
17661_(get_first_msg_id, "client <name>") \
17662_(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
17663_(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n" \
17664 "fib-id <nn> [ip4][ip6][default]") \
17665_(get_node_graph, " ") \
17666_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
17667_(ioam_enable, "[trace] [pow] [ppc <encap|decap>]") \
17668_(ioam_disable, "") \
17669_(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
17670 " sw_if_index <sw_if_index> p <priority> " \
17671 "w <weight>] [del]") \
17672_(lisp_add_del_locator, "locator-set <locator_name> " \
17673 "iface <intf> | sw_if_index <sw_if_index> " \
17674 "p <priority> w <weight> [del]") \
17675_(lisp_add_del_local_eid,"vni <vni> eid " \
17676 "<ipv4|ipv6>/<prefix> | <L2 address> " \
17677 "locator-set <locator_name> [del]" \
17678 "[key-id sha1|sha256 secret-key <secret-key>]") \
17679_(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
17680 "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]") \
17681_(lisp_add_del_map_resolver, "<ip4|6-addr> [del]") \
17682_(lisp_add_del_map_server, "<ip4|6-addr> [del]") \
17683_(lisp_gpe_enable_disable, "enable|disable") \
17684_(lisp_enable_disable, "enable|disable") \
17685_(lisp_map_register_enable_disable, "enable|disable") \
17686_(lisp_rloc_probe_enable_disable, "enable|disable") \
17687_(lisp_gpe_add_del_iface, "up|down") \
17688_(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> " \
17689 "[seid <seid>] " \
17690 "rloc <locator> p <prio> " \
17691 "w <weight> [rloc <loc> ... ] " \
17692 "action <action> [del-all]") \
17693_(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid " \
17694 "<local-eid>") \
17695_(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del") \
17696_(lisp_map_request_mode, "src-dst|dst-only") \
17697_(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]") \
17698_(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>") \
17699_(lisp_locator_set_dump, "[local | remote]") \
17700_(lisp_locator_dump, "ls_index <index> | ls_name <name>") \
17701_(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] " \
17702 "[local] | [remote]") \
17703_(lisp_eid_table_vni_dump, "") \
17704_(lisp_eid_table_map_dump, "l2|l3") \
17705_(lisp_gpe_tunnel_dump, "") \
17706_(lisp_map_resolver_dump, "") \
17707_(lisp_map_server_dump, "") \
17708_(lisp_adjacencies_get, "vni <vni>") \
17709_(show_lisp_rloc_probe_state, "") \
17710_(show_lisp_map_register_state, "") \
17711_(show_lisp_status, "") \
17712_(lisp_get_map_request_itr_rlocs, "") \
17713_(show_lisp_pitr, "") \
17714_(show_lisp_map_request_mode, "") \
17715_(af_packet_create, "name <host interface name> [hw_addr <mac>]") \
17716_(af_packet_delete, "name <host interface name>") \
17717_(policer_add_del, "name <policer name> <params> [del]") \
17718_(policer_dump, "[name <policer name>]") \
17719_(policer_classify_set_interface, \
17720 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
17721 " [l2-table <nn>] [del]") \
17722_(policer_classify_dump, "type [ip4|ip6|l2]") \
17723_(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] " \
17724 "[master|slave]") \
17725_(netmap_delete, "name <interface name>") \
17726_(mpls_tunnel_dump, "tunnel_index <tunnel-id>") \
17727_(mpls_fib_dump, "") \
17728_(classify_table_ids, "") \
17729_(classify_table_by_interface, "sw_if_index <sw_if_index>") \
17730_(classify_table_info, "table_id <nn>") \
17731_(classify_session_dump, "table_id <nn>") \
17732_(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] " \
17733 "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] " \
17734 "[template_interval <nn>] [udp_checksum]") \
17735_(ipfix_exporter_dump, "") \
17736_(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17737_(ipfix_classify_stream_dump, "") \
17738_(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
17739_(ipfix_classify_table_dump, "") \
17740_(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
17741_(sw_interface_span_dump, "") \
17742_(get_next_index, "node-name <node-name> next-node-name <node-name>") \
17743_(pg_create_interface, "if_id <nn>") \
17744_(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]") \
17745_(pg_enable_disable, "[stream <id>] disable") \
17746_(ip_source_and_port_range_check_add_del, \
17747 "<ip-addr>/<mask> range <nn>-<nn> vrf <id>") \
17748_(ip_source_and_port_range_check_interface_add_del, \
17749 "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]" \
17750 "[udp-in-vrf <id>] [udp-out-vrf <id>]") \
17751_(ipsec_gre_add_del_tunnel, \
17752 "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]") \
17753_(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]") \
17754_(delete_subif,"<intfc> | sw_if_index <nn>") \
17755_(l2_interface_pbb_tag_rewrite, \
17756 "<intfc> | sw_if_index <nn> \n" \
17757 "[disable | push | pop | translate_pbb_stag <outer_tag>] \n" \
17758 "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]") \
17759_(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]") \
17760_(flow_classify_set_interface, \
17761 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17762_(flow_classify_dump, "type [ip4|ip6]") \
17763_(ip_fib_dump, "") \
17764_(ip6_fib_dump, "") \
17765_(feature_enable_disable, "arc_name <arc_name> " \
17766 "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]") \
17767_(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>" \
17768"[disable]") \
17769_(l2_xconnect_dump, "") \
17770_(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>") \
17771_(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>") \
17772_(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
17773
Pavel Kotucek738f3f22017-01-09 15:11:03 +010017774#if DPDK > 0
17775#define foreach_vpe_dpdk_api_msg \
17776_(sw_interface_set_dpdk_hqos_pipe, \
17777 "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
17778 "profile <profile-id>\n") \
17779_(sw_interface_set_dpdk_hqos_subport, \
17780 "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n" \
17781 "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
17782_(sw_interface_set_dpdk_hqos_tctbl, \
17783 "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")
17784#endif
17785
Damjan Marion7cd468a2016-12-19 23:05:39 +010017786/* List of command functions, CLI names map directly to functions */
17787#define foreach_cli_function \
17788_(comment, "usage: comment <ignore-rest-of-line>") \
17789_(dump_interface_table, "usage: dump_interface_table") \
17790_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
17791_(dump_ipv4_table, "usage: dump_ipv4_table") \
17792_(dump_ipv6_table, "usage: dump_ipv6_table") \
17793_(dump_stats_table, "usage: dump_stats_table") \
17794_(dump_macro_table, "usage: dump_macro_table ") \
17795_(dump_node_table, "usage: dump_node_table") \
17796_(dump_msg_api_table, "usage: dump_msg_api_table") \
17797_(get_msg_id, "usage: get_msg_id name_and_crc") \
17798_(echo, "usage: echo <message>") \
17799_(exec, "usage: exec <vpe-debug-CLI-command>") \
17800_(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>") \
17801_(help, "usage: help") \
17802_(q, "usage: quit") \
17803_(quit, "usage: quit") \
17804_(search_node_table, "usage: search_node_table <name>...") \
17805_(set, "usage: set <variable-name> <value>") \
17806_(script, "usage: script <file-name>") \
17807_(unset, "usage: unset <variable-name>")
17808
17809#define _(N,n) \
17810 static void vl_api_##n##_t_handler_uni \
17811 (vl_api_##n##_t * mp) \
17812 { \
17813 vat_main_t * vam = &vat_main; \
17814 if (vam->json_output) { \
17815 vl_api_##n##_t_handler_json(mp); \
17816 } else { \
17817 vl_api_##n##_t_handler(mp); \
17818 } \
17819 }
17820foreach_vpe_api_reply_msg;
17821#undef _
17822
Pavel Kotucek738f3f22017-01-09 15:11:03 +010017823#if DPDK > 0
17824#define _(N,n) \
17825 static void vl_api_##n##_t_handler_uni \
17826 (vl_api_##n##_t * mp) \
17827 { \
17828 vat_main_t * vam = &vat_main; \
17829 if (vam->json_output) { \
17830 vl_api_##n##_t_handler_json(mp); \
17831 } else { \
17832 vl_api_##n##_t_handler(mp); \
17833 } \
17834 }
17835foreach_vpe_dpdk_api_reply_msg;
17836#undef _
17837#endif
17838
Damjan Marion7cd468a2016-12-19 23:05:39 +010017839void
17840vat_api_hookup (vat_main_t * vam)
17841{
17842#define _(N,n) \
17843 vl_msg_api_set_handlers(VL_API_##N, #n, \
17844 vl_api_##n##_t_handler_uni, \
17845 vl_noop_handler, \
17846 vl_api_##n##_t_endian, \
17847 vl_api_##n##_t_print, \
17848 sizeof(vl_api_##n##_t), 1);
17849 foreach_vpe_api_reply_msg;
17850#undef _
17851
Pavel Kotucek738f3f22017-01-09 15:11:03 +010017852#if DPDK > 0
17853#define _(N,n) \
17854 vl_msg_api_set_handlers(VL_API_##N, #n, \
17855 vl_api_##n##_t_handler_uni, \
17856 vl_noop_handler, \
17857 vl_api_##n##_t_endian, \
17858 vl_api_##n##_t_print, \
17859 sizeof(vl_api_##n##_t), 1);
17860 foreach_vpe_dpdk_api_reply_msg;
17861#undef _
17862#endif
17863
Damjan Marion7cd468a2016-12-19 23:05:39 +010017864#if (VPP_API_TEST_BUILTIN==0)
17865 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17866#endif
17867
17868 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17869
17870 vam->function_by_name = hash_create_string (0, sizeof (uword));
17871
17872 vam->help_by_name = hash_create_string (0, sizeof (uword));
17873
17874 /* API messages we can send */
17875#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17876 foreach_vpe_api_msg;
17877#undef _
Pavel Kotucek738f3f22017-01-09 15:11:03 +010017878#if DPDK >0
17879#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17880 foreach_vpe_dpdk_api_msg;
17881#undef _
17882#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010017883
17884 /* Help strings */
17885#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17886 foreach_vpe_api_msg;
17887#undef _
Pavel Kotucek738f3f22017-01-09 15:11:03 +010017888#if DPDK >0
17889#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17890 foreach_vpe_dpdk_api_msg;
17891#undef _
17892#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010017893
17894 /* CLI functions */
17895#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17896 foreach_cli_function;
17897#undef _
17898
17899 /* Help strings */
17900#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17901 foreach_cli_function;
17902#undef _
17903}
17904
17905/*
17906 * fd.io coding-style-patch-verification: ON
17907 *
17908 * Local Variables:
17909 * eval: (c-set-style "gnu")
17910 * End:
17911 */