blob: e6c0f244d8354205496c5d6ee5b7cfa3a52752b5 [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) \
3572_(sw_interface_set_dpdk_hqos_pipe_reply) \
3573_(sw_interface_set_dpdk_hqos_subport_reply) \
3574_(sw_interface_set_dpdk_hqos_tctbl_reply) \
3575_(bridge_domain_add_del_reply) \
3576_(sw_interface_set_l2_xconnect_reply) \
3577_(l2fib_add_del_reply) \
3578_(ip_add_del_route_reply) \
3579_(mpls_route_add_del_reply) \
3580_(mpls_ip_bind_unbind_reply) \
3581_(proxy_arp_add_del_reply) \
3582_(proxy_arp_intfc_enable_disable_reply) \
3583_(sw_interface_set_unnumbered_reply) \
3584_(ip_neighbor_add_del_reply) \
3585_(reset_vrf_reply) \
3586_(oam_add_del_reply) \
3587_(reset_fib_reply) \
3588_(dhcp_proxy_config_reply) \
3589_(dhcp_proxy_config_2_reply) \
3590_(dhcp_proxy_set_vss_reply) \
3591_(dhcp_client_config_reply) \
3592_(set_ip_flow_hash_reply) \
3593_(sw_interface_ip6_enable_disable_reply) \
3594_(sw_interface_ip6_set_link_local_address_reply) \
3595_(sw_interface_ip6nd_ra_prefix_reply) \
3596_(sw_interface_ip6nd_ra_config_reply) \
3597_(set_arp_neighbor_limit_reply) \
3598_(l2_patch_add_del_reply) \
3599_(sr_tunnel_add_del_reply) \
3600_(sr_policy_add_del_reply) \
3601_(sr_multicast_map_add_del_reply) \
3602_(classify_add_del_session_reply) \
3603_(classify_set_interface_ip_table_reply) \
3604_(classify_set_interface_l2_tables_reply) \
3605_(l2tpv3_set_tunnel_cookies_reply) \
3606_(l2tpv3_interface_enable_disable_reply) \
3607_(l2tpv3_set_lookup_key_reply) \
3608_(l2_fib_clear_table_reply) \
3609_(l2_interface_efp_filter_reply) \
3610_(l2_interface_vlan_tag_rewrite_reply) \
3611_(modify_vhost_user_if_reply) \
3612_(delete_vhost_user_if_reply) \
3613_(want_ip4_arp_events_reply) \
3614_(want_ip6_nd_events_reply) \
3615_(input_acl_set_interface_reply) \
3616_(ipsec_spd_add_del_reply) \
3617_(ipsec_interface_add_del_spd_reply) \
3618_(ipsec_spd_add_del_entry_reply) \
3619_(ipsec_sad_add_del_entry_reply) \
3620_(ipsec_sa_set_key_reply) \
3621_(ikev2_profile_add_del_reply) \
3622_(ikev2_profile_set_auth_reply) \
3623_(ikev2_profile_set_id_reply) \
3624_(ikev2_profile_set_ts_reply) \
3625_(ikev2_set_local_key_reply) \
3626_(delete_loopback_reply) \
3627_(bd_ip_mac_add_del_reply) \
3628_(map_del_domain_reply) \
3629_(map_add_del_rule_reply) \
3630_(want_interface_events_reply) \
3631_(want_stats_reply) \
3632_(cop_interface_enable_disable_reply) \
3633_(cop_whitelist_enable_disable_reply) \
3634_(sw_interface_clear_stats_reply) \
3635_(ioam_enable_reply) \
3636_(ioam_disable_reply) \
3637_(lisp_add_del_locator_reply) \
3638_(lisp_add_del_local_eid_reply) \
3639_(lisp_add_del_remote_mapping_reply) \
3640_(lisp_add_del_adjacency_reply) \
3641_(lisp_gpe_add_del_fwd_entry_reply) \
3642_(lisp_add_del_map_resolver_reply) \
3643_(lisp_add_del_map_server_reply) \
3644_(lisp_gpe_enable_disable_reply) \
3645_(lisp_gpe_add_del_iface_reply) \
3646_(lisp_enable_disable_reply) \
3647_(lisp_rloc_probe_enable_disable_reply) \
3648_(lisp_map_register_enable_disable_reply) \
3649_(lisp_pitr_set_locator_set_reply) \
3650_(lisp_map_request_mode_reply) \
3651_(lisp_add_del_map_request_itr_rlocs_reply) \
3652_(lisp_eid_table_add_del_map_reply) \
3653_(vxlan_gpe_add_del_tunnel_reply) \
3654_(af_packet_delete_reply) \
3655_(policer_classify_set_interface_reply) \
3656_(netmap_create_reply) \
3657_(netmap_delete_reply) \
3658_(set_ipfix_exporter_reply) \
3659_(set_ipfix_classify_stream_reply) \
3660_(ipfix_classify_table_add_del_reply) \
3661_(flow_classify_set_interface_reply) \
3662_(sw_interface_span_enable_disable_reply) \
3663_(pg_capture_reply) \
3664_(pg_enable_disable_reply) \
3665_(ip_source_and_port_range_check_add_del_reply) \
3666_(ip_source_and_port_range_check_interface_add_del_reply)\
3667_(delete_subif_reply) \
3668_(l2_interface_pbb_tag_rewrite_reply) \
3669_(punt_reply) \
3670_(feature_enable_disable_reply) \
3671_(sw_interface_tag_add_del_reply) \
3672_(sw_interface_set_mtu_reply)
3673
3674#define _(n) \
3675 static void vl_api_##n##_t_handler \
3676 (vl_api_##n##_t * mp) \
3677 { \
3678 vat_main_t * vam = &vat_main; \
3679 i32 retval = ntohl(mp->retval); \
3680 if (vam->async_mode) { \
3681 vam->async_errors += (retval < 0); \
3682 } else { \
3683 vam->retval = retval; \
3684 vam->result_ready = 1; \
3685 } \
3686 }
3687foreach_standard_reply_retval_handler;
3688#undef _
3689
3690#define _(n) \
3691 static void vl_api_##n##_t_handler_json \
3692 (vl_api_##n##_t * mp) \
3693 { \
3694 vat_main_t * vam = &vat_main; \
3695 vat_json_node_t node; \
3696 vat_json_init_object(&node); \
3697 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
3698 vat_json_print(vam->ofp, &node); \
3699 vam->retval = ntohl(mp->retval); \
3700 vam->result_ready = 1; \
3701 }
3702foreach_standard_reply_retval_handler;
3703#undef _
3704
3705/*
3706 * Table of message reply handlers, must include boilerplate handlers
3707 * we just generated
3708 */
3709
3710#define foreach_vpe_api_reply_msg \
3711_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
3712_(SW_INTERFACE_DETAILS, sw_interface_details) \
3713_(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \
3714_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
3715_(CONTROL_PING_REPLY, control_ping_reply) \
3716_(CLI_REPLY, cli_reply) \
3717_(CLI_INBAND_REPLY, cli_inband_reply) \
3718_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
3719 sw_interface_add_del_address_reply) \
3720_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
3721_(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3722_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
3723_(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3724_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
3725 sw_interface_set_l2_xconnect_reply) \
3726_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
3727 sw_interface_set_l2_bridge_reply) \
3728_(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY, \
3729 sw_interface_set_dpdk_hqos_pipe_reply) \
3730_(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY, \
3731 sw_interface_set_dpdk_hqos_subport_reply) \
3732_(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY, \
3733 sw_interface_set_dpdk_hqos_tctbl_reply) \
3734_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
3735_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
3736_(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details) \
3737_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
3738_(L2_FLAGS_REPLY, l2_flags_reply) \
3739_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
3740_(TAP_CONNECT_REPLY, tap_connect_reply) \
3741_(TAP_MODIFY_REPLY, tap_modify_reply) \
3742_(TAP_DELETE_REPLY, tap_delete_reply) \
3743_(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details) \
3744_(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply) \
3745_(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply) \
3746_(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply) \
3747_(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply) \
3748_(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY, \
3749 proxy_arp_intfc_enable_disable_reply) \
3750_(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply) \
3751_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
3752 sw_interface_set_unnumbered_reply) \
3753_(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply) \
3754_(RESET_VRF_REPLY, reset_vrf_reply) \
3755_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
3756_(CREATE_SUBIF_REPLY, create_subif_reply) \
3757_(OAM_ADD_DEL_REPLY, oam_add_del_reply) \
3758_(RESET_FIB_REPLY, reset_fib_reply) \
3759_(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply) \
3760_(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply) \
3761_(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply) \
3762_(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply) \
3763_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
3764_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
3765 sw_interface_ip6_enable_disable_reply) \
3766_(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY, \
3767 sw_interface_ip6_set_link_local_address_reply) \
3768_(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY, \
3769 sw_interface_ip6nd_ra_prefix_reply) \
3770_(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY, \
3771 sw_interface_ip6nd_ra_config_reply) \
3772_(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply) \
3773_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
3774_(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply) \
3775_(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply) \
3776_(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply) \
3777_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \
3778_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \
3779_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \
3780classify_set_interface_ip_table_reply) \
3781_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY, \
3782 classify_set_interface_l2_tables_reply) \
3783_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
3784_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
3785_(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply) \
3786_(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply) \
3787_(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY, \
3788 l2tpv3_interface_enable_disable_reply) \
3789_(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply) \
3790_(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details) \
3791_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
3792_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
3793_(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply) \
3794_(GRE_TUNNEL_DETAILS, gre_tunnel_details) \
3795_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
3796_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
3797_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3798_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
3799_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply) \
3800_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply) \
3801_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply) \
3802_(SHOW_VERSION_REPLY, show_version_reply) \
3803_(L2_FIB_TABLE_ENTRY, l2_fib_table_entry) \
3804_(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply) \
3805_(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details) \
3806_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
3807_(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply) \
3808_(IP4_ARP_EVENT, ip4_arp_event) \
3809_(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply) \
3810_(IP6_ND_EVENT, ip6_nd_event) \
3811_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply) \
3812_(IP_ADDRESS_DETAILS, ip_address_details) \
3813_(IP_DETAILS, ip_details) \
3814_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \
3815_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3816_(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply) \
3817_(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply) \
3818_(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply) \
3819_(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply) \
3820_(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply) \
3821_(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply) \
3822_(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply) \
3823_(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply) \
3824_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
3825_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
3826_(DHCP_COMPL_EVENT, dhcp_compl_event) \
3827_(VNET_INTERFACE_COUNTERS, vnet_interface_counters) \
3828_(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters) \
3829_(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters) \
3830_(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply) \
3831_(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply) \
3832_(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply) \
3833_(MAP_DOMAIN_DETAILS, map_domain_details) \
3834_(MAP_RULE_DETAILS, map_rule_details) \
3835_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
3836_(WANT_STATS_REPLY, want_stats_reply) \
3837_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
3838_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3839_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3840_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
3841_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
3842_(IOAM_ENABLE_REPLY, ioam_enable_reply) \
3843_(IOAM_DISABLE_REPLY, ioam_disable_reply) \
3844_(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply) \
3845_(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply) \
3846_(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply) \
3847_(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3848_(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply) \
3849_(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply) \
3850_(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply) \
3851_(LISP_ADD_DEL_MAP_SERVER_REPLY, lisp_add_del_map_server_reply) \
3852_(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply) \
3853_(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply) \
3854_(LISP_MAP_REGISTER_ENABLE_DISABLE_REPLY, \
3855 lisp_map_register_enable_disable_reply) \
3856_(LISP_RLOC_PROBE_ENABLE_DISABLE_REPLY, \
3857 lisp_rloc_probe_enable_disable_reply) \
3858_(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply) \
3859_(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply) \
3860_(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply) \
3861_(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply) \
3862_(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details) \
3863_(LISP_LOCATOR_DETAILS, lisp_locator_details) \
3864_(LISP_EID_TABLE_DETAILS, lisp_eid_table_details) \
3865_(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details) \
3866_(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details) \
3867_(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details) \
3868_(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details) \
3869_(LISP_MAP_SERVER_DETAILS, lisp_map_server_details) \
3870_(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply) \
3871_(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply) \
3872_(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY, \
3873 lisp_add_del_map_request_itr_rlocs_reply) \
3874_(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY, \
3875 lisp_get_map_request_itr_rlocs_reply) \
3876_(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply) \
3877_(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply) \
3878_(SHOW_LISP_RLOC_PROBE_STATE_REPLY, show_lisp_rloc_probe_state_reply) \
3879_(SHOW_LISP_MAP_REGISTER_STATE_REPLY, \
3880 show_lisp_map_register_state_reply) \
3881_(AF_PACKET_CREATE_REPLY, af_packet_create_reply) \
3882_(AF_PACKET_DELETE_REPLY, af_packet_delete_reply) \
3883_(POLICER_ADD_DEL_REPLY, policer_add_del_reply) \
3884_(POLICER_DETAILS, policer_details) \
3885_(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3886_(POLICER_CLASSIFY_DETAILS, policer_classify_details) \
3887_(NETMAP_CREATE_REPLY, netmap_create_reply) \
3888_(NETMAP_DELETE_REPLY, netmap_delete_reply) \
3889_(MPLS_TUNNEL_DETAILS, mpls_tunnel_details) \
3890_(MPLS_FIB_DETAILS, mpls_fib_details) \
3891_(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply) \
3892_(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3893_(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply) \
3894_(CLASSIFY_SESSION_DETAILS, classify_session_details) \
3895_(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply) \
3896_(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details) \
3897_(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply) \
3898_(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details) \
3899_(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3900_(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details) \
3901_(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3902_(FLOW_CLASSIFY_DETAILS, flow_classify_details) \
3903_(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3904_(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details) \
3905_(GET_NEXT_INDEX_REPLY, get_next_index_reply) \
3906_(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply) \
3907_(PG_CAPTURE_REPLY, pg_capture_reply) \
3908_(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply) \
3909_(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY, \
3910 ip_source_and_port_range_check_add_del_reply) \
3911_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY, \
3912 ip_source_and_port_range_check_interface_add_del_reply) \
3913_(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply) \
3914_(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details) \
3915_(DELETE_SUBIF_REPLY, delete_subif_reply) \
3916_(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3917_(PUNT_REPLY, punt_reply) \
3918_(IP_FIB_DETAILS, ip_fib_details) \
3919_(IP6_FIB_DETAILS, ip6_fib_details) \
3920_(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply) \
3921_(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply) \
3922_(L2_XCONNECT_DETAILS, l2_xconnect_details) \
3923_(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply) \
3924_(IP_NEIGHBOR_DETAILS, ip_neighbor_details) \
3925_(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
3926
3927/* M: construct, but don't yet send a message */
3928
3929#define M(T,t) \
3930do { \
3931 vam->result_ready = 0; \
3932 mp = vl_msg_api_alloc_as_if_client(sizeof(*mp)); \
3933 memset (mp, 0, sizeof (*mp)); \
3934 mp->_vl_msg_id = ntohs (VL_API_##T); \
3935 mp->client_index = vam->my_client_index; \
3936} while(0);
3937
3938#define M2(T,t,n) \
3939do { \
3940 vam->result_ready = 0; \
3941 mp = vl_msg_api_alloc_as_if_client(sizeof(*mp)+(n)); \
3942 memset (mp, 0, sizeof (*mp)); \
3943 mp->_vl_msg_id = ntohs (VL_API_##T); \
3944 mp->client_index = vam->my_client_index; \
3945} while(0);
3946
3947
3948/* S: send a message */
3949#define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3950
3951/* W: wait for results, with timeout */
3952#define W \
3953do { \
3954 timeout = vat_time_now (vam) + 1.0; \
3955 \
3956 while (vat_time_now (vam) < timeout) { \
3957 if (vam->result_ready == 1) { \
3958 return (vam->retval); \
3959 } \
3960 vat_suspend (vam->vlib_main, 1e-3); \
3961 } \
3962 return -99; \
3963} while(0);
3964
3965/* W2: wait for results, with timeout */
3966#define W2(body) \
3967do { \
3968 timeout = vat_time_now (vam) + 1.0; \
3969 \
3970 while (vat_time_now (vam) < timeout) { \
3971 if (vam->result_ready == 1) { \
3972 (body); \
3973 return (vam->retval); \
3974 } \
3975 vat_suspend (vam->vlib_main, 1e-3); \
3976 } \
3977 return -99; \
3978} while(0);
3979
3980typedef struct
3981{
3982 u8 *name;
3983 u32 value;
3984} name_sort_t;
3985
3986
3987#define STR_VTR_OP_CASE(op) \
3988 case L2_VTR_ ## op: \
3989 return "" # op;
3990
3991static const char *
3992str_vtr_op (u32 vtr_op)
3993{
3994 switch (vtr_op)
3995 {
3996 STR_VTR_OP_CASE (DISABLED);
3997 STR_VTR_OP_CASE (PUSH_1);
3998 STR_VTR_OP_CASE (PUSH_2);
3999 STR_VTR_OP_CASE (POP_1);
4000 STR_VTR_OP_CASE (POP_2);
4001 STR_VTR_OP_CASE (TRANSLATE_1_1);
4002 STR_VTR_OP_CASE (TRANSLATE_1_2);
4003 STR_VTR_OP_CASE (TRANSLATE_2_1);
4004 STR_VTR_OP_CASE (TRANSLATE_2_2);
4005 }
4006
4007 return "UNKNOWN";
4008}
4009
4010static int
4011dump_sub_interface_table (vat_main_t * vam)
4012{
4013 const sw_interface_subif_t *sub = NULL;
4014
4015 if (vam->json_output)
4016 {
4017 clib_warning
4018 ("JSON output supported only for VPE API calls and dump_stats_table");
4019 return -99;
4020 }
4021
4022 print (vam->ofp,
4023 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4024 "Interface", "sw_if_index",
4025 "sub id", "dot1ad", "tags", "outer id",
4026 "inner id", "exact", "default", "outer any", "inner any");
4027
4028 vec_foreach (sub, vam->sw_if_subif_table)
4029 {
4030 print (vam->ofp,
4031 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4032 sub->interface_name,
4033 sub->sw_if_index,
4034 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4035 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4036 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4037 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4038 if (sub->vtr_op != L2_VTR_DISABLED)
4039 {
4040 print (vam->ofp,
4041 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4042 "tag1: %d tag2: %d ]",
4043 str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4044 sub->vtr_tag1, sub->vtr_tag2);
4045 }
4046 }
4047
4048 return 0;
4049}
4050
4051static int
4052name_sort_cmp (void *a1, void *a2)
4053{
4054 name_sort_t *n1 = a1;
4055 name_sort_t *n2 = a2;
4056
4057 return strcmp ((char *) n1->name, (char *) n2->name);
4058}
4059
4060static int
4061dump_interface_table (vat_main_t * vam)
4062{
4063 hash_pair_t *p;
4064 name_sort_t *nses = 0, *ns;
4065
4066 if (vam->json_output)
4067 {
4068 clib_warning
4069 ("JSON output supported only for VPE API calls and dump_stats_table");
4070 return -99;
4071 }
4072
4073 /* *INDENT-OFF* */
4074 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4075 ({
4076 vec_add2 (nses, ns, 1);
4077 ns->name = (u8 *)(p->key);
4078 ns->value = (u32) p->value[0];
4079 }));
4080 /* *INDENT-ON* */
4081
4082 vec_sort_with_function (nses, name_sort_cmp);
4083
4084 print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4085 vec_foreach (ns, nses)
4086 {
4087 print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4088 }
4089 vec_free (nses);
4090 return 0;
4091}
4092
4093static int
4094dump_ip_table (vat_main_t * vam, int is_ipv6)
4095{
4096 const ip_details_t *det = NULL;
4097 const ip_address_details_t *address = NULL;
4098 u32 i = ~0;
4099
4100 print (vam->ofp, "%-12s", "sw_if_index");
4101
4102 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4103 {
4104 i++;
4105 if (!det->present)
4106 {
4107 continue;
4108 }
4109 print (vam->ofp, "%-12d", i);
4110 print (vam->ofp, " %-30s%-13s", "Address", "Prefix length");
4111 if (!det->addr)
4112 {
4113 continue;
4114 }
4115 vec_foreach (address, det->addr)
4116 {
4117 print (vam->ofp,
4118 " %-30U%-13d",
4119 is_ipv6 ? format_ip6_address : format_ip4_address,
4120 address->ip, address->prefix_length);
4121 }
4122 }
4123
4124 return 0;
4125}
4126
4127static int
4128dump_ipv4_table (vat_main_t * vam)
4129{
4130 if (vam->json_output)
4131 {
4132 clib_warning
4133 ("JSON output supported only for VPE API calls and dump_stats_table");
4134 return -99;
4135 }
4136
4137 return dump_ip_table (vam, 0);
4138}
4139
4140static int
4141dump_ipv6_table (vat_main_t * vam)
4142{
4143 if (vam->json_output)
4144 {
4145 clib_warning
4146 ("JSON output supported only for VPE API calls and dump_stats_table");
4147 return -99;
4148 }
4149
4150 return dump_ip_table (vam, 1);
4151}
4152
4153static char *
4154counter_type_to_str (u8 counter_type, u8 is_combined)
4155{
4156 if (!is_combined)
4157 {
4158 switch (counter_type)
4159 {
4160 case VNET_INTERFACE_COUNTER_DROP:
4161 return "drop";
4162 case VNET_INTERFACE_COUNTER_PUNT:
4163 return "punt";
4164 case VNET_INTERFACE_COUNTER_IP4:
4165 return "ip4";
4166 case VNET_INTERFACE_COUNTER_IP6:
4167 return "ip6";
4168 case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4169 return "rx-no-buf";
4170 case VNET_INTERFACE_COUNTER_RX_MISS:
4171 return "rx-miss";
4172 case VNET_INTERFACE_COUNTER_RX_ERROR:
4173 return "rx-error";
4174 case VNET_INTERFACE_COUNTER_TX_ERROR:
4175 return "tx-error";
4176 default:
4177 return "INVALID-COUNTER-TYPE";
4178 }
4179 }
4180 else
4181 {
4182 switch (counter_type)
4183 {
4184 case VNET_INTERFACE_COUNTER_RX:
4185 return "rx";
4186 case VNET_INTERFACE_COUNTER_TX:
4187 return "tx";
4188 default:
4189 return "INVALID-COUNTER-TYPE";
4190 }
4191 }
4192}
4193
4194static int
4195dump_stats_table (vat_main_t * vam)
4196{
4197 vat_json_node_t node;
4198 vat_json_node_t *msg_array;
4199 vat_json_node_t *msg;
4200 vat_json_node_t *counter_array;
4201 vat_json_node_t *counter;
4202 interface_counter_t c;
4203 u64 packets;
4204 ip4_fib_counter_t *c4;
4205 ip6_fib_counter_t *c6;
4206 int i, j;
4207
4208 if (!vam->json_output)
4209 {
4210 clib_warning ("dump_stats_table supported only in JSON format");
4211 return -99;
4212 }
4213
4214 vat_json_init_object (&node);
4215
4216 /* interface counters */
4217 msg_array = vat_json_object_add (&node, "interface_counters");
4218 vat_json_init_array (msg_array);
4219 for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4220 {
4221 msg = vat_json_array_add (msg_array);
4222 vat_json_init_object (msg);
4223 vat_json_object_add_string_copy (msg, "vnet_counter_type",
4224 (u8 *) counter_type_to_str (i, 0));
4225 vat_json_object_add_int (msg, "is_combined", 0);
4226 counter_array = vat_json_object_add (msg, "data");
4227 vat_json_init_array (counter_array);
4228 for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4229 {
4230 packets = vam->simple_interface_counters[i][j];
4231 vat_json_array_add_uint (counter_array, packets);
4232 }
4233 }
4234 for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4235 {
4236 msg = vat_json_array_add (msg_array);
4237 vat_json_init_object (msg);
4238 vat_json_object_add_string_copy (msg, "vnet_counter_type",
4239 (u8 *) counter_type_to_str (i, 1));
4240 vat_json_object_add_int (msg, "is_combined", 1);
4241 counter_array = vat_json_object_add (msg, "data");
4242 vat_json_init_array (counter_array);
4243 for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4244 {
4245 c = vam->combined_interface_counters[i][j];
4246 counter = vat_json_array_add (counter_array);
4247 vat_json_init_object (counter);
4248 vat_json_object_add_uint (counter, "packets", c.packets);
4249 vat_json_object_add_uint (counter, "bytes", c.bytes);
4250 }
4251 }
4252
4253 /* ip4 fib counters */
4254 msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4255 vat_json_init_array (msg_array);
4256 for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4257 {
4258 msg = vat_json_array_add (msg_array);
4259 vat_json_init_object (msg);
4260 vat_json_object_add_uint (msg, "vrf_id",
4261 vam->ip4_fib_counters_vrf_id_by_index[i]);
4262 counter_array = vat_json_object_add (msg, "c");
4263 vat_json_init_array (counter_array);
4264 for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4265 {
4266 counter = vat_json_array_add (counter_array);
4267 vat_json_init_object (counter);
4268 c4 = &vam->ip4_fib_counters[i][j];
4269 vat_json_object_add_ip4 (counter, "address", c4->address);
4270 vat_json_object_add_uint (counter, "address_length",
4271 c4->address_length);
4272 vat_json_object_add_uint (counter, "packets", c4->packets);
4273 vat_json_object_add_uint (counter, "bytes", c4->bytes);
4274 }
4275 }
4276
4277 /* ip6 fib counters */
4278 msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4279 vat_json_init_array (msg_array);
4280 for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4281 {
4282 msg = vat_json_array_add (msg_array);
4283 vat_json_init_object (msg);
4284 vat_json_object_add_uint (msg, "vrf_id",
4285 vam->ip6_fib_counters_vrf_id_by_index[i]);
4286 counter_array = vat_json_object_add (msg, "c");
4287 vat_json_init_array (counter_array);
4288 for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4289 {
4290 counter = vat_json_array_add (counter_array);
4291 vat_json_init_object (counter);
4292 c6 = &vam->ip6_fib_counters[i][j];
4293 vat_json_object_add_ip6 (counter, "address", c6->address);
4294 vat_json_object_add_uint (counter, "address_length",
4295 c6->address_length);
4296 vat_json_object_add_uint (counter, "packets", c6->packets);
4297 vat_json_object_add_uint (counter, "bytes", c6->bytes);
4298 }
4299 }
4300
4301 vat_json_print (vam->ofp, &node);
4302 vat_json_free (&node);
4303
4304 return 0;
4305}
4306
4307int
4308exec (vat_main_t * vam)
4309{
4310 api_main_t *am = &api_main;
4311 vl_api_cli_request_t *mp;
4312 f64 timeout;
4313 void *oldheap;
4314 u8 *cmd = 0;
4315 unformat_input_t *i = vam->input;
4316
4317 if (vec_len (i->buffer) == 0)
4318 return -1;
4319
4320 if (vam->exec_mode == 0 && unformat (i, "mode"))
4321 {
4322 vam->exec_mode = 1;
4323 return 0;
4324 }
4325 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4326 {
4327 vam->exec_mode = 0;
4328 return 0;
4329 }
4330
4331
4332 M (CLI_REQUEST, cli_request);
4333
4334 /*
4335 * Copy cmd into shared memory.
4336 * In order for the CLI command to work, it
4337 * must be a vector ending in \n, not a C-string ending
4338 * in \n\0.
4339 */
4340 pthread_mutex_lock (&am->vlib_rp->mutex);
4341 oldheap = svm_push_data_heap (am->vlib_rp);
4342
4343 vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4344 clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4345
4346 svm_pop_heap (oldheap);
4347 pthread_mutex_unlock (&am->vlib_rp->mutex);
4348
4349 mp->cmd_in_shmem = (u64) cmd;
4350 S;
4351 timeout = vat_time_now (vam) + 10.0;
4352
4353 while (vat_time_now (vam) < timeout)
4354 {
4355 if (vam->result_ready == 1)
4356 {
4357 u8 *free_me;
4358 if (vam->shmem_result != NULL)
4359 print (vam->ofp, "%s", vam->shmem_result);
4360 pthread_mutex_lock (&am->vlib_rp->mutex);
4361 oldheap = svm_push_data_heap (am->vlib_rp);
4362
4363 free_me = (u8 *) vam->shmem_result;
4364 vec_free (free_me);
4365
4366 svm_pop_heap (oldheap);
4367 pthread_mutex_unlock (&am->vlib_rp->mutex);
4368 return 0;
4369 }
4370 }
4371 return -99;
4372}
4373
4374/*
4375 * Future replacement of exec() that passes CLI buffers directly in
4376 * the API messages instead of an additional shared memory area.
4377 */
4378static int
4379exec_inband (vat_main_t * vam)
4380{
4381 vl_api_cli_inband_t *mp;
4382 f64 timeout;
4383 unformat_input_t *i = vam->input;
4384
4385 if (vec_len (i->buffer) == 0)
4386 return -1;
4387
4388 if (vam->exec_mode == 0 && unformat (i, "mode"))
4389 {
4390 vam->exec_mode = 1;
4391 return 0;
4392 }
4393 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4394 {
4395 vam->exec_mode = 0;
4396 return 0;
4397 }
4398
4399 /*
4400 * In order for the CLI command to work, it
4401 * must be a vector ending in \n, not a C-string ending
4402 * in \n\0.
4403 */
4404 u32 len = vec_len (vam->input->buffer);
4405 M2 (CLI_INBAND, cli_inband, len);
4406 clib_memcpy (mp->cmd, vam->input->buffer, len);
4407 mp->length = htonl (len);
4408
4409 S;
4410 W2 (print (vam->ofp, "%s", vam->cmd_reply));
4411}
4412
4413static int
4414api_create_loopback (vat_main_t * vam)
4415{
4416 unformat_input_t *i = vam->input;
4417 vl_api_create_loopback_t *mp;
4418 f64 timeout;
4419 u8 mac_address[6];
4420 u8 mac_set = 0;
4421
4422 memset (mac_address, 0, sizeof (mac_address));
4423
4424 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4425 {
4426 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4427 mac_set = 1;
4428 else
4429 break;
4430 }
4431
4432 /* Construct the API message */
4433 M (CREATE_LOOPBACK, create_loopback);
4434 if (mac_set)
4435 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4436
4437 S;
4438 W;
4439}
4440
4441static int
4442api_delete_loopback (vat_main_t * vam)
4443{
4444 unformat_input_t *i = vam->input;
4445 vl_api_delete_loopback_t *mp;
4446 f64 timeout;
4447 u32 sw_if_index = ~0;
4448
4449 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4450 {
4451 if (unformat (i, "sw_if_index %d", &sw_if_index))
4452 ;
4453 else
4454 break;
4455 }
4456
4457 if (sw_if_index == ~0)
4458 {
4459 errmsg ("missing sw_if_index");
4460 return -99;
4461 }
4462
4463 /* Construct the API message */
4464 M (DELETE_LOOPBACK, delete_loopback);
4465 mp->sw_if_index = ntohl (sw_if_index);
4466
4467 S;
4468 W;
4469}
4470
4471static int
4472api_want_stats (vat_main_t * vam)
4473{
4474 unformat_input_t *i = vam->input;
4475 vl_api_want_stats_t *mp;
4476 f64 timeout;
4477 int enable = -1;
4478
4479 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4480 {
4481 if (unformat (i, "enable"))
4482 enable = 1;
4483 else if (unformat (i, "disable"))
4484 enable = 0;
4485 else
4486 break;
4487 }
4488
4489 if (enable == -1)
4490 {
4491 errmsg ("missing enable|disable");
4492 return -99;
4493 }
4494
4495 M (WANT_STATS, want_stats);
4496 mp->enable_disable = enable;
4497
4498 S;
4499 W;
4500}
4501
4502static int
4503api_want_interface_events (vat_main_t * vam)
4504{
4505 unformat_input_t *i = vam->input;
4506 vl_api_want_interface_events_t *mp;
4507 f64 timeout;
4508 int enable = -1;
4509
4510 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4511 {
4512 if (unformat (i, "enable"))
4513 enable = 1;
4514 else if (unformat (i, "disable"))
4515 enable = 0;
4516 else
4517 break;
4518 }
4519
4520 if (enable == -1)
4521 {
4522 errmsg ("missing enable|disable");
4523 return -99;
4524 }
4525
4526 M (WANT_INTERFACE_EVENTS, want_interface_events);
4527 mp->enable_disable = enable;
4528
4529 vam->interface_event_display = enable;
4530
4531 S;
4532 W;
4533}
4534
4535
4536/* Note: non-static, called once to set up the initial intfc table */
4537int
4538api_sw_interface_dump (vat_main_t * vam)
4539{
4540 vl_api_sw_interface_dump_t *mp;
4541 f64 timeout;
4542 hash_pair_t *p;
4543 name_sort_t *nses = 0, *ns;
4544 sw_interface_subif_t *sub = NULL;
4545
4546 /* Toss the old name table */
4547 /* *INDENT-OFF* */
4548 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4549 ({
4550 vec_add2 (nses, ns, 1);
4551 ns->name = (u8 *)(p->key);
4552 ns->value = (u32) p->value[0];
4553 }));
4554 /* *INDENT-ON* */
4555
4556 hash_free (vam->sw_if_index_by_interface_name);
4557
4558 vec_foreach (ns, nses) vec_free (ns->name);
4559
4560 vec_free (nses);
4561
4562 vec_foreach (sub, vam->sw_if_subif_table)
4563 {
4564 vec_free (sub->interface_name);
4565 }
4566 vec_free (vam->sw_if_subif_table);
4567
4568 /* recreate the interface name hash table */
4569 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4570
4571 /* Get list of ethernets */
4572 M (SW_INTERFACE_DUMP, sw_interface_dump);
4573 mp->name_filter_valid = 1;
4574 strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4575 S;
4576
4577 /* and local / loopback interfaces */
4578 M (SW_INTERFACE_DUMP, sw_interface_dump);
4579 mp->name_filter_valid = 1;
4580 strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4581 S;
4582
4583 /* and packet-generator interfaces */
4584 M (SW_INTERFACE_DUMP, sw_interface_dump);
4585 mp->name_filter_valid = 1;
4586 strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4587 S;
4588
4589 /* and vxlan-gpe tunnel interfaces */
4590 M (SW_INTERFACE_DUMP, sw_interface_dump);
4591 mp->name_filter_valid = 1;
4592 strncpy ((char *) mp->name_filter, "vxlan_gpe",
4593 sizeof (mp->name_filter) - 1);
4594 S;
4595
4596 /* and vxlan tunnel interfaces */
4597 M (SW_INTERFACE_DUMP, sw_interface_dump);
4598 mp->name_filter_valid = 1;
4599 strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4600 S;
4601
4602 /* and host (af_packet) interfaces */
4603 M (SW_INTERFACE_DUMP, sw_interface_dump);
4604 mp->name_filter_valid = 1;
4605 strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4606 S;
4607
4608 /* and l2tpv3 tunnel interfaces */
4609 M (SW_INTERFACE_DUMP, sw_interface_dump);
4610 mp->name_filter_valid = 1;
4611 strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4612 sizeof (mp->name_filter) - 1);
4613 S;
4614
4615 /* and GRE tunnel interfaces */
4616 M (SW_INTERFACE_DUMP, sw_interface_dump);
4617 mp->name_filter_valid = 1;
4618 strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4619 S;
4620
4621 /* and LISP-GPE interfaces */
4622 M (SW_INTERFACE_DUMP, sw_interface_dump);
4623 mp->name_filter_valid = 1;
4624 strncpy ((char *) mp->name_filter, "lisp_gpe",
4625 sizeof (mp->name_filter) - 1);
4626 S;
4627
4628 /* and IPSEC tunnel interfaces */
4629 M (SW_INTERFACE_DUMP, sw_interface_dump);
4630 mp->name_filter_valid = 1;
4631 strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4632 S;
4633
4634 /* Use a control ping for synchronization */
4635 {
4636 vl_api_control_ping_t *mp;
4637 M (CONTROL_PING, control_ping);
4638 S;
4639 }
4640 W;
4641}
4642
4643static int
4644api_sw_interface_set_flags (vat_main_t * vam)
4645{
4646 unformat_input_t *i = vam->input;
4647 vl_api_sw_interface_set_flags_t *mp;
4648 f64 timeout;
4649 u32 sw_if_index;
4650 u8 sw_if_index_set = 0;
4651 u8 admin_up = 0, link_up = 0;
4652
4653 /* Parse args required to build the message */
4654 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4655 {
4656 if (unformat (i, "admin-up"))
4657 admin_up = 1;
4658 else if (unformat (i, "admin-down"))
4659 admin_up = 0;
4660 else if (unformat (i, "link-up"))
4661 link_up = 1;
4662 else if (unformat (i, "link-down"))
4663 link_up = 0;
4664 else
4665 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4666 sw_if_index_set = 1;
4667 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4668 sw_if_index_set = 1;
4669 else
4670 break;
4671 }
4672
4673 if (sw_if_index_set == 0)
4674 {
4675 errmsg ("missing interface name or sw_if_index");
4676 return -99;
4677 }
4678
4679 /* Construct the API message */
4680 M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4681 mp->sw_if_index = ntohl (sw_if_index);
4682 mp->admin_up_down = admin_up;
4683 mp->link_up_down = link_up;
4684
4685 /* send it... */
4686 S;
4687
4688 /* Wait for a reply, return the good/bad news... */
4689 W;
4690}
4691
4692static int
4693api_sw_interface_clear_stats (vat_main_t * vam)
4694{
4695 unformat_input_t *i = vam->input;
4696 vl_api_sw_interface_clear_stats_t *mp;
4697 f64 timeout;
4698 u32 sw_if_index;
4699 u8 sw_if_index_set = 0;
4700
4701 /* Parse args required to build the message */
4702 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4703 {
4704 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4705 sw_if_index_set = 1;
4706 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4707 sw_if_index_set = 1;
4708 else
4709 break;
4710 }
4711
4712 /* Construct the API message */
4713 M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4714
4715 if (sw_if_index_set == 1)
4716 mp->sw_if_index = ntohl (sw_if_index);
4717 else
4718 mp->sw_if_index = ~0;
4719
4720 /* send it... */
4721 S;
4722
4723 /* Wait for a reply, return the good/bad news... */
4724 W;
4725}
4726
4727static int
4728api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4729{
4730 unformat_input_t *i = vam->input;
4731 vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4732 f64 timeout;
4733 u32 sw_if_index;
4734 u8 sw_if_index_set = 0;
4735 u32 subport;
4736 u8 subport_set = 0;
4737 u32 pipe;
4738 u8 pipe_set = 0;
4739 u32 profile;
4740 u8 profile_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, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4746 sw_if_index_set = 1;
4747 else if (unformat (i, "sw_if_index %u", &sw_if_index))
4748 sw_if_index_set = 1;
4749 else if (unformat (i, "subport %u", &subport))
4750 subport_set = 1;
4751 else
4752 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4753 sw_if_index_set = 1;
4754 else if (unformat (i, "pipe %u", &pipe))
4755 pipe_set = 1;
4756 else if (unformat (i, "profile %u", &profile))
4757 profile_set = 1;
4758 else
4759 break;
4760 }
4761
4762 if (sw_if_index_set == 0)
4763 {
4764 errmsg ("missing interface name or sw_if_index");
4765 return -99;
4766 }
4767
4768 if (subport_set == 0)
4769 {
4770 errmsg ("missing subport ");
4771 return -99;
4772 }
4773
4774 if (pipe_set == 0)
4775 {
4776 errmsg ("missing pipe");
4777 return -99;
4778 }
4779
4780 if (profile_set == 0)
4781 {
4782 errmsg ("missing profile");
4783 return -99;
4784 }
4785
4786 M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4787
4788 mp->sw_if_index = ntohl (sw_if_index);
4789 mp->subport = ntohl (subport);
4790 mp->pipe = ntohl (pipe);
4791 mp->profile = ntohl (profile);
4792
4793
4794 S;
4795 W;
4796 /* NOTREACHED */
4797 return 0;
4798}
4799
4800static int
4801api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4802{
4803 unformat_input_t *i = vam->input;
4804 vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4805 f64 timeout;
4806 u32 sw_if_index;
4807 u8 sw_if_index_set = 0;
4808 u32 subport;
4809 u8 subport_set = 0;
4810 u32 tb_rate = 1250000000; /* 10GbE */
4811 u32 tb_size = 1000000;
4812 u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4813 u32 tc_period = 10;
4814
4815 /* Parse args required to build the message */
4816 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4817 {
4818 if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4819 sw_if_index_set = 1;
4820 else if (unformat (i, "sw_if_index %u", &sw_if_index))
4821 sw_if_index_set = 1;
4822 else if (unformat (i, "subport %u", &subport))
4823 subport_set = 1;
4824 else
4825 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4826 sw_if_index_set = 1;
4827 else if (unformat (i, "rate %u", &tb_rate))
4828 {
4829 u32 tc_id;
4830
4831 for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4832 tc_id++)
4833 tc_rate[tc_id] = tb_rate;
4834 }
4835 else if (unformat (i, "bktsize %u", &tb_size))
4836 ;
4837 else if (unformat (i, "tc0 %u", &tc_rate[0]))
4838 ;
4839 else if (unformat (i, "tc1 %u", &tc_rate[1]))
4840 ;
4841 else if (unformat (i, "tc2 %u", &tc_rate[2]))
4842 ;
4843 else if (unformat (i, "tc3 %u", &tc_rate[3]))
4844 ;
4845 else if (unformat (i, "period %u", &tc_period))
4846 ;
4847 else
4848 break;
4849 }
4850
4851 if (sw_if_index_set == 0)
4852 {
4853 errmsg ("missing interface name or sw_if_index");
4854 return -99;
4855 }
4856
4857 if (subport_set == 0)
4858 {
4859 errmsg ("missing subport ");
4860 return -99;
4861 }
4862
4863 M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4864
4865 mp->sw_if_index = ntohl (sw_if_index);
4866 mp->subport = ntohl (subport);
4867 mp->tb_rate = ntohl (tb_rate);
4868 mp->tb_size = ntohl (tb_size);
4869 mp->tc_rate[0] = ntohl (tc_rate[0]);
4870 mp->tc_rate[1] = ntohl (tc_rate[1]);
4871 mp->tc_rate[2] = ntohl (tc_rate[2]);
4872 mp->tc_rate[3] = ntohl (tc_rate[3]);
4873 mp->tc_period = ntohl (tc_period);
4874
4875 S;
4876 W;
4877 /* NOTREACHED */
4878 return 0;
4879}
4880
4881static int
4882api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4883{
4884 unformat_input_t *i = vam->input;
4885 vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4886 f64 timeout;
4887 u32 sw_if_index;
4888 u8 sw_if_index_set = 0;
4889 u8 entry_set = 0;
4890 u8 tc_set = 0;
4891 u8 queue_set = 0;
4892 u32 entry, tc, queue;
4893
4894 /* Parse args required to build the message */
4895 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4896 {
4897 if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4898 sw_if_index_set = 1;
4899 else if (unformat (i, "sw_if_index %u", &sw_if_index))
4900 sw_if_index_set = 1;
4901 else if (unformat (i, "entry %d", &entry))
4902 entry_set = 1;
4903 else if (unformat (i, "tc %d", &tc))
4904 tc_set = 1;
4905 else if (unformat (i, "queue %d", &queue))
4906 queue_set = 1;
4907 else
4908 break;
4909 }
4910
4911 if (sw_if_index_set == 0)
4912 {
4913 errmsg ("missing interface name or sw_if_index");
4914 return -99;
4915 }
4916
4917 if (entry_set == 0)
4918 {
4919 errmsg ("missing entry ");
4920 return -99;
4921 }
4922
4923 if (tc_set == 0)
4924 {
4925 errmsg ("missing traffic class ");
4926 return -99;
4927 }
4928
4929 if (queue_set == 0)
4930 {
4931 errmsg ("missing queue ");
4932 return -99;
4933 }
4934
4935 M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4936
4937 mp->sw_if_index = ntohl (sw_if_index);
4938 mp->entry = ntohl (entry);
4939 mp->tc = ntohl (tc);
4940 mp->queue = ntohl (queue);
4941
4942 S;
4943 W;
4944 /* NOTREACHED */
4945 return 0;
4946}
4947
4948static int
4949api_sw_interface_add_del_address (vat_main_t * vam)
4950{
4951 unformat_input_t *i = vam->input;
4952 vl_api_sw_interface_add_del_address_t *mp;
4953 f64 timeout;
4954 u32 sw_if_index;
4955 u8 sw_if_index_set = 0;
4956 u8 is_add = 1, del_all = 0;
4957 u32 address_length = 0;
4958 u8 v4_address_set = 0;
4959 u8 v6_address_set = 0;
4960 ip4_address_t v4address;
4961 ip6_address_t v6address;
4962
4963 /* Parse args required to build the message */
4964 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4965 {
4966 if (unformat (i, "del-all"))
4967 del_all = 1;
4968 else if (unformat (i, "del"))
4969 is_add = 0;
4970 else
4971 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4972 sw_if_index_set = 1;
4973 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4974 sw_if_index_set = 1;
4975 else if (unformat (i, "%U/%d",
4976 unformat_ip4_address, &v4address, &address_length))
4977 v4_address_set = 1;
4978 else if (unformat (i, "%U/%d",
4979 unformat_ip6_address, &v6address, &address_length))
4980 v6_address_set = 1;
4981 else
4982 break;
4983 }
4984
4985 if (sw_if_index_set == 0)
4986 {
4987 errmsg ("missing interface name or sw_if_index");
4988 return -99;
4989 }
4990 if (v4_address_set && v6_address_set)
4991 {
4992 errmsg ("both v4 and v6 addresses set");
4993 return -99;
4994 }
4995 if (!v4_address_set && !v6_address_set && !del_all)
4996 {
4997 errmsg ("no addresses set");
4998 return -99;
4999 }
5000
5001 /* Construct the API message */
5002 M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
5003
5004 mp->sw_if_index = ntohl (sw_if_index);
5005 mp->is_add = is_add;
5006 mp->del_all = del_all;
5007 if (v6_address_set)
5008 {
5009 mp->is_ipv6 = 1;
5010 clib_memcpy (mp->address, &v6address, sizeof (v6address));
5011 }
5012 else
5013 {
5014 clib_memcpy (mp->address, &v4address, sizeof (v4address));
5015 }
5016 mp->address_length = address_length;
5017
5018 /* send it... */
5019 S;
5020
5021 /* Wait for a reply, return good/bad news */
5022 W;
5023}
5024
5025static int
5026api_sw_interface_set_mpls_enable (vat_main_t * vam)
5027{
5028 unformat_input_t *i = vam->input;
5029 vl_api_sw_interface_set_mpls_enable_t *mp;
5030 f64 timeout;
5031 u32 sw_if_index;
5032 u8 sw_if_index_set = 0;
5033 u8 enable = 1;
5034
5035 /* Parse args required to build the message */
5036 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5037 {
5038 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5039 sw_if_index_set = 1;
5040 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5041 sw_if_index_set = 1;
5042 else if (unformat (i, "disable"))
5043 enable = 0;
5044 else if (unformat (i, "dis"))
5045 enable = 0;
5046 else
5047 break;
5048 }
5049
5050 if (sw_if_index_set == 0)
5051 {
5052 errmsg ("missing interface name or sw_if_index");
5053 return -99;
5054 }
5055
5056 /* Construct the API message */
5057 M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
5058
5059 mp->sw_if_index = ntohl (sw_if_index);
5060 mp->enable = enable;
5061
5062 /* send it... */
5063 S;
5064
5065 /* Wait for a reply... */
5066 W;
5067}
5068
5069static int
5070api_sw_interface_set_table (vat_main_t * vam)
5071{
5072 unformat_input_t *i = vam->input;
5073 vl_api_sw_interface_set_table_t *mp;
5074 f64 timeout;
5075 u32 sw_if_index, vrf_id = 0;
5076 u8 sw_if_index_set = 0;
5077 u8 is_ipv6 = 0;
5078
5079 /* Parse args required to build the message */
5080 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5081 {
5082 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5083 sw_if_index_set = 1;
5084 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5085 sw_if_index_set = 1;
5086 else if (unformat (i, "vrf %d", &vrf_id))
5087 ;
5088 else if (unformat (i, "ipv6"))
5089 is_ipv6 = 1;
5090 else
5091 break;
5092 }
5093
5094 if (sw_if_index_set == 0)
5095 {
5096 errmsg ("missing interface name or sw_if_index");
5097 return -99;
5098 }
5099
5100 /* Construct the API message */
5101 M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
5102
5103 mp->sw_if_index = ntohl (sw_if_index);
5104 mp->is_ipv6 = is_ipv6;
5105 mp->vrf_id = ntohl (vrf_id);
5106
5107 /* send it... */
5108 S;
5109
5110 /* Wait for a reply... */
5111 W;
5112}
5113
5114static void vl_api_sw_interface_get_table_reply_t_handler
5115 (vl_api_sw_interface_get_table_reply_t * mp)
5116{
5117 vat_main_t *vam = &vat_main;
5118
5119 print (vam->ofp, "%d", ntohl (mp->vrf_id));
5120
5121 vam->retval = ntohl (mp->retval);
5122 vam->result_ready = 1;
5123
5124}
5125
5126static void vl_api_sw_interface_get_table_reply_t_handler_json
5127 (vl_api_sw_interface_get_table_reply_t * mp)
5128{
5129 vat_main_t *vam = &vat_main;
5130 vat_json_node_t node;
5131
5132 vat_json_init_object (&node);
5133 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5134 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5135
5136 vat_json_print (vam->ofp, &node);
5137 vat_json_free (&node);
5138
5139 vam->retval = ntohl (mp->retval);
5140 vam->result_ready = 1;
5141}
5142
5143static int
5144api_sw_interface_get_table (vat_main_t * vam)
5145{
5146 unformat_input_t *i = vam->input;
5147 vl_api_sw_interface_get_table_t *mp;
5148 u32 sw_if_index;
5149 u8 sw_if_index_set = 0;
5150 u8 is_ipv6 = 0;
5151 f64 timeout;
5152
5153 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5154 {
5155 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5156 sw_if_index_set = 1;
5157 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5158 sw_if_index_set = 1;
5159 else if (unformat (i, "ipv6"))
5160 is_ipv6 = 1;
5161 else
5162 break;
5163 }
5164
5165 if (sw_if_index_set == 0)
5166 {
5167 errmsg ("missing interface name or sw_if_index");
5168 return -99;
5169 }
5170
5171 M (SW_INTERFACE_GET_TABLE, sw_interface_get_table);
5172 mp->sw_if_index = htonl (sw_if_index);
5173 mp->is_ipv6 = is_ipv6;
5174
5175 S;
5176 W;
5177}
5178
5179static int
5180api_sw_interface_set_vpath (vat_main_t * vam)
5181{
5182 unformat_input_t *i = vam->input;
5183 vl_api_sw_interface_set_vpath_t *mp;
5184 f64 timeout;
5185 u32 sw_if_index = 0;
5186 u8 sw_if_index_set = 0;
5187 u8 is_enable = 0;
5188
5189 /* Parse args required to build the message */
5190 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5191 {
5192 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5193 sw_if_index_set = 1;
5194 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5195 sw_if_index_set = 1;
5196 else if (unformat (i, "enable"))
5197 is_enable = 1;
5198 else if (unformat (i, "disable"))
5199 is_enable = 0;
5200 else
5201 break;
5202 }
5203
5204 if (sw_if_index_set == 0)
5205 {
5206 errmsg ("missing interface name or sw_if_index");
5207 return -99;
5208 }
5209
5210 /* Construct the API message */
5211 M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5212
5213 mp->sw_if_index = ntohl (sw_if_index);
5214 mp->enable = is_enable;
5215
5216 /* send it... */
5217 S;
5218
5219 /* Wait for a reply... */
5220 W;
5221}
5222
5223static int
5224api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5225{
5226 unformat_input_t *i = vam->input;
5227 vl_api_sw_interface_set_vxlan_bypass_t *mp;
5228 f64 timeout;
5229 u32 sw_if_index = 0;
5230 u8 sw_if_index_set = 0;
5231 u8 is_enable = 0;
5232 u8 is_ipv6 = 0;
5233
5234 /* Parse args required to build the message */
5235 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5236 {
5237 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5238 sw_if_index_set = 1;
5239 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5240 sw_if_index_set = 1;
5241 else if (unformat (i, "enable"))
5242 is_enable = 1;
5243 else if (unformat (i, "disable"))
5244 is_enable = 0;
5245 else if (unformat (i, "ip4"))
5246 is_ipv6 = 0;
5247 else if (unformat (i, "ip6"))
5248 is_ipv6 = 1;
5249 else
5250 break;
5251 }
5252
5253 if (sw_if_index_set == 0)
5254 {
5255 errmsg ("missing interface name or sw_if_index");
5256 return -99;
5257 }
5258
5259 /* Construct the API message */
5260 M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5261
5262 mp->sw_if_index = ntohl (sw_if_index);
5263 mp->enable = is_enable;
5264 mp->is_ipv6 = is_ipv6;
5265
5266 /* send it... */
5267 S;
5268
5269 /* Wait for a reply... */
5270 W;
5271}
5272
5273static int
5274api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5275{
5276 unformat_input_t *i = vam->input;
5277 vl_api_sw_interface_set_l2_xconnect_t *mp;
5278 f64 timeout;
5279 u32 rx_sw_if_index;
5280 u8 rx_sw_if_index_set = 0;
5281 u32 tx_sw_if_index;
5282 u8 tx_sw_if_index_set = 0;
5283 u8 enable = 1;
5284
5285 /* Parse args required to build the message */
5286 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5287 {
5288 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5289 rx_sw_if_index_set = 1;
5290 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5291 tx_sw_if_index_set = 1;
5292 else if (unformat (i, "rx"))
5293 {
5294 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5295 {
5296 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5297 &rx_sw_if_index))
5298 rx_sw_if_index_set = 1;
5299 }
5300 else
5301 break;
5302 }
5303 else if (unformat (i, "tx"))
5304 {
5305 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5306 {
5307 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5308 &tx_sw_if_index))
5309 tx_sw_if_index_set = 1;
5310 }
5311 else
5312 break;
5313 }
5314 else if (unformat (i, "enable"))
5315 enable = 1;
5316 else if (unformat (i, "disable"))
5317 enable = 0;
5318 else
5319 break;
5320 }
5321
5322 if (rx_sw_if_index_set == 0)
5323 {
5324 errmsg ("missing rx interface name or rx_sw_if_index");
5325 return -99;
5326 }
5327
5328 if (enable && (tx_sw_if_index_set == 0))
5329 {
5330 errmsg ("missing tx interface name or tx_sw_if_index");
5331 return -99;
5332 }
5333
5334 M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5335
5336 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5337 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5338 mp->enable = enable;
5339
5340 S;
5341 W;
5342 /* NOTREACHED */
5343 return 0;
5344}
5345
5346static int
5347api_sw_interface_set_l2_bridge (vat_main_t * vam)
5348{
5349 unformat_input_t *i = vam->input;
5350 vl_api_sw_interface_set_l2_bridge_t *mp;
5351 f64 timeout;
5352 u32 rx_sw_if_index;
5353 u8 rx_sw_if_index_set = 0;
5354 u32 bd_id;
5355 u8 bd_id_set = 0;
5356 u8 bvi = 0;
5357 u32 shg = 0;
5358 u8 enable = 1;
5359
5360 /* Parse args required to build the message */
5361 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5362 {
5363 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5364 rx_sw_if_index_set = 1;
5365 else if (unformat (i, "bd_id %d", &bd_id))
5366 bd_id_set = 1;
5367 else
5368 if (unformat
5369 (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5370 rx_sw_if_index_set = 1;
5371 else if (unformat (i, "shg %d", &shg))
5372 ;
5373 else if (unformat (i, "bvi"))
5374 bvi = 1;
5375 else if (unformat (i, "enable"))
5376 enable = 1;
5377 else if (unformat (i, "disable"))
5378 enable = 0;
5379 else
5380 break;
5381 }
5382
5383 if (rx_sw_if_index_set == 0)
5384 {
5385 errmsg ("missing rx interface name or sw_if_index");
5386 return -99;
5387 }
5388
5389 if (enable && (bd_id_set == 0))
5390 {
5391 errmsg ("missing bridge domain");
5392 return -99;
5393 }
5394
5395 M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5396
5397 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5398 mp->bd_id = ntohl (bd_id);
5399 mp->shg = (u8) shg;
5400 mp->bvi = bvi;
5401 mp->enable = enable;
5402
5403 S;
5404 W;
5405 /* NOTREACHED */
5406 return 0;
5407}
5408
5409static int
5410api_bridge_domain_dump (vat_main_t * vam)
5411{
5412 unformat_input_t *i = vam->input;
5413 vl_api_bridge_domain_dump_t *mp;
5414 f64 timeout;
5415 u32 bd_id = ~0;
5416
5417 /* Parse args required to build the message */
5418 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5419 {
5420 if (unformat (i, "bd_id %d", &bd_id))
5421 ;
5422 else
5423 break;
5424 }
5425
5426 M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5427 mp->bd_id = ntohl (bd_id);
5428 S;
5429
5430 /* Use a control ping for synchronization */
5431 {
5432 vl_api_control_ping_t *mp;
5433 M (CONTROL_PING, control_ping);
5434 S;
5435 }
5436
5437 W;
5438 /* NOTREACHED */
5439 return 0;
5440}
5441
5442static int
5443api_bridge_domain_add_del (vat_main_t * vam)
5444{
5445 unformat_input_t *i = vam->input;
5446 vl_api_bridge_domain_add_del_t *mp;
5447 f64 timeout;
5448 u32 bd_id = ~0;
5449 u8 is_add = 1;
5450 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5451 u32 mac_age = 0;
5452
5453 /* Parse args required to build the message */
5454 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5455 {
5456 if (unformat (i, "bd_id %d", &bd_id))
5457 ;
5458 else if (unformat (i, "flood %d", &flood))
5459 ;
5460 else if (unformat (i, "uu-flood %d", &uu_flood))
5461 ;
5462 else if (unformat (i, "forward %d", &forward))
5463 ;
5464 else if (unformat (i, "learn %d", &learn))
5465 ;
5466 else if (unformat (i, "arp-term %d", &arp_term))
5467 ;
5468 else if (unformat (i, "mac-age %d", &mac_age))
5469 ;
5470 else if (unformat (i, "del"))
5471 {
5472 is_add = 0;
5473 flood = uu_flood = forward = learn = 0;
5474 }
5475 else
5476 break;
5477 }
5478
5479 if (bd_id == ~0)
5480 {
5481 errmsg ("missing bridge domain");
5482 return -99;
5483 }
5484
5485 if (mac_age > 255)
5486 {
5487 errmsg ("mac age must be less than 256 ");
5488 return -99;
5489 }
5490
5491 M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5492
5493 mp->bd_id = ntohl (bd_id);
5494 mp->flood = flood;
5495 mp->uu_flood = uu_flood;
5496 mp->forward = forward;
5497 mp->learn = learn;
5498 mp->arp_term = arp_term;
5499 mp->is_add = is_add;
5500 mp->mac_age = (u8) mac_age;
5501
5502 S;
5503 W;
5504 /* NOTREACHED */
5505 return 0;
5506}
5507
5508static int
5509api_l2fib_add_del (vat_main_t * vam)
5510{
5511 unformat_input_t *i = vam->input;
5512 vl_api_l2fib_add_del_t *mp;
5513 f64 timeout;
5514 u64 mac = 0;
5515 u8 mac_set = 0;
5516 u32 bd_id;
5517 u8 bd_id_set = 0;
5518 u32 sw_if_index = ~0;
5519 u8 sw_if_index_set = 0;
5520 u8 is_add = 1;
5521 u8 static_mac = 0;
5522 u8 filter_mac = 0;
5523 u8 bvi_mac = 0;
5524 int count = 1;
5525 f64 before = 0;
5526 int j;
5527
5528 /* Parse args required to build the message */
5529 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5530 {
5531 if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5532 mac_set = 1;
5533 else if (unformat (i, "bd_id %d", &bd_id))
5534 bd_id_set = 1;
5535 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5536 sw_if_index_set = 1;
5537 else if (unformat (i, "sw_if"))
5538 {
5539 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5540 {
5541 if (unformat
5542 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5543 sw_if_index_set = 1;
5544 }
5545 else
5546 break;
5547 }
5548 else if (unformat (i, "static"))
5549 static_mac = 1;
5550 else if (unformat (i, "filter"))
5551 {
5552 filter_mac = 1;
5553 static_mac = 1;
5554 }
5555 else if (unformat (i, "bvi"))
5556 {
5557 bvi_mac = 1;
5558 static_mac = 1;
5559 }
5560 else if (unformat (i, "del"))
5561 is_add = 0;
5562 else if (unformat (i, "count %d", &count))
5563 ;
5564 else
5565 break;
5566 }
5567
5568 if (mac_set == 0)
5569 {
5570 errmsg ("missing mac address");
5571 return -99;
5572 }
5573
5574 if (bd_id_set == 0)
5575 {
5576 errmsg ("missing bridge domain");
5577 return -99;
5578 }
5579
5580 if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5581 {
5582 errmsg ("missing interface name or sw_if_index");
5583 return -99;
5584 }
5585
5586 if (count > 1)
5587 {
5588 /* Turn on async mode */
5589 vam->async_mode = 1;
5590 vam->async_errors = 0;
5591 before = vat_time_now (vam);
5592 }
5593
5594 for (j = 0; j < count; j++)
5595 {
5596 M (L2FIB_ADD_DEL, l2fib_add_del);
5597
5598 mp->mac = mac;
5599 mp->bd_id = ntohl (bd_id);
5600 mp->is_add = is_add;
5601
5602 if (is_add)
5603 {
5604 mp->sw_if_index = ntohl (sw_if_index);
5605 mp->static_mac = static_mac;
5606 mp->filter_mac = filter_mac;
5607 mp->bvi_mac = bvi_mac;
5608 }
5609 increment_mac_address (&mac);
5610 /* send it... */
5611 S;
5612 }
5613
5614 if (count > 1)
5615 {
5616 vl_api_control_ping_t *mp;
5617 f64 after;
5618
5619 /* Shut off async mode */
5620 vam->async_mode = 0;
5621
5622 M (CONTROL_PING, control_ping);
5623 S;
5624
5625 timeout = vat_time_now (vam) + 1.0;
5626 while (vat_time_now (vam) < timeout)
5627 if (vam->result_ready == 1)
5628 goto out;
5629 vam->retval = -99;
5630
5631 out:
5632 if (vam->retval == -99)
5633 errmsg ("timeout");
5634
5635 if (vam->async_errors > 0)
5636 {
5637 errmsg ("%d asynchronous errors", vam->async_errors);
5638 vam->retval = -98;
5639 }
5640 vam->async_errors = 0;
5641 after = vat_time_now (vam);
5642
5643 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5644 count, after - before, count / (after - before));
5645 }
5646 else
5647 {
5648 /* Wait for a reply... */
5649 W;
5650 }
5651 /* Return the good/bad news */
5652 return (vam->retval);
5653}
5654
5655static int
5656api_l2_flags (vat_main_t * vam)
5657{
5658 unformat_input_t *i = vam->input;
5659 vl_api_l2_flags_t *mp;
5660 f64 timeout;
5661 u32 sw_if_index;
5662 u32 feature_bitmap = 0;
5663 u8 sw_if_index_set = 0;
5664
5665 /* Parse args required to build the message */
5666 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5667 {
5668 if (unformat (i, "sw_if_index %d", &sw_if_index))
5669 sw_if_index_set = 1;
5670 else if (unformat (i, "sw_if"))
5671 {
5672 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5673 {
5674 if (unformat
5675 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5676 sw_if_index_set = 1;
5677 }
5678 else
5679 break;
5680 }
5681 else if (unformat (i, "learn"))
5682 feature_bitmap |= L2INPUT_FEAT_LEARN;
5683 else if (unformat (i, "forward"))
5684 feature_bitmap |= L2INPUT_FEAT_FWD;
5685 else if (unformat (i, "flood"))
5686 feature_bitmap |= L2INPUT_FEAT_FLOOD;
5687 else if (unformat (i, "uu-flood"))
5688 feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5689 else
5690 break;
5691 }
5692
5693 if (sw_if_index_set == 0)
5694 {
5695 errmsg ("missing interface name or sw_if_index");
5696 return -99;
5697 }
5698
5699 M (L2_FLAGS, l2_flags);
5700
5701 mp->sw_if_index = ntohl (sw_if_index);
5702 mp->feature_bitmap = ntohl (feature_bitmap);
5703
5704 S;
5705 W;
5706 /* NOTREACHED */
5707 return 0;
5708}
5709
5710static int
5711api_bridge_flags (vat_main_t * vam)
5712{
5713 unformat_input_t *i = vam->input;
5714 vl_api_bridge_flags_t *mp;
5715 f64 timeout;
5716 u32 bd_id;
5717 u8 bd_id_set = 0;
5718 u8 is_set = 1;
5719 u32 flags = 0;
5720
5721 /* Parse args required to build the message */
5722 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5723 {
5724 if (unformat (i, "bd_id %d", &bd_id))
5725 bd_id_set = 1;
5726 else if (unformat (i, "learn"))
5727 flags |= L2_LEARN;
5728 else if (unformat (i, "forward"))
5729 flags |= L2_FWD;
5730 else if (unformat (i, "flood"))
5731 flags |= L2_FLOOD;
5732 else if (unformat (i, "uu-flood"))
5733 flags |= L2_UU_FLOOD;
5734 else if (unformat (i, "arp-term"))
5735 flags |= L2_ARP_TERM;
5736 else if (unformat (i, "off"))
5737 is_set = 0;
5738 else if (unformat (i, "disable"))
5739 is_set = 0;
5740 else
5741 break;
5742 }
5743
5744 if (bd_id_set == 0)
5745 {
5746 errmsg ("missing bridge domain");
5747 return -99;
5748 }
5749
5750 M (BRIDGE_FLAGS, bridge_flags);
5751
5752 mp->bd_id = ntohl (bd_id);
5753 mp->feature_bitmap = ntohl (flags);
5754 mp->is_set = is_set;
5755
5756 S;
5757 W;
5758 /* NOTREACHED */
5759 return 0;
5760}
5761
5762static int
5763api_bd_ip_mac_add_del (vat_main_t * vam)
5764{
5765 unformat_input_t *i = vam->input;
5766 vl_api_bd_ip_mac_add_del_t *mp;
5767 f64 timeout;
5768 u32 bd_id;
5769 u8 is_ipv6 = 0;
5770 u8 is_add = 1;
5771 u8 bd_id_set = 0;
5772 u8 ip_set = 0;
5773 u8 mac_set = 0;
5774 ip4_address_t v4addr;
5775 ip6_address_t v6addr;
5776 u8 macaddr[6];
5777
5778
5779 /* Parse args required to build the message */
5780 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5781 {
5782 if (unformat (i, "bd_id %d", &bd_id))
5783 {
5784 bd_id_set++;
5785 }
5786 else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5787 {
5788 ip_set++;
5789 }
5790 else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5791 {
5792 ip_set++;
5793 is_ipv6++;
5794 }
5795 else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5796 {
5797 mac_set++;
5798 }
5799 else if (unformat (i, "del"))
5800 is_add = 0;
5801 else
5802 break;
5803 }
5804
5805 if (bd_id_set == 0)
5806 {
5807 errmsg ("missing bridge domain");
5808 return -99;
5809 }
5810 else if (ip_set == 0)
5811 {
5812 errmsg ("missing IP address");
5813 return -99;
5814 }
5815 else if (mac_set == 0)
5816 {
5817 errmsg ("missing MAC address");
5818 return -99;
5819 }
5820
5821 M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5822
5823 mp->bd_id = ntohl (bd_id);
5824 mp->is_ipv6 = is_ipv6;
5825 mp->is_add = is_add;
5826 if (is_ipv6)
5827 clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5828 else
5829 clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5830 clib_memcpy (mp->mac_address, macaddr, 6);
5831 S;
5832 W;
5833 /* NOTREACHED */
5834 return 0;
5835}
5836
5837static int
5838api_tap_connect (vat_main_t * vam)
5839{
5840 unformat_input_t *i = vam->input;
5841 vl_api_tap_connect_t *mp;
5842 f64 timeout;
5843 u8 mac_address[6];
5844 u8 random_mac = 1;
5845 u8 name_set = 0;
5846 u8 *tap_name;
5847 u8 *tag = 0;
5848
5849 memset (mac_address, 0, sizeof (mac_address));
5850
5851 /* Parse args required to build the message */
5852 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5853 {
5854 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5855 {
5856 random_mac = 0;
5857 }
5858 else if (unformat (i, "random-mac"))
5859 random_mac = 1;
5860 else if (unformat (i, "tapname %s", &tap_name))
5861 name_set = 1;
5862 else if (unformat (i, "tag %s", &tag))
5863 ;
5864 else
5865 break;
5866 }
5867
5868 if (name_set == 0)
5869 {
5870 errmsg ("missing tap name");
5871 return -99;
5872 }
5873 if (vec_len (tap_name) > 63)
5874 {
5875 errmsg ("tap name too long");
5876 return -99;
5877 }
5878 vec_add1 (tap_name, 0);
5879
5880 if (vec_len (tag) > 63)
5881 {
5882 errmsg ("tag too long");
5883 return -99;
5884 }
5885
5886 /* Construct the API message */
5887 M (TAP_CONNECT, tap_connect);
5888
5889 mp->use_random_mac = random_mac;
5890 clib_memcpy (mp->mac_address, mac_address, 6);
5891 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5892 if (tag)
5893 clib_memcpy (mp->tag, tag, vec_len (tag));
5894
5895 vec_free (tap_name);
5896 vec_free (tag);
5897
5898 /* send it... */
5899 S;
5900
5901 /* Wait for a reply... */
5902 W;
5903}
5904
5905static int
5906api_tap_modify (vat_main_t * vam)
5907{
5908 unformat_input_t *i = vam->input;
5909 vl_api_tap_modify_t *mp;
5910 f64 timeout;
5911 u8 mac_address[6];
5912 u8 random_mac = 1;
5913 u8 name_set = 0;
5914 u8 *tap_name;
5915 u32 sw_if_index = ~0;
5916 u8 sw_if_index_set = 0;
5917
5918 memset (mac_address, 0, sizeof (mac_address));
5919
5920 /* Parse args required to build the message */
5921 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5922 {
5923 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5924 sw_if_index_set = 1;
5925 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5926 sw_if_index_set = 1;
5927 else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5928 {
5929 random_mac = 0;
5930 }
5931 else if (unformat (i, "random-mac"))
5932 random_mac = 1;
5933 else if (unformat (i, "tapname %s", &tap_name))
5934 name_set = 1;
5935 else
5936 break;
5937 }
5938
5939 if (sw_if_index_set == 0)
5940 {
5941 errmsg ("missing vpp interface name");
5942 return -99;
5943 }
5944 if (name_set == 0)
5945 {
5946 errmsg ("missing tap name");
5947 return -99;
5948 }
5949 if (vec_len (tap_name) > 63)
5950 {
5951 errmsg ("tap name too long");
5952 }
5953 vec_add1 (tap_name, 0);
5954
5955 /* Construct the API message */
5956 M (TAP_MODIFY, tap_modify);
5957
5958 mp->use_random_mac = random_mac;
5959 mp->sw_if_index = ntohl (sw_if_index);
5960 clib_memcpy (mp->mac_address, mac_address, 6);
5961 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5962 vec_free (tap_name);
5963
5964 /* send it... */
5965 S;
5966
5967 /* Wait for a reply... */
5968 W;
5969}
5970
5971static int
5972api_tap_delete (vat_main_t * vam)
5973{
5974 unformat_input_t *i = vam->input;
5975 vl_api_tap_delete_t *mp;
5976 f64 timeout;
5977 u32 sw_if_index = ~0;
5978 u8 sw_if_index_set = 0;
5979
5980 /* Parse args required to build the message */
5981 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5982 {
5983 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5984 sw_if_index_set = 1;
5985 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5986 sw_if_index_set = 1;
5987 else
5988 break;
5989 }
5990
5991 if (sw_if_index_set == 0)
5992 {
5993 errmsg ("missing vpp interface name");
5994 return -99;
5995 }
5996
5997 /* Construct the API message */
5998 M (TAP_DELETE, tap_delete);
5999
6000 mp->sw_if_index = ntohl (sw_if_index);
6001
6002 /* send it... */
6003 S;
6004
6005 /* Wait for a reply... */
6006 W;
6007}
6008
6009static int
6010api_ip_add_del_route (vat_main_t * vam)
6011{
6012 unformat_input_t *i = vam->input;
6013 vl_api_ip_add_del_route_t *mp;
6014 f64 timeout;
6015 u32 sw_if_index = ~0, vrf_id = 0;
6016 u8 is_ipv6 = 0;
6017 u8 is_local = 0, is_drop = 0;
6018 u8 is_unreach = 0, is_prohibit = 0;
6019 u8 create_vrf_if_needed = 0;
6020 u8 is_add = 1;
6021 u32 next_hop_weight = 1;
6022 u8 not_last = 0;
6023 u8 is_multipath = 0;
6024 u8 address_set = 0;
6025 u8 address_length_set = 0;
6026 u32 next_hop_table_id = 0;
6027 u32 resolve_attempts = 0;
6028 u32 dst_address_length = 0;
6029 u8 next_hop_set = 0;
6030 ip4_address_t v4_dst_address, v4_next_hop_address;
6031 ip6_address_t v6_dst_address, v6_next_hop_address;
6032 int count = 1;
6033 int j;
6034 f64 before = 0;
6035 u32 random_add_del = 0;
6036 u32 *random_vector = 0;
6037 uword *random_hash;
6038 u32 random_seed = 0xdeaddabe;
6039 u32 classify_table_index = ~0;
6040 u8 is_classify = 0;
6041 u8 resolve_host = 0, resolve_attached = 0;
6042 mpls_label_t *next_hop_out_label_stack = NULL;
6043 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6044 mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6045
6046 /* Parse args required to build the message */
6047 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6048 {
6049 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6050 ;
6051 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6052 ;
6053 else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6054 {
6055 address_set = 1;
6056 is_ipv6 = 0;
6057 }
6058 else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6059 {
6060 address_set = 1;
6061 is_ipv6 = 1;
6062 }
6063 else if (unformat (i, "/%d", &dst_address_length))
6064 {
6065 address_length_set = 1;
6066 }
6067
6068 else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6069 &v4_next_hop_address))
6070 {
6071 next_hop_set = 1;
6072 }
6073 else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6074 &v6_next_hop_address))
6075 {
6076 next_hop_set = 1;
6077 }
6078 else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6079 ;
6080 else if (unformat (i, "weight %d", &next_hop_weight))
6081 ;
6082 else if (unformat (i, "drop"))
6083 {
6084 is_drop = 1;
6085 }
6086 else if (unformat (i, "null-send-unreach"))
6087 {
6088 is_unreach = 1;
6089 }
6090 else if (unformat (i, "null-send-prohibit"))
6091 {
6092 is_prohibit = 1;
6093 }
6094 else if (unformat (i, "local"))
6095 {
6096 is_local = 1;
6097 }
6098 else if (unformat (i, "classify %d", &classify_table_index))
6099 {
6100 is_classify = 1;
6101 }
6102 else if (unformat (i, "del"))
6103 is_add = 0;
6104 else if (unformat (i, "add"))
6105 is_add = 1;
6106 else if (unformat (i, "not-last"))
6107 not_last = 1;
6108 else if (unformat (i, "resolve-via-host"))
6109 resolve_host = 1;
6110 else if (unformat (i, "resolve-via-attached"))
6111 resolve_attached = 1;
6112 else if (unformat (i, "multipath"))
6113 is_multipath = 1;
6114 else if (unformat (i, "vrf %d", &vrf_id))
6115 ;
6116 else if (unformat (i, "create-vrf"))
6117 create_vrf_if_needed = 1;
6118 else if (unformat (i, "count %d", &count))
6119 ;
6120 else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6121 ;
6122 else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6123 ;
6124 else if (unformat (i, "out-label %d", &next_hop_out_label))
6125 vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6126 else if (unformat (i, "via-label %d", &next_hop_via_label))
6127 ;
6128 else if (unformat (i, "random"))
6129 random_add_del = 1;
6130 else if (unformat (i, "seed %d", &random_seed))
6131 ;
6132 else
6133 {
6134 clib_warning ("parse error '%U'", format_unformat_error, i);
6135 return -99;
6136 }
6137 }
6138
6139 if (!next_hop_set && !is_drop && !is_local &&
6140 !is_classify && !is_unreach && !is_prohibit &&
6141 MPLS_LABEL_INVALID == next_hop_via_label)
6142 {
6143 errmsg
6144 ("next hop / local / drop / unreach / prohibit / classify not set");
6145 return -99;
6146 }
6147
6148 if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6149 {
6150 errmsg ("next hop and next-hop via label set");
6151 return -99;
6152 }
6153 if (address_set == 0)
6154 {
6155 errmsg ("missing addresses");
6156 return -99;
6157 }
6158
6159 if (address_length_set == 0)
6160 {
6161 errmsg ("missing address length");
6162 return -99;
6163 }
6164
6165 /* Generate a pile of unique, random routes */
6166 if (random_add_del)
6167 {
6168 u32 this_random_address;
6169 random_hash = hash_create (count, sizeof (uword));
6170
6171 hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6172 for (j = 0; j <= count; j++)
6173 {
6174 do
6175 {
6176 this_random_address = random_u32 (&random_seed);
6177 this_random_address =
6178 clib_host_to_net_u32 (this_random_address);
6179 }
6180 while (hash_get (random_hash, this_random_address));
6181 vec_add1 (random_vector, this_random_address);
6182 hash_set (random_hash, this_random_address, 1);
6183 }
6184 hash_free (random_hash);
6185 v4_dst_address.as_u32 = random_vector[0];
6186 }
6187
6188 if (count > 1)
6189 {
6190 /* Turn on async mode */
6191 vam->async_mode = 1;
6192 vam->async_errors = 0;
6193 before = vat_time_now (vam);
6194 }
6195
6196 for (j = 0; j < count; j++)
6197 {
6198 /* Construct the API message */
6199 M2 (IP_ADD_DEL_ROUTE, ip_add_del_route,
6200 sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6201
6202 mp->next_hop_sw_if_index = ntohl (sw_if_index);
6203 mp->table_id = ntohl (vrf_id);
6204 mp->create_vrf_if_needed = create_vrf_if_needed;
6205
6206 mp->is_add = is_add;
6207 mp->is_drop = is_drop;
6208 mp->is_unreach = is_unreach;
6209 mp->is_prohibit = is_prohibit;
6210 mp->is_ipv6 = is_ipv6;
6211 mp->is_local = is_local;
6212 mp->is_classify = is_classify;
6213 mp->is_multipath = is_multipath;
6214 mp->is_resolve_host = resolve_host;
6215 mp->is_resolve_attached = resolve_attached;
6216 mp->not_last = not_last;
6217 mp->next_hop_weight = next_hop_weight;
6218 mp->dst_address_length = dst_address_length;
6219 mp->next_hop_table_id = ntohl (next_hop_table_id);
6220 mp->classify_table_index = ntohl (classify_table_index);
6221 mp->next_hop_via_label = ntohl (next_hop_via_label);
6222 mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6223 if (0 != mp->next_hop_n_out_labels)
6224 {
6225 memcpy (mp->next_hop_out_label_stack,
6226 next_hop_out_label_stack,
6227 vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6228 vec_free (next_hop_out_label_stack);
6229 }
6230
6231 if (is_ipv6)
6232 {
6233 clib_memcpy (mp->dst_address, &v6_dst_address,
6234 sizeof (v6_dst_address));
6235 if (next_hop_set)
6236 clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6237 sizeof (v6_next_hop_address));
6238 increment_v6_address (&v6_dst_address);
6239 }
6240 else
6241 {
6242 clib_memcpy (mp->dst_address, &v4_dst_address,
6243 sizeof (v4_dst_address));
6244 if (next_hop_set)
6245 clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6246 sizeof (v4_next_hop_address));
6247 if (random_add_del)
6248 v4_dst_address.as_u32 = random_vector[j + 1];
6249 else
6250 increment_v4_address (&v4_dst_address);
6251 }
6252 /* send it... */
6253 S;
6254 /* If we receive SIGTERM, stop now... */
6255 if (vam->do_exit)
6256 break;
6257 }
6258
6259 /* When testing multiple add/del ops, use a control-ping to sync */
6260 if (count > 1)
6261 {
6262 vl_api_control_ping_t *mp;
6263 f64 after;
6264
6265 /* Shut off async mode */
6266 vam->async_mode = 0;
6267
6268 M (CONTROL_PING, control_ping);
6269 S;
6270
6271 timeout = vat_time_now (vam) + 1.0;
6272 while (vat_time_now (vam) < timeout)
6273 if (vam->result_ready == 1)
6274 goto out;
6275 vam->retval = -99;
6276
6277 out:
6278 if (vam->retval == -99)
6279 errmsg ("timeout");
6280
6281 if (vam->async_errors > 0)
6282 {
6283 errmsg ("%d asynchronous errors", vam->async_errors);
6284 vam->retval = -98;
6285 }
6286 vam->async_errors = 0;
6287 after = vat_time_now (vam);
6288
6289 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6290 if (j > 0)
6291 count = j;
6292
6293 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6294 count, after - before, count / (after - before));
6295 }
6296 else
6297 {
6298 /* Wait for a reply... */
6299 W;
6300 }
6301
6302 /* Return the good/bad news */
6303 return (vam->retval);
6304}
6305
6306static int
6307api_mpls_route_add_del (vat_main_t * vam)
6308{
6309 unformat_input_t *i = vam->input;
6310 vl_api_mpls_route_add_del_t *mp;
6311 f64 timeout;
6312 u32 sw_if_index = ~0, table_id = 0;
6313 u8 create_table_if_needed = 0;
6314 u8 is_add = 1;
6315 u32 next_hop_weight = 1;
6316 u8 is_multipath = 0;
6317 u32 next_hop_table_id = 0;
6318 u8 next_hop_set = 0;
6319 ip4_address_t v4_next_hop_address = {
6320 .as_u32 = 0,
6321 };
6322 ip6_address_t v6_next_hop_address = { {0} };
6323 int count = 1;
6324 int j;
6325 f64 before = 0;
6326 u32 classify_table_index = ~0;
6327 u8 is_classify = 0;
6328 u8 resolve_host = 0, resolve_attached = 0;
6329 mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6330 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6331 mpls_label_t *next_hop_out_label_stack = NULL;
6332 mpls_label_t local_label = MPLS_LABEL_INVALID;
6333 u8 is_eos = 0;
6334 u8 next_hop_proto_is_ip4 = 1;
6335
6336 /* Parse args required to build the message */
6337 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6338 {
6339 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6340 ;
6341 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6342 ;
6343 else if (unformat (i, "%d", &local_label))
6344 ;
6345 else if (unformat (i, "eos"))
6346 is_eos = 1;
6347 else if (unformat (i, "non-eos"))
6348 is_eos = 0;
6349 else if (unformat (i, "via %U", unformat_ip4_address,
6350 &v4_next_hop_address))
6351 {
6352 next_hop_set = 1;
6353 next_hop_proto_is_ip4 = 1;
6354 }
6355 else if (unformat (i, "via %U", unformat_ip6_address,
6356 &v6_next_hop_address))
6357 {
6358 next_hop_set = 1;
6359 next_hop_proto_is_ip4 = 0;
6360 }
6361 else if (unformat (i, "weight %d", &next_hop_weight))
6362 ;
6363 else if (unformat (i, "create-table"))
6364 create_table_if_needed = 1;
6365 else if (unformat (i, "classify %d", &classify_table_index))
6366 {
6367 is_classify = 1;
6368 }
6369 else if (unformat (i, "del"))
6370 is_add = 0;
6371 else if (unformat (i, "add"))
6372 is_add = 1;
6373 else if (unformat (i, "resolve-via-host"))
6374 resolve_host = 1;
6375 else if (unformat (i, "resolve-via-attached"))
6376 resolve_attached = 1;
6377 else if (unformat (i, "multipath"))
6378 is_multipath = 1;
6379 else if (unformat (i, "count %d", &count))
6380 ;
6381 else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6382 {
6383 next_hop_set = 1;
6384 next_hop_proto_is_ip4 = 1;
6385 }
6386 else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6387 {
6388 next_hop_set = 1;
6389 next_hop_proto_is_ip4 = 0;
6390 }
6391 else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6392 ;
6393 else if (unformat (i, "via-label %d", &next_hop_via_label))
6394 ;
6395 else if (unformat (i, "out-label %d", &next_hop_out_label))
6396 vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6397 else
6398 {
6399 clib_warning ("parse error '%U'", format_unformat_error, i);
6400 return -99;
6401 }
6402 }
6403
6404 if (!next_hop_set && !is_classify)
6405 {
6406 errmsg ("next hop / classify not set");
6407 return -99;
6408 }
6409
6410 if (MPLS_LABEL_INVALID == local_label)
6411 {
6412 errmsg ("missing label");
6413 return -99;
6414 }
6415
6416 if (count > 1)
6417 {
6418 /* Turn on async mode */
6419 vam->async_mode = 1;
6420 vam->async_errors = 0;
6421 before = vat_time_now (vam);
6422 }
6423
6424 for (j = 0; j < count; j++)
6425 {
6426 /* Construct the API message */
6427 M2 (MPLS_ROUTE_ADD_DEL, mpls_route_add_del,
6428 sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6429
6430 mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6431 mp->mr_table_id = ntohl (table_id);
6432 mp->mr_create_table_if_needed = create_table_if_needed;
6433
6434 mp->mr_is_add = is_add;
6435 mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6436 mp->mr_is_classify = is_classify;
6437 mp->mr_is_multipath = is_multipath;
6438 mp->mr_is_resolve_host = resolve_host;
6439 mp->mr_is_resolve_attached = resolve_attached;
6440 mp->mr_next_hop_weight = next_hop_weight;
6441 mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6442 mp->mr_classify_table_index = ntohl (classify_table_index);
6443 mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6444 mp->mr_label = ntohl (local_label);
6445 mp->mr_eos = is_eos;
6446
6447 mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6448 if (0 != mp->mr_next_hop_n_out_labels)
6449 {
6450 memcpy (mp->mr_next_hop_out_label_stack,
6451 next_hop_out_label_stack,
6452 vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6453 vec_free (next_hop_out_label_stack);
6454 }
6455
6456 if (next_hop_set)
6457 {
6458 if (next_hop_proto_is_ip4)
6459 {
6460 clib_memcpy (mp->mr_next_hop,
6461 &v4_next_hop_address,
6462 sizeof (v4_next_hop_address));
6463 }
6464 else
6465 {
6466 clib_memcpy (mp->mr_next_hop,
6467 &v6_next_hop_address,
6468 sizeof (v6_next_hop_address));
6469 }
6470 }
6471 local_label++;
6472
6473 /* send it... */
6474 S;
6475 /* If we receive SIGTERM, stop now... */
6476 if (vam->do_exit)
6477 break;
6478 }
6479
6480 /* When testing multiple add/del ops, use a control-ping to sync */
6481 if (count > 1)
6482 {
6483 vl_api_control_ping_t *mp;
6484 f64 after;
6485
6486 /* Shut off async mode */
6487 vam->async_mode = 0;
6488
6489 M (CONTROL_PING, control_ping);
6490 S;
6491
6492 timeout = vat_time_now (vam) + 1.0;
6493 while (vat_time_now (vam) < timeout)
6494 if (vam->result_ready == 1)
6495 goto out;
6496 vam->retval = -99;
6497
6498 out:
6499 if (vam->retval == -99)
6500 errmsg ("timeout");
6501
6502 if (vam->async_errors > 0)
6503 {
6504 errmsg ("%d asynchronous errors", vam->async_errors);
6505 vam->retval = -98;
6506 }
6507 vam->async_errors = 0;
6508 after = vat_time_now (vam);
6509
6510 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6511 if (j > 0)
6512 count = j;
6513
6514 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6515 count, after - before, count / (after - before));
6516 }
6517 else
6518 {
6519 /* Wait for a reply... */
6520 W;
6521 }
6522
6523 /* Return the good/bad news */
6524 return (vam->retval);
6525}
6526
6527static int
6528api_mpls_ip_bind_unbind (vat_main_t * vam)
6529{
6530 unformat_input_t *i = vam->input;
6531 vl_api_mpls_ip_bind_unbind_t *mp;
6532 f64 timeout;
6533 u32 ip_table_id = 0;
6534 u8 create_table_if_needed = 0;
6535 u8 is_bind = 1;
6536 u8 is_ip4 = 1;
6537 ip4_address_t v4_address;
6538 ip6_address_t v6_address;
6539 u32 address_length;
6540 u8 address_set = 0;
6541 mpls_label_t local_label = MPLS_LABEL_INVALID;
6542
6543 /* Parse args required to build the message */
6544 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6545 {
6546 if (unformat (i, "%U/%d", unformat_ip4_address,
6547 &v4_address, &address_length))
6548 {
6549 is_ip4 = 1;
6550 address_set = 1;
6551 }
6552 else if (unformat (i, "%U/%d", unformat_ip6_address,
6553 &v6_address, &address_length))
6554 {
6555 is_ip4 = 0;
6556 address_set = 1;
6557 }
6558 else if (unformat (i, "%d", &local_label))
6559 ;
6560 else if (unformat (i, "create-table"))
6561 create_table_if_needed = 1;
6562 else if (unformat (i, "table-id %d", &ip_table_id))
6563 ;
6564 else if (unformat (i, "unbind"))
6565 is_bind = 0;
6566 else if (unformat (i, "bind"))
6567 is_bind = 1;
6568 else
6569 {
6570 clib_warning ("parse error '%U'", format_unformat_error, i);
6571 return -99;
6572 }
6573 }
6574
6575 if (!address_set)
6576 {
6577 errmsg ("IP addres not set");
6578 return -99;
6579 }
6580
6581 if (MPLS_LABEL_INVALID == local_label)
6582 {
6583 errmsg ("missing label");
6584 return -99;
6585 }
6586
6587 /* Construct the API message */
6588 M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6589
6590 mp->mb_create_table_if_needed = create_table_if_needed;
6591 mp->mb_is_bind = is_bind;
6592 mp->mb_is_ip4 = is_ip4;
6593 mp->mb_ip_table_id = ntohl (ip_table_id);
6594 mp->mb_mpls_table_id = 0;
6595 mp->mb_label = ntohl (local_label);
6596 mp->mb_address_length = address_length;
6597
6598 if (is_ip4)
6599 clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6600 else
6601 clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6602
6603 /* send it... */
6604 S;
6605
6606 /* Wait for a reply... */
6607 W;
6608}
6609
6610static int
6611api_proxy_arp_add_del (vat_main_t * vam)
6612{
6613 unformat_input_t *i = vam->input;
6614 vl_api_proxy_arp_add_del_t *mp;
6615 f64 timeout;
6616 u32 vrf_id = 0;
6617 u8 is_add = 1;
6618 ip4_address_t lo, hi;
6619 u8 range_set = 0;
6620
6621 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6622 {
6623 if (unformat (i, "vrf %d", &vrf_id))
6624 ;
6625 else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6626 unformat_ip4_address, &hi))
6627 range_set = 1;
6628 else if (unformat (i, "del"))
6629 is_add = 0;
6630 else
6631 {
6632 clib_warning ("parse error '%U'", format_unformat_error, i);
6633 return -99;
6634 }
6635 }
6636
6637 if (range_set == 0)
6638 {
6639 errmsg ("address range not set");
6640 return -99;
6641 }
6642
6643 M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6644
6645 mp->vrf_id = ntohl (vrf_id);
6646 mp->is_add = is_add;
6647 clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6648 clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6649
6650 S;
6651 W;
6652 /* NOTREACHED */
6653 return 0;
6654}
6655
6656static int
6657api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6658{
6659 unformat_input_t *i = vam->input;
6660 vl_api_proxy_arp_intfc_enable_disable_t *mp;
6661 f64 timeout;
6662 u32 sw_if_index;
6663 u8 enable = 1;
6664 u8 sw_if_index_set = 0;
6665
6666 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6667 {
6668 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6669 sw_if_index_set = 1;
6670 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6671 sw_if_index_set = 1;
6672 else if (unformat (i, "enable"))
6673 enable = 1;
6674 else if (unformat (i, "disable"))
6675 enable = 0;
6676 else
6677 {
6678 clib_warning ("parse error '%U'", format_unformat_error, i);
6679 return -99;
6680 }
6681 }
6682
6683 if (sw_if_index_set == 0)
6684 {
6685 errmsg ("missing interface name or sw_if_index");
6686 return -99;
6687 }
6688
6689 M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6690
6691 mp->sw_if_index = ntohl (sw_if_index);
6692 mp->enable_disable = enable;
6693
6694 S;
6695 W;
6696 /* NOTREACHED */
6697 return 0;
6698}
6699
6700static int
6701api_mpls_tunnel_add_del (vat_main_t * vam)
6702{
6703 unformat_input_t *i = vam->input;
6704 vl_api_mpls_tunnel_add_del_t *mp;
6705 f64 timeout;
6706
6707 u8 is_add = 1;
6708 u8 l2_only = 0;
6709 u32 sw_if_index = ~0;
6710 u32 next_hop_sw_if_index = ~0;
6711 u32 next_hop_proto_is_ip4 = 1;
6712
6713 u32 next_hop_table_id = 0;
6714 ip4_address_t v4_next_hop_address = {
6715 .as_u32 = 0,
6716 };
6717 ip6_address_t v6_next_hop_address = { {0} };
6718 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
6719
6720 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6721 {
6722 if (unformat (i, "add"))
6723 is_add = 1;
6724 else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6725 is_add = 0;
6726 else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
6727 ;
6728 else if (unformat (i, "via %U",
6729 unformat_ip4_address, &v4_next_hop_address))
6730 {
6731 next_hop_proto_is_ip4 = 1;
6732 }
6733 else if (unformat (i, "via %U",
6734 unformat_ip6_address, &v6_next_hop_address))
6735 {
6736 next_hop_proto_is_ip4 = 0;
6737 }
6738 else if (unformat (i, "l2-only"))
6739 l2_only = 1;
6740 else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6741 ;
6742 else if (unformat (i, "out-label %d", &next_hop_out_label))
6743 vec_add1 (labels, ntohl (next_hop_out_label));
6744 else
6745 {
6746 clib_warning ("parse error '%U'", format_unformat_error, i);
6747 return -99;
6748 }
6749 }
6750
6751 M2 (MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del,
6752 sizeof (mpls_label_t) * vec_len (labels));
6753
6754 mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
6755 mp->mt_sw_if_index = ntohl (sw_if_index);
6756 mp->mt_is_add = is_add;
6757 mp->mt_l2_only = l2_only;
6758 mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
6759 mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6760
6761 mp->mt_next_hop_n_out_labels = vec_len (labels);
6762
6763 if (0 != mp->mt_next_hop_n_out_labels)
6764 {
6765 clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
6766 sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
6767 vec_free (labels);
6768 }
6769
6770 if (next_hop_proto_is_ip4)
6771 {
6772 clib_memcpy (mp->mt_next_hop,
6773 &v4_next_hop_address, sizeof (v4_next_hop_address));
6774 }
6775 else
6776 {
6777 clib_memcpy (mp->mt_next_hop,
6778 &v6_next_hop_address, sizeof (v6_next_hop_address));
6779 }
6780
6781 S;
6782 W;
6783 /* NOTREACHED */
6784 return 0;
6785}
6786
6787static int
6788api_sw_interface_set_unnumbered (vat_main_t * vam)
6789{
6790 unformat_input_t *i = vam->input;
6791 vl_api_sw_interface_set_unnumbered_t *mp;
6792 f64 timeout;
6793 u32 sw_if_index;
6794 u32 unnum_sw_index = ~0;
6795 u8 is_add = 1;
6796 u8 sw_if_index_set = 0;
6797
6798 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6799 {
6800 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6801 sw_if_index_set = 1;
6802 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6803 sw_if_index_set = 1;
6804 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6805 ;
6806 else if (unformat (i, "del"))
6807 is_add = 0;
6808 else
6809 {
6810 clib_warning ("parse error '%U'", format_unformat_error, i);
6811 return -99;
6812 }
6813 }
6814
6815 if (sw_if_index_set == 0)
6816 {
6817 errmsg ("missing interface name or sw_if_index");
6818 return -99;
6819 }
6820
6821 M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6822
6823 mp->sw_if_index = ntohl (sw_if_index);
6824 mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6825 mp->is_add = is_add;
6826
6827 S;
6828 W;
6829 /* NOTREACHED */
6830 return 0;
6831}
6832
6833static int
6834api_ip_neighbor_add_del (vat_main_t * vam)
6835{
6836 unformat_input_t *i = vam->input;
6837 vl_api_ip_neighbor_add_del_t *mp;
6838 f64 timeout;
6839 u32 sw_if_index;
6840 u8 sw_if_index_set = 0;
6841 u32 vrf_id = 0;
6842 u8 is_add = 1;
6843 u8 is_static = 0;
6844 u8 mac_address[6];
6845 u8 mac_set = 0;
6846 u8 v4_address_set = 0;
6847 u8 v6_address_set = 0;
6848 ip4_address_t v4address;
6849 ip6_address_t v6address;
6850
6851 memset (mac_address, 0, sizeof (mac_address));
6852
6853 /* Parse args required to build the message */
6854 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6855 {
6856 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6857 {
6858 mac_set = 1;
6859 }
6860 else if (unformat (i, "del"))
6861 is_add = 0;
6862 else
6863 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6864 sw_if_index_set = 1;
6865 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6866 sw_if_index_set = 1;
6867 else if (unformat (i, "is_static"))
6868 is_static = 1;
6869 else if (unformat (i, "vrf %d", &vrf_id))
6870 ;
6871 else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6872 v4_address_set = 1;
6873 else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6874 v6_address_set = 1;
6875 else
6876 {
6877 clib_warning ("parse error '%U'", format_unformat_error, i);
6878 return -99;
6879 }
6880 }
6881
6882 if (sw_if_index_set == 0)
6883 {
6884 errmsg ("missing interface name or sw_if_index");
6885 return -99;
6886 }
6887 if (v4_address_set && v6_address_set)
6888 {
6889 errmsg ("both v4 and v6 addresses set");
6890 return -99;
6891 }
6892 if (!v4_address_set && !v6_address_set)
6893 {
6894 errmsg ("no address set");
6895 return -99;
6896 }
6897
6898 /* Construct the API message */
6899 M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6900
6901 mp->sw_if_index = ntohl (sw_if_index);
6902 mp->is_add = is_add;
6903 mp->vrf_id = ntohl (vrf_id);
6904 mp->is_static = is_static;
6905 if (mac_set)
6906 clib_memcpy (mp->mac_address, mac_address, 6);
6907 if (v6_address_set)
6908 {
6909 mp->is_ipv6 = 1;
6910 clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6911 }
6912 else
6913 {
6914 /* mp->is_ipv6 = 0; via memset in M macro above */
6915 clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6916 }
6917
6918 /* send it... */
6919 S;
6920
6921 /* Wait for a reply, return good/bad news */
6922 W;
6923
6924 /* NOTREACHED */
6925 return 0;
6926}
6927
6928static int
6929api_reset_vrf (vat_main_t * vam)
6930{
6931 unformat_input_t *i = vam->input;
6932 vl_api_reset_vrf_t *mp;
6933 f64 timeout;
6934 u32 vrf_id = 0;
6935 u8 is_ipv6 = 0;
6936 u8 vrf_id_set = 0;
6937
6938 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6939 {
6940 if (unformat (i, "vrf %d", &vrf_id))
6941 vrf_id_set = 1;
6942 else if (unformat (i, "ipv6"))
6943 is_ipv6 = 1;
6944 else
6945 {
6946 clib_warning ("parse error '%U'", format_unformat_error, i);
6947 return -99;
6948 }
6949 }
6950
6951 if (vrf_id_set == 0)
6952 {
6953 errmsg ("missing vrf id");
6954 return -99;
6955 }
6956
6957 M (RESET_VRF, reset_vrf);
6958
6959 mp->vrf_id = ntohl (vrf_id);
6960 mp->is_ipv6 = is_ipv6;
6961
6962 S;
6963 W;
6964 /* NOTREACHED */
6965 return 0;
6966}
6967
6968static int
6969api_create_vlan_subif (vat_main_t * vam)
6970{
6971 unformat_input_t *i = vam->input;
6972 vl_api_create_vlan_subif_t *mp;
6973 f64 timeout;
6974 u32 sw_if_index;
6975 u8 sw_if_index_set = 0;
6976 u32 vlan_id;
6977 u8 vlan_id_set = 0;
6978
6979 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6980 {
6981 if (unformat (i, "sw_if_index %d", &sw_if_index))
6982 sw_if_index_set = 1;
6983 else
6984 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6985 sw_if_index_set = 1;
6986 else if (unformat (i, "vlan %d", &vlan_id))
6987 vlan_id_set = 1;
6988 else
6989 {
6990 clib_warning ("parse error '%U'", format_unformat_error, i);
6991 return -99;
6992 }
6993 }
6994
6995 if (sw_if_index_set == 0)
6996 {
6997 errmsg ("missing interface name or sw_if_index");
6998 return -99;
6999 }
7000
7001 if (vlan_id_set == 0)
7002 {
7003 errmsg ("missing vlan_id");
7004 return -99;
7005 }
7006 M (CREATE_VLAN_SUBIF, create_vlan_subif);
7007
7008 mp->sw_if_index = ntohl (sw_if_index);
7009 mp->vlan_id = ntohl (vlan_id);
7010
7011 S;
7012 W;
7013 /* NOTREACHED */
7014 return 0;
7015}
7016
7017#define foreach_create_subif_bit \
7018_(no_tags) \
7019_(one_tag) \
7020_(two_tags) \
7021_(dot1ad) \
7022_(exact_match) \
7023_(default_sub) \
7024_(outer_vlan_id_any) \
7025_(inner_vlan_id_any)
7026
7027static int
7028api_create_subif (vat_main_t * vam)
7029{
7030 unformat_input_t *i = vam->input;
7031 vl_api_create_subif_t *mp;
7032 f64 timeout;
7033 u32 sw_if_index;
7034 u8 sw_if_index_set = 0;
7035 u32 sub_id;
7036 u8 sub_id_set = 0;
7037 u32 no_tags = 0;
7038 u32 one_tag = 0;
7039 u32 two_tags = 0;
7040 u32 dot1ad = 0;
7041 u32 exact_match = 0;
7042 u32 default_sub = 0;
7043 u32 outer_vlan_id_any = 0;
7044 u32 inner_vlan_id_any = 0;
7045 u32 tmp;
7046 u16 outer_vlan_id = 0;
7047 u16 inner_vlan_id = 0;
7048
7049 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7050 {
7051 if (unformat (i, "sw_if_index %d", &sw_if_index))
7052 sw_if_index_set = 1;
7053 else
7054 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7055 sw_if_index_set = 1;
7056 else if (unformat (i, "sub_id %d", &sub_id))
7057 sub_id_set = 1;
7058 else if (unformat (i, "outer_vlan_id %d", &tmp))
7059 outer_vlan_id = tmp;
7060 else if (unformat (i, "inner_vlan_id %d", &tmp))
7061 inner_vlan_id = tmp;
7062
7063#define _(a) else if (unformat (i, #a)) a = 1 ;
7064 foreach_create_subif_bit
7065#undef _
7066 else
7067 {
7068 clib_warning ("parse error '%U'", format_unformat_error, i);
7069 return -99;
7070 }
7071 }
7072
7073 if (sw_if_index_set == 0)
7074 {
7075 errmsg ("missing interface name or sw_if_index");
7076 return -99;
7077 }
7078
7079 if (sub_id_set == 0)
7080 {
7081 errmsg ("missing sub_id");
7082 return -99;
7083 }
7084 M (CREATE_SUBIF, create_subif);
7085
7086 mp->sw_if_index = ntohl (sw_if_index);
7087 mp->sub_id = ntohl (sub_id);
7088
7089#define _(a) mp->a = a;
7090 foreach_create_subif_bit;
7091#undef _
7092
7093 mp->outer_vlan_id = ntohs (outer_vlan_id);
7094 mp->inner_vlan_id = ntohs (inner_vlan_id);
7095
7096 S;
7097 W;
7098 /* NOTREACHED */
7099 return 0;
7100}
7101
7102static int
7103api_oam_add_del (vat_main_t * vam)
7104{
7105 unformat_input_t *i = vam->input;
7106 vl_api_oam_add_del_t *mp;
7107 f64 timeout;
7108 u32 vrf_id = 0;
7109 u8 is_add = 1;
7110 ip4_address_t src, dst;
7111 u8 src_set = 0;
7112 u8 dst_set = 0;
7113
7114 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7115 {
7116 if (unformat (i, "vrf %d", &vrf_id))
7117 ;
7118 else if (unformat (i, "src %U", unformat_ip4_address, &src))
7119 src_set = 1;
7120 else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7121 dst_set = 1;
7122 else if (unformat (i, "del"))
7123 is_add = 0;
7124 else
7125 {
7126 clib_warning ("parse error '%U'", format_unformat_error, i);
7127 return -99;
7128 }
7129 }
7130
7131 if (src_set == 0)
7132 {
7133 errmsg ("missing src addr");
7134 return -99;
7135 }
7136
7137 if (dst_set == 0)
7138 {
7139 errmsg ("missing dst addr");
7140 return -99;
7141 }
7142
7143 M (OAM_ADD_DEL, oam_add_del);
7144
7145 mp->vrf_id = ntohl (vrf_id);
7146 mp->is_add = is_add;
7147 clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7148 clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7149
7150 S;
7151 W;
7152 /* NOTREACHED */
7153 return 0;
7154}
7155
7156static int
7157api_reset_fib (vat_main_t * vam)
7158{
7159 unformat_input_t *i = vam->input;
7160 vl_api_reset_fib_t *mp;
7161 f64 timeout;
7162 u32 vrf_id = 0;
7163 u8 is_ipv6 = 0;
7164 u8 vrf_id_set = 0;
7165
7166 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7167 {
7168 if (unformat (i, "vrf %d", &vrf_id))
7169 vrf_id_set = 1;
7170 else if (unformat (i, "ipv6"))
7171 is_ipv6 = 1;
7172 else
7173 {
7174 clib_warning ("parse error '%U'", format_unformat_error, i);
7175 return -99;
7176 }
7177 }
7178
7179 if (vrf_id_set == 0)
7180 {
7181 errmsg ("missing vrf id");
7182 return -99;
7183 }
7184
7185 M (RESET_FIB, reset_fib);
7186
7187 mp->vrf_id = ntohl (vrf_id);
7188 mp->is_ipv6 = is_ipv6;
7189
7190 S;
7191 W;
7192 /* NOTREACHED */
7193 return 0;
7194}
7195
7196static int
7197api_dhcp_proxy_config (vat_main_t * vam)
7198{
7199 unformat_input_t *i = vam->input;
7200 vl_api_dhcp_proxy_config_t *mp;
7201 f64 timeout;
7202 u32 vrf_id = 0;
7203 u8 is_add = 1;
7204 u8 insert_cid = 1;
7205 u8 v4_address_set = 0;
7206 u8 v6_address_set = 0;
7207 ip4_address_t v4address;
7208 ip6_address_t v6address;
7209 u8 v4_src_address_set = 0;
7210 u8 v6_src_address_set = 0;
7211 ip4_address_t v4srcaddress;
7212 ip6_address_t v6srcaddress;
7213
7214 /* Parse args required to build the message */
7215 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7216 {
7217 if (unformat (i, "del"))
7218 is_add = 0;
7219 else if (unformat (i, "vrf %d", &vrf_id))
7220 ;
7221 else if (unformat (i, "insert-cid %d", &insert_cid))
7222 ;
7223 else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7224 v4_address_set = 1;
7225 else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7226 v6_address_set = 1;
7227 else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7228 v4_src_address_set = 1;
7229 else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7230 v6_src_address_set = 1;
7231 else
7232 break;
7233 }
7234
7235 if (v4_address_set && v6_address_set)
7236 {
7237 errmsg ("both v4 and v6 server addresses set");
7238 return -99;
7239 }
7240 if (!v4_address_set && !v6_address_set)
7241 {
7242 errmsg ("no server addresses set");
7243 return -99;
7244 }
7245
7246 if (v4_src_address_set && v6_src_address_set)
7247 {
7248 errmsg ("both v4 and v6 src addresses set");
7249 return -99;
7250 }
7251 if (!v4_src_address_set && !v6_src_address_set)
7252 {
7253 errmsg ("no src addresses set");
7254 return -99;
7255 }
7256
7257 if (!(v4_src_address_set && v4_address_set) &&
7258 !(v6_src_address_set && v6_address_set))
7259 {
7260 errmsg ("no matching server and src addresses set");
7261 return -99;
7262 }
7263
7264 /* Construct the API message */
7265 M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7266
7267 mp->insert_circuit_id = insert_cid;
7268 mp->is_add = is_add;
7269 mp->vrf_id = ntohl (vrf_id);
7270 if (v6_address_set)
7271 {
7272 mp->is_ipv6 = 1;
7273 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7274 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7275 }
7276 else
7277 {
7278 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7279 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7280 }
7281
7282 /* send it... */
7283 S;
7284
7285 /* Wait for a reply, return good/bad news */
7286 W;
7287 /* NOTREACHED */
7288 return 0;
7289}
7290
7291static int
7292api_dhcp_proxy_config_2 (vat_main_t * vam)
7293{
7294 unformat_input_t *i = vam->input;
7295 vl_api_dhcp_proxy_config_2_t *mp;
7296 f64 timeout;
7297 u32 rx_vrf_id = 0;
7298 u32 server_vrf_id = 0;
7299 u8 is_add = 1;
7300 u8 insert_cid = 1;
7301 u8 v4_address_set = 0;
7302 u8 v6_address_set = 0;
7303 ip4_address_t v4address;
7304 ip6_address_t v6address;
7305 u8 v4_src_address_set = 0;
7306 u8 v6_src_address_set = 0;
7307 ip4_address_t v4srcaddress;
7308 ip6_address_t v6srcaddress;
7309
7310 /* Parse args required to build the message */
7311 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7312 {
7313 if (unformat (i, "del"))
7314 is_add = 0;
7315 else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7316 ;
7317 else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7318 ;
7319 else if (unformat (i, "insert-cid %d", &insert_cid))
7320 ;
7321 else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7322 v4_address_set = 1;
7323 else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7324 v6_address_set = 1;
7325 else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7326 v4_src_address_set = 1;
7327 else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7328 v6_src_address_set = 1;
7329 else
7330 break;
7331 }
7332
7333 if (v4_address_set && v6_address_set)
7334 {
7335 errmsg ("both v4 and v6 server addresses set");
7336 return -99;
7337 }
7338 if (!v4_address_set && !v6_address_set)
7339 {
7340 errmsg ("no server addresses set");
7341 return -99;
7342 }
7343
7344 if (v4_src_address_set && v6_src_address_set)
7345 {
7346 errmsg ("both v4 and v6 src addresses set");
7347 return -99;
7348 }
7349 if (!v4_src_address_set && !v6_src_address_set)
7350 {
7351 errmsg ("no src addresses set");
7352 return -99;
7353 }
7354
7355 if (!(v4_src_address_set && v4_address_set) &&
7356 !(v6_src_address_set && v6_address_set))
7357 {
7358 errmsg ("no matching server and src addresses set");
7359 return -99;
7360 }
7361
7362 /* Construct the API message */
7363 M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7364
7365 mp->insert_circuit_id = insert_cid;
7366 mp->is_add = is_add;
7367 mp->rx_vrf_id = ntohl (rx_vrf_id);
7368 mp->server_vrf_id = ntohl (server_vrf_id);
7369 if (v6_address_set)
7370 {
7371 mp->is_ipv6 = 1;
7372 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7373 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7374 }
7375 else
7376 {
7377 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7378 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7379 }
7380
7381 /* send it... */
7382 S;
7383
7384 /* Wait for a reply, return good/bad news */
7385 W;
7386 /* NOTREACHED */
7387 return 0;
7388}
7389
7390static int
7391api_dhcp_proxy_set_vss (vat_main_t * vam)
7392{
7393 unformat_input_t *i = vam->input;
7394 vl_api_dhcp_proxy_set_vss_t *mp;
7395 f64 timeout;
7396 u8 is_ipv6 = 0;
7397 u8 is_add = 1;
7398 u32 tbl_id;
7399 u8 tbl_id_set = 0;
7400 u32 oui;
7401 u8 oui_set = 0;
7402 u32 fib_id;
7403 u8 fib_id_set = 0;
7404
7405 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7406 {
7407 if (unformat (i, "tbl_id %d", &tbl_id))
7408 tbl_id_set = 1;
7409 if (unformat (i, "fib_id %d", &fib_id))
7410 fib_id_set = 1;
7411 if (unformat (i, "oui %d", &oui))
7412 oui_set = 1;
7413 else if (unformat (i, "ipv6"))
7414 is_ipv6 = 1;
7415 else if (unformat (i, "del"))
7416 is_add = 0;
7417 else
7418 {
7419 clib_warning ("parse error '%U'", format_unformat_error, i);
7420 return -99;
7421 }
7422 }
7423
7424 if (tbl_id_set == 0)
7425 {
7426 errmsg ("missing tbl id");
7427 return -99;
7428 }
7429
7430 if (fib_id_set == 0)
7431 {
7432 errmsg ("missing fib id");
7433 return -99;
7434 }
7435 if (oui_set == 0)
7436 {
7437 errmsg ("missing oui");
7438 return -99;
7439 }
7440
7441 M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7442 mp->tbl_id = ntohl (tbl_id);
7443 mp->fib_id = ntohl (fib_id);
7444 mp->oui = ntohl (oui);
7445 mp->is_ipv6 = is_ipv6;
7446 mp->is_add = is_add;
7447
7448 S;
7449 W;
7450 /* NOTREACHED */
7451 return 0;
7452}
7453
7454static int
7455api_dhcp_client_config (vat_main_t * vam)
7456{
7457 unformat_input_t *i = vam->input;
7458 vl_api_dhcp_client_config_t *mp;
7459 f64 timeout;
7460 u32 sw_if_index;
7461 u8 sw_if_index_set = 0;
7462 u8 is_add = 1;
7463 u8 *hostname = 0;
7464 u8 disable_event = 0;
7465
7466 /* Parse args required to build the message */
7467 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7468 {
7469 if (unformat (i, "del"))
7470 is_add = 0;
7471 else
7472 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7473 sw_if_index_set = 1;
7474 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7475 sw_if_index_set = 1;
7476 else if (unformat (i, "hostname %s", &hostname))
7477 ;
7478 else if (unformat (i, "disable_event"))
7479 disable_event = 1;
7480 else
7481 break;
7482 }
7483
7484 if (sw_if_index_set == 0)
7485 {
7486 errmsg ("missing interface name or sw_if_index");
7487 return -99;
7488 }
7489
7490 if (vec_len (hostname) > 63)
7491 {
7492 errmsg ("hostname too long");
7493 }
7494 vec_add1 (hostname, 0);
7495
7496 /* Construct the API message */
7497 M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7498
7499 mp->sw_if_index = ntohl (sw_if_index);
7500 clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7501 vec_free (hostname);
7502 mp->is_add = is_add;
7503 mp->want_dhcp_event = disable_event ? 0 : 1;
7504 mp->pid = getpid ();
7505
7506 /* send it... */
7507 S;
7508
7509 /* Wait for a reply, return good/bad news */
7510 W;
7511 /* NOTREACHED */
7512 return 0;
7513}
7514
7515static int
7516api_set_ip_flow_hash (vat_main_t * vam)
7517{
7518 unformat_input_t *i = vam->input;
7519 vl_api_set_ip_flow_hash_t *mp;
7520 f64 timeout;
7521 u32 vrf_id = 0;
7522 u8 is_ipv6 = 0;
7523 u8 vrf_id_set = 0;
7524 u8 src = 0;
7525 u8 dst = 0;
7526 u8 sport = 0;
7527 u8 dport = 0;
7528 u8 proto = 0;
7529 u8 reverse = 0;
7530
7531 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7532 {
7533 if (unformat (i, "vrf %d", &vrf_id))
7534 vrf_id_set = 1;
7535 else if (unformat (i, "ipv6"))
7536 is_ipv6 = 1;
7537 else if (unformat (i, "src"))
7538 src = 1;
7539 else if (unformat (i, "dst"))
7540 dst = 1;
7541 else if (unformat (i, "sport"))
7542 sport = 1;
7543 else if (unformat (i, "dport"))
7544 dport = 1;
7545 else if (unformat (i, "proto"))
7546 proto = 1;
7547 else if (unformat (i, "reverse"))
7548 reverse = 1;
7549
7550 else
7551 {
7552 clib_warning ("parse error '%U'", format_unformat_error, i);
7553 return -99;
7554 }
7555 }
7556
7557 if (vrf_id_set == 0)
7558 {
7559 errmsg ("missing vrf id");
7560 return -99;
7561 }
7562
7563 M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7564 mp->src = src;
7565 mp->dst = dst;
7566 mp->sport = sport;
7567 mp->dport = dport;
7568 mp->proto = proto;
7569 mp->reverse = reverse;
7570 mp->vrf_id = ntohl (vrf_id);
7571 mp->is_ipv6 = is_ipv6;
7572
7573 S;
7574 W;
7575 /* NOTREACHED */
7576 return 0;
7577}
7578
7579static int
7580api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7581{
7582 unformat_input_t *i = vam->input;
7583 vl_api_sw_interface_ip6_enable_disable_t *mp;
7584 f64 timeout;
7585 u32 sw_if_index;
7586 u8 sw_if_index_set = 0;
7587 u8 enable = 0;
7588
7589 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7590 {
7591 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7592 sw_if_index_set = 1;
7593 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7594 sw_if_index_set = 1;
7595 else if (unformat (i, "enable"))
7596 enable = 1;
7597 else if (unformat (i, "disable"))
7598 enable = 0;
7599 else
7600 {
7601 clib_warning ("parse error '%U'", format_unformat_error, i);
7602 return -99;
7603 }
7604 }
7605
7606 if (sw_if_index_set == 0)
7607 {
7608 errmsg ("missing interface name or sw_if_index");
7609 return -99;
7610 }
7611
7612 M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7613
7614 mp->sw_if_index = ntohl (sw_if_index);
7615 mp->enable = enable;
7616
7617 S;
7618 W;
7619 /* NOTREACHED */
7620 return 0;
7621}
7622
7623static int
7624api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7625{
7626 unformat_input_t *i = vam->input;
7627 vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7628 f64 timeout;
7629 u32 sw_if_index;
7630 u8 sw_if_index_set = 0;
7631 u32 address_length = 0;
7632 u8 v6_address_set = 0;
7633 ip6_address_t v6address;
7634
7635 /* Parse args required to build the message */
7636 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7637 {
7638 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7639 sw_if_index_set = 1;
7640 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7641 sw_if_index_set = 1;
7642 else if (unformat (i, "%U/%d",
7643 unformat_ip6_address, &v6address, &address_length))
7644 v6_address_set = 1;
7645 else
7646 break;
7647 }
7648
7649 if (sw_if_index_set == 0)
7650 {
7651 errmsg ("missing interface name or sw_if_index");
7652 return -99;
7653 }
7654 if (!v6_address_set)
7655 {
7656 errmsg ("no address set");
7657 return -99;
7658 }
7659
7660 /* Construct the API message */
7661 M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7662 sw_interface_ip6_set_link_local_address);
7663
7664 mp->sw_if_index = ntohl (sw_if_index);
7665 clib_memcpy (mp->address, &v6address, sizeof (v6address));
7666 mp->address_length = address_length;
7667
7668 /* send it... */
7669 S;
7670
7671 /* Wait for a reply, return good/bad news */
7672 W;
7673
7674 /* NOTREACHED */
7675 return 0;
7676}
7677
7678
7679static int
7680api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7681{
7682 unformat_input_t *i = vam->input;
7683 vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7684 f64 timeout;
7685 u32 sw_if_index;
7686 u8 sw_if_index_set = 0;
7687 u32 address_length = 0;
7688 u8 v6_address_set = 0;
7689 ip6_address_t v6address;
7690 u8 use_default = 0;
7691 u8 no_advertise = 0;
7692 u8 off_link = 0;
7693 u8 no_autoconfig = 0;
7694 u8 no_onlink = 0;
7695 u8 is_no = 0;
7696 u32 val_lifetime = 0;
7697 u32 pref_lifetime = 0;
7698
7699 /* Parse args required to build the message */
7700 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7701 {
7702 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7703 sw_if_index_set = 1;
7704 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7705 sw_if_index_set = 1;
7706 else if (unformat (i, "%U/%d",
7707 unformat_ip6_address, &v6address, &address_length))
7708 v6_address_set = 1;
7709 else if (unformat (i, "val_life %d", &val_lifetime))
7710 ;
7711 else if (unformat (i, "pref_life %d", &pref_lifetime))
7712 ;
7713 else if (unformat (i, "def"))
7714 use_default = 1;
7715 else if (unformat (i, "noadv"))
7716 no_advertise = 1;
7717 else if (unformat (i, "offl"))
7718 off_link = 1;
7719 else if (unformat (i, "noauto"))
7720 no_autoconfig = 1;
7721 else if (unformat (i, "nolink"))
7722 no_onlink = 1;
7723 else if (unformat (i, "isno"))
7724 is_no = 1;
7725 else
7726 {
7727 clib_warning ("parse error '%U'", format_unformat_error, i);
7728 return -99;
7729 }
7730 }
7731
7732 if (sw_if_index_set == 0)
7733 {
7734 errmsg ("missing interface name or sw_if_index");
7735 return -99;
7736 }
7737 if (!v6_address_set)
7738 {
7739 errmsg ("no address set");
7740 return -99;
7741 }
7742
7743 /* Construct the API message */
7744 M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7745
7746 mp->sw_if_index = ntohl (sw_if_index);
7747 clib_memcpy (mp->address, &v6address, sizeof (v6address));
7748 mp->address_length = address_length;
7749 mp->use_default = use_default;
7750 mp->no_advertise = no_advertise;
7751 mp->off_link = off_link;
7752 mp->no_autoconfig = no_autoconfig;
7753 mp->no_onlink = no_onlink;
7754 mp->is_no = is_no;
7755 mp->val_lifetime = ntohl (val_lifetime);
7756 mp->pref_lifetime = ntohl (pref_lifetime);
7757
7758 /* send it... */
7759 S;
7760
7761 /* Wait for a reply, return good/bad news */
7762 W;
7763
7764 /* NOTREACHED */
7765 return 0;
7766}
7767
7768static int
7769api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7770{
7771 unformat_input_t *i = vam->input;
7772 vl_api_sw_interface_ip6nd_ra_config_t *mp;
7773 f64 timeout;
7774 u32 sw_if_index;
7775 u8 sw_if_index_set = 0;
7776 u8 suppress = 0;
7777 u8 managed = 0;
7778 u8 other = 0;
7779 u8 ll_option = 0;
7780 u8 send_unicast = 0;
7781 u8 cease = 0;
7782 u8 is_no = 0;
7783 u8 default_router = 0;
7784 u32 max_interval = 0;
7785 u32 min_interval = 0;
7786 u32 lifetime = 0;
7787 u32 initial_count = 0;
7788 u32 initial_interval = 0;
7789
7790
7791 /* Parse args required to build the message */
7792 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7793 {
7794 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7795 sw_if_index_set = 1;
7796 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7797 sw_if_index_set = 1;
7798 else if (unformat (i, "maxint %d", &max_interval))
7799 ;
7800 else if (unformat (i, "minint %d", &min_interval))
7801 ;
7802 else if (unformat (i, "life %d", &lifetime))
7803 ;
7804 else if (unformat (i, "count %d", &initial_count))
7805 ;
7806 else if (unformat (i, "interval %d", &initial_interval))
7807 ;
7808 else if (unformat (i, "suppress") || unformat (i, "surpress"))
7809 suppress = 1;
7810 else if (unformat (i, "managed"))
7811 managed = 1;
7812 else if (unformat (i, "other"))
7813 other = 1;
7814 else if (unformat (i, "ll"))
7815 ll_option = 1;
7816 else if (unformat (i, "send"))
7817 send_unicast = 1;
7818 else if (unformat (i, "cease"))
7819 cease = 1;
7820 else if (unformat (i, "isno"))
7821 is_no = 1;
7822 else if (unformat (i, "def"))
7823 default_router = 1;
7824 else
7825 {
7826 clib_warning ("parse error '%U'", format_unformat_error, i);
7827 return -99;
7828 }
7829 }
7830
7831 if (sw_if_index_set == 0)
7832 {
7833 errmsg ("missing interface name or sw_if_index");
7834 return -99;
7835 }
7836
7837 /* Construct the API message */
7838 M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7839
7840 mp->sw_if_index = ntohl (sw_if_index);
7841 mp->max_interval = ntohl (max_interval);
7842 mp->min_interval = ntohl (min_interval);
7843 mp->lifetime = ntohl (lifetime);
7844 mp->initial_count = ntohl (initial_count);
7845 mp->initial_interval = ntohl (initial_interval);
7846 mp->suppress = suppress;
7847 mp->managed = managed;
7848 mp->other = other;
7849 mp->ll_option = ll_option;
7850 mp->send_unicast = send_unicast;
7851 mp->cease = cease;
7852 mp->is_no = is_no;
7853 mp->default_router = default_router;
7854
7855 /* send it... */
7856 S;
7857
7858 /* Wait for a reply, return good/bad news */
7859 W;
7860
7861 /* NOTREACHED */
7862 return 0;
7863}
7864
7865static int
7866api_set_arp_neighbor_limit (vat_main_t * vam)
7867{
7868 unformat_input_t *i = vam->input;
7869 vl_api_set_arp_neighbor_limit_t *mp;
7870 f64 timeout;
7871 u32 arp_nbr_limit;
7872 u8 limit_set = 0;
7873 u8 is_ipv6 = 0;
7874
7875 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7876 {
7877 if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7878 limit_set = 1;
7879 else if (unformat (i, "ipv6"))
7880 is_ipv6 = 1;
7881 else
7882 {
7883 clib_warning ("parse error '%U'", format_unformat_error, i);
7884 return -99;
7885 }
7886 }
7887
7888 if (limit_set == 0)
7889 {
7890 errmsg ("missing limit value");
7891 return -99;
7892 }
7893
7894 M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7895
7896 mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7897 mp->is_ipv6 = is_ipv6;
7898
7899 S;
7900 W;
7901 /* NOTREACHED */
7902 return 0;
7903}
7904
7905static int
7906api_l2_patch_add_del (vat_main_t * vam)
7907{
7908 unformat_input_t *i = vam->input;
7909 vl_api_l2_patch_add_del_t *mp;
7910 f64 timeout;
7911 u32 rx_sw_if_index;
7912 u8 rx_sw_if_index_set = 0;
7913 u32 tx_sw_if_index;
7914 u8 tx_sw_if_index_set = 0;
7915 u8 is_add = 1;
7916
7917 /* Parse args required to build the message */
7918 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7919 {
7920 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7921 rx_sw_if_index_set = 1;
7922 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7923 tx_sw_if_index_set = 1;
7924 else if (unformat (i, "rx"))
7925 {
7926 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7927 {
7928 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7929 &rx_sw_if_index))
7930 rx_sw_if_index_set = 1;
7931 }
7932 else
7933 break;
7934 }
7935 else if (unformat (i, "tx"))
7936 {
7937 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7938 {
7939 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7940 &tx_sw_if_index))
7941 tx_sw_if_index_set = 1;
7942 }
7943 else
7944 break;
7945 }
7946 else if (unformat (i, "del"))
7947 is_add = 0;
7948 else
7949 break;
7950 }
7951
7952 if (rx_sw_if_index_set == 0)
7953 {
7954 errmsg ("missing rx interface name or rx_sw_if_index");
7955 return -99;
7956 }
7957
7958 if (tx_sw_if_index_set == 0)
7959 {
7960 errmsg ("missing tx interface name or tx_sw_if_index");
7961 return -99;
7962 }
7963
7964 M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7965
7966 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7967 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7968 mp->is_add = is_add;
7969
7970 S;
7971 W;
7972 /* NOTREACHED */
7973 return 0;
7974}
7975
7976static int
7977api_ioam_enable (vat_main_t * vam)
7978{
7979 unformat_input_t *input = vam->input;
7980 vl_api_ioam_enable_t *mp;
7981 f64 timeout;
7982 u32 id = 0;
7983 int has_trace_option = 0;
7984 int has_pot_option = 0;
7985 int has_seqno_option = 0;
7986 int has_analyse_option = 0;
7987
7988 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7989 {
7990 if (unformat (input, "trace"))
7991 has_trace_option = 1;
7992 else if (unformat (input, "pot"))
7993 has_pot_option = 1;
7994 else if (unformat (input, "seqno"))
7995 has_seqno_option = 1;
7996 else if (unformat (input, "analyse"))
7997 has_analyse_option = 1;
7998 else
7999 break;
8000 }
8001 M (IOAM_ENABLE, ioam_enable);
8002 mp->id = htons (id);
8003 mp->seqno = has_seqno_option;
8004 mp->analyse = has_analyse_option;
8005 mp->pot_enable = has_pot_option;
8006 mp->trace_enable = has_trace_option;
8007
8008 S;
8009 W;
8010
8011 return (0);
8012
8013}
8014
8015
8016static int
8017api_ioam_disable (vat_main_t * vam)
8018{
8019 vl_api_ioam_disable_t *mp;
8020 f64 timeout;
8021
8022 M (IOAM_DISABLE, ioam_disable);
8023 S;
8024 W;
8025 return 0;
8026}
8027
8028static int
8029api_sr_tunnel_add_del (vat_main_t * vam)
8030{
8031 unformat_input_t *i = vam->input;
8032 vl_api_sr_tunnel_add_del_t *mp;
8033 f64 timeout;
8034 int is_del = 0;
8035 int pl_index;
8036 ip6_address_t src_address;
8037 int src_address_set = 0;
8038 ip6_address_t dst_address;
8039 u32 dst_mask_width;
8040 int dst_address_set = 0;
8041 u16 flags = 0;
8042 u32 rx_table_id = 0;
8043 u32 tx_table_id = 0;
8044 ip6_address_t *segments = 0;
8045 ip6_address_t *this_seg;
8046 ip6_address_t *tags = 0;
8047 ip6_address_t *this_tag;
8048 ip6_address_t next_address, tag;
8049 u8 *name = 0;
8050 u8 *policy_name = 0;
8051
8052 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8053 {
8054 if (unformat (i, "del"))
8055 is_del = 1;
8056 else if (unformat (i, "name %s", &name))
8057 ;
8058 else if (unformat (i, "policy %s", &policy_name))
8059 ;
8060 else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8061 ;
8062 else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8063 ;
8064 else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8065 src_address_set = 1;
8066 else if (unformat (i, "dst %U/%d",
8067 unformat_ip6_address, &dst_address, &dst_mask_width))
8068 dst_address_set = 1;
8069 else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8070 {
8071 vec_add2 (segments, this_seg, 1);
8072 clib_memcpy (this_seg->as_u8, next_address.as_u8,
8073 sizeof (*this_seg));
8074 }
8075 else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8076 {
8077 vec_add2 (tags, this_tag, 1);
8078 clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8079 }
8080 else if (unformat (i, "clean"))
8081 flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8082 else if (unformat (i, "protected"))
8083 flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8084 else if (unformat (i, "InPE %d", &pl_index))
8085 {
8086 if (pl_index <= 0 || pl_index > 4)
8087 {
8088 pl_index_range_error:
8089 errmsg ("pl index %d out of range", pl_index);
8090 return -99;
8091 }
8092 flags |=
8093 IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8094 }
8095 else if (unformat (i, "EgPE %d", &pl_index))
8096 {
8097 if (pl_index <= 0 || pl_index > 4)
8098 goto pl_index_range_error;
8099 flags |=
8100 IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8101 }
8102 else if (unformat (i, "OrgSrc %d", &pl_index))
8103 {
8104 if (pl_index <= 0 || pl_index > 4)
8105 goto pl_index_range_error;
8106 flags |=
8107 IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8108 }
8109 else
8110 break;
8111 }
8112
8113 if (!src_address_set)
8114 {
8115 errmsg ("src address required");
8116 return -99;
8117 }
8118
8119 if (!dst_address_set)
8120 {
8121 errmsg ("dst address required");
8122 return -99;
8123 }
8124
8125 if (!segments)
8126 {
8127 errmsg ("at least one sr segment required");
8128 return -99;
8129 }
8130
8131 M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
8132 vec_len (segments) * sizeof (ip6_address_t)
8133 + vec_len (tags) * sizeof (ip6_address_t));
8134
8135 clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8136 clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8137 mp->dst_mask_width = dst_mask_width;
8138 mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8139 mp->n_segments = vec_len (segments);
8140 mp->n_tags = vec_len (tags);
8141 mp->is_add = is_del == 0;
8142 clib_memcpy (mp->segs_and_tags, segments,
8143 vec_len (segments) * sizeof (ip6_address_t));
8144 clib_memcpy (mp->segs_and_tags +
8145 vec_len (segments) * sizeof (ip6_address_t), tags,
8146 vec_len (tags) * sizeof (ip6_address_t));
8147
8148 mp->outer_vrf_id = ntohl (rx_table_id);
8149 mp->inner_vrf_id = ntohl (tx_table_id);
8150 memcpy (mp->name, name, vec_len (name));
8151 memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8152
8153 vec_free (segments);
8154 vec_free (tags);
8155
8156 S;
8157 W;
8158 /* NOTREACHED */
8159}
8160
8161static int
8162api_sr_policy_add_del (vat_main_t * vam)
8163{
8164 unformat_input_t *input = vam->input;
8165 vl_api_sr_policy_add_del_t *mp;
8166 f64 timeout;
8167 int is_del = 0;
8168 u8 *name = 0;
8169 u8 *tunnel_name = 0;
8170 u8 **tunnel_names = 0;
8171
8172 int name_set = 0;
8173 int tunnel_set = 0;
8174 int j = 0;
8175 int tunnel_names_length = 1; // Init to 1 to offset the #tunnel_names counter byte
8176 int tun_name_len = 0; // Different naming convention used as confusing these would be "bad" (TM)
8177
8178 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8179 {
8180 if (unformat (input, "del"))
8181 is_del = 1;
8182 else if (unformat (input, "name %s", &name))
8183 name_set = 1;
8184 else if (unformat (input, "tunnel %s", &tunnel_name))
8185 {
8186 if (tunnel_name)
8187 {
8188 vec_add1 (tunnel_names, tunnel_name);
8189 /* For serializer:
8190 - length = #bytes to store in serial vector
8191 - +1 = byte to store that length
8192 */
8193 tunnel_names_length += (vec_len (tunnel_name) + 1);
8194 tunnel_set = 1;
8195 tunnel_name = 0;
8196 }
8197 }
8198 else
8199 break;
8200 }
8201
8202 if (!name_set)
8203 {
8204 errmsg ("policy name required");
8205 return -99;
8206 }
8207
8208 if ((!tunnel_set) && (!is_del))
8209 {
8210 errmsg ("tunnel name required");
8211 return -99;
8212 }
8213
8214 M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8215
8216
8217
8218 mp->is_add = !is_del;
8219
8220 memcpy (mp->name, name, vec_len (name));
8221 // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8222 u8 *serial_orig = 0;
8223 vec_validate (serial_orig, tunnel_names_length);
8224 *serial_orig = vec_len (tunnel_names); // Store the number of tunnels as length in first byte of serialized vector
8225 serial_orig += 1; // Move along one byte to store the length of first tunnel_name
8226
8227 for (j = 0; j < vec_len (tunnel_names); j++)
8228 {
8229 tun_name_len = vec_len (tunnel_names[j]);
8230 *serial_orig = tun_name_len; // Store length of tunnel name in first byte of Length/Value pair
8231 serial_orig += 1; // Move along one byte to store the actual tunnel name
8232 memcpy (serial_orig, tunnel_names[j], tun_name_len);
8233 serial_orig += tun_name_len; // Advance past the copy
8234 }
8235 memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length); // Regress serial_orig to head then copy fwd
8236
8237 vec_free (tunnel_names);
8238 vec_free (tunnel_name);
8239
8240 S;
8241 W;
8242 /* NOTREACHED */
8243}
8244
8245static int
8246api_sr_multicast_map_add_del (vat_main_t * vam)
8247{
8248 unformat_input_t *input = vam->input;
8249 vl_api_sr_multicast_map_add_del_t *mp;
8250 f64 timeout;
8251 int is_del = 0;
8252 ip6_address_t multicast_address;
8253 u8 *policy_name = 0;
8254 int multicast_address_set = 0;
8255
8256 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8257 {
8258 if (unformat (input, "del"))
8259 is_del = 1;
8260 else
8261 if (unformat
8262 (input, "address %U", unformat_ip6_address, &multicast_address))
8263 multicast_address_set = 1;
8264 else if (unformat (input, "sr-policy %s", &policy_name))
8265 ;
8266 else
8267 break;
8268 }
8269
8270 if (!is_del && !policy_name)
8271 {
8272 errmsg ("sr-policy name required");
8273 return -99;
8274 }
8275
8276
8277 if (!multicast_address_set)
8278 {
8279 errmsg ("address required");
8280 return -99;
8281 }
8282
8283 M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8284
8285 mp->is_add = !is_del;
8286 memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8287 clib_memcpy (mp->multicast_address, &multicast_address,
8288 sizeof (mp->multicast_address));
8289
8290
8291 vec_free (policy_name);
8292
8293 S;
8294 W;
8295 /* NOTREACHED */
8296}
8297
8298
8299#define foreach_tcp_proto_field \
8300_(src_port) \
8301_(dst_port)
8302
8303#define foreach_udp_proto_field \
8304_(src_port) \
8305_(dst_port)
8306
8307#define foreach_ip4_proto_field \
8308_(src_address) \
8309_(dst_address) \
8310_(tos) \
8311_(length) \
8312_(fragment_id) \
8313_(ttl) \
8314_(protocol) \
8315_(checksum)
8316
8317uword
8318unformat_tcp_mask (unformat_input_t * input, va_list * args)
8319{
8320 u8 **maskp = va_arg (*args, u8 **);
8321 u8 *mask = 0;
8322 u8 found_something = 0;
8323 tcp_header_t *tcp;
8324
8325#define _(a) u8 a=0;
8326 foreach_tcp_proto_field;
8327#undef _
8328
8329 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8330 {
8331 if (0);
8332#define _(a) else if (unformat (input, #a)) a=1;
8333 foreach_tcp_proto_field
8334#undef _
8335 else
8336 break;
8337 }
8338
8339#define _(a) found_something += a;
8340 foreach_tcp_proto_field;
8341#undef _
8342
8343 if (found_something == 0)
8344 return 0;
8345
8346 vec_validate (mask, sizeof (*tcp) - 1);
8347
8348 tcp = (tcp_header_t *) mask;
8349
8350#define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8351 foreach_tcp_proto_field;
8352#undef _
8353
8354 *maskp = mask;
8355 return 1;
8356}
8357
8358uword
8359unformat_udp_mask (unformat_input_t * input, va_list * args)
8360{
8361 u8 **maskp = va_arg (*args, u8 **);
8362 u8 *mask = 0;
8363 u8 found_something = 0;
8364 udp_header_t *udp;
8365
8366#define _(a) u8 a=0;
8367 foreach_udp_proto_field;
8368#undef _
8369
8370 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8371 {
8372 if (0);
8373#define _(a) else if (unformat (input, #a)) a=1;
8374 foreach_udp_proto_field
8375#undef _
8376 else
8377 break;
8378 }
8379
8380#define _(a) found_something += a;
8381 foreach_udp_proto_field;
8382#undef _
8383
8384 if (found_something == 0)
8385 return 0;
8386
8387 vec_validate (mask, sizeof (*udp) - 1);
8388
8389 udp = (udp_header_t *) mask;
8390
8391#define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8392 foreach_udp_proto_field;
8393#undef _
8394
8395 *maskp = mask;
8396 return 1;
8397}
8398
8399typedef struct
8400{
8401 u16 src_port, dst_port;
8402} tcpudp_header_t;
8403
8404uword
8405unformat_l4_mask (unformat_input_t * input, va_list * args)
8406{
8407 u8 **maskp = va_arg (*args, u8 **);
8408 u16 src_port = 0, dst_port = 0;
8409 tcpudp_header_t *tcpudp;
8410
8411 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8412 {
8413 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8414 return 1;
8415 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8416 return 1;
8417 else if (unformat (input, "src_port"))
8418 src_port = 0xFFFF;
8419 else if (unformat (input, "dst_port"))
8420 dst_port = 0xFFFF;
8421 else
8422 return 0;
8423 }
8424
8425 if (!src_port && !dst_port)
8426 return 0;
8427
8428 u8 *mask = 0;
8429 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8430
8431 tcpudp = (tcpudp_header_t *) mask;
8432 tcpudp->src_port = src_port;
8433 tcpudp->dst_port = dst_port;
8434
8435 *maskp = mask;
8436
8437 return 1;
8438}
8439
8440uword
8441unformat_ip4_mask (unformat_input_t * input, va_list * args)
8442{
8443 u8 **maskp = va_arg (*args, u8 **);
8444 u8 *mask = 0;
8445 u8 found_something = 0;
8446 ip4_header_t *ip;
8447
8448#define _(a) u8 a=0;
8449 foreach_ip4_proto_field;
8450#undef _
8451 u8 version = 0;
8452 u8 hdr_length = 0;
8453
8454
8455 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8456 {
8457 if (unformat (input, "version"))
8458 version = 1;
8459 else if (unformat (input, "hdr_length"))
8460 hdr_length = 1;
8461 else if (unformat (input, "src"))
8462 src_address = 1;
8463 else if (unformat (input, "dst"))
8464 dst_address = 1;
8465 else if (unformat (input, "proto"))
8466 protocol = 1;
8467
8468#define _(a) else if (unformat (input, #a)) a=1;
8469 foreach_ip4_proto_field
8470#undef _
8471 else
8472 break;
8473 }
8474
8475#define _(a) found_something += a;
8476 foreach_ip4_proto_field;
8477#undef _
8478
8479 if (found_something == 0)
8480 return 0;
8481
8482 vec_validate (mask, sizeof (*ip) - 1);
8483
8484 ip = (ip4_header_t *) mask;
8485
8486#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8487 foreach_ip4_proto_field;
8488#undef _
8489
8490 ip->ip_version_and_header_length = 0;
8491
8492 if (version)
8493 ip->ip_version_and_header_length |= 0xF0;
8494
8495 if (hdr_length)
8496 ip->ip_version_and_header_length |= 0x0F;
8497
8498 *maskp = mask;
8499 return 1;
8500}
8501
8502#define foreach_ip6_proto_field \
8503_(src_address) \
8504_(dst_address) \
8505_(payload_length) \
8506_(hop_limit) \
8507_(protocol)
8508
8509uword
8510unformat_ip6_mask (unformat_input_t * input, va_list * args)
8511{
8512 u8 **maskp = va_arg (*args, u8 **);
8513 u8 *mask = 0;
8514 u8 found_something = 0;
8515 ip6_header_t *ip;
8516 u32 ip_version_traffic_class_and_flow_label;
8517
8518#define _(a) u8 a=0;
8519 foreach_ip6_proto_field;
8520#undef _
8521 u8 version = 0;
8522 u8 traffic_class = 0;
8523 u8 flow_label = 0;
8524
8525 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8526 {
8527 if (unformat (input, "version"))
8528 version = 1;
8529 else if (unformat (input, "traffic-class"))
8530 traffic_class = 1;
8531 else if (unformat (input, "flow-label"))
8532 flow_label = 1;
8533 else if (unformat (input, "src"))
8534 src_address = 1;
8535 else if (unformat (input, "dst"))
8536 dst_address = 1;
8537 else if (unformat (input, "proto"))
8538 protocol = 1;
8539
8540#define _(a) else if (unformat (input, #a)) a=1;
8541 foreach_ip6_proto_field
8542#undef _
8543 else
8544 break;
8545 }
8546
8547#define _(a) found_something += a;
8548 foreach_ip6_proto_field;
8549#undef _
8550
8551 if (found_something == 0)
8552 return 0;
8553
8554 vec_validate (mask, sizeof (*ip) - 1);
8555
8556 ip = (ip6_header_t *) mask;
8557
8558#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8559 foreach_ip6_proto_field;
8560#undef _
8561
8562 ip_version_traffic_class_and_flow_label = 0;
8563
8564 if (version)
8565 ip_version_traffic_class_and_flow_label |= 0xF0000000;
8566
8567 if (traffic_class)
8568 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8569
8570 if (flow_label)
8571 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8572
8573 ip->ip_version_traffic_class_and_flow_label =
8574 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8575
8576 *maskp = mask;
8577 return 1;
8578}
8579
8580uword
8581unformat_l3_mask (unformat_input_t * input, va_list * args)
8582{
8583 u8 **maskp = va_arg (*args, u8 **);
8584
8585 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8586 {
8587 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8588 return 1;
8589 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8590 return 1;
8591 else
8592 break;
8593 }
8594 return 0;
8595}
8596
8597uword
8598unformat_l2_mask (unformat_input_t * input, va_list * args)
8599{
8600 u8 **maskp = va_arg (*args, u8 **);
8601 u8 *mask = 0;
8602 u8 src = 0;
8603 u8 dst = 0;
8604 u8 proto = 0;
8605 u8 tag1 = 0;
8606 u8 tag2 = 0;
8607 u8 ignore_tag1 = 0;
8608 u8 ignore_tag2 = 0;
8609 u8 cos1 = 0;
8610 u8 cos2 = 0;
8611 u8 dot1q = 0;
8612 u8 dot1ad = 0;
8613 int len = 14;
8614
8615 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8616 {
8617 if (unformat (input, "src"))
8618 src = 1;
8619 else if (unformat (input, "dst"))
8620 dst = 1;
8621 else if (unformat (input, "proto"))
8622 proto = 1;
8623 else if (unformat (input, "tag1"))
8624 tag1 = 1;
8625 else if (unformat (input, "tag2"))
8626 tag2 = 1;
8627 else if (unformat (input, "ignore-tag1"))
8628 ignore_tag1 = 1;
8629 else if (unformat (input, "ignore-tag2"))
8630 ignore_tag2 = 1;
8631 else if (unformat (input, "cos1"))
8632 cos1 = 1;
8633 else if (unformat (input, "cos2"))
8634 cos2 = 1;
8635 else if (unformat (input, "dot1q"))
8636 dot1q = 1;
8637 else if (unformat (input, "dot1ad"))
8638 dot1ad = 1;
8639 else
8640 break;
8641 }
8642 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8643 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8644 return 0;
8645
8646 if (tag1 || ignore_tag1 || cos1 || dot1q)
8647 len = 18;
8648 if (tag2 || ignore_tag2 || cos2 || dot1ad)
8649 len = 22;
8650
8651 vec_validate (mask, len - 1);
8652
8653 if (dst)
8654 memset (mask, 0xff, 6);
8655
8656 if (src)
8657 memset (mask + 6, 0xff, 6);
8658
8659 if (tag2 || dot1ad)
8660 {
8661 /* inner vlan tag */
8662 if (tag2)
8663 {
8664 mask[19] = 0xff;
8665 mask[18] = 0x0f;
8666 }
8667 if (cos2)
8668 mask[18] |= 0xe0;
8669 if (proto)
8670 mask[21] = mask[20] = 0xff;
8671 if (tag1)
8672 {
8673 mask[15] = 0xff;
8674 mask[14] = 0x0f;
8675 }
8676 if (cos1)
8677 mask[14] |= 0xe0;
8678 *maskp = mask;
8679 return 1;
8680 }
8681 if (tag1 | dot1q)
8682 {
8683 if (tag1)
8684 {
8685 mask[15] = 0xff;
8686 mask[14] = 0x0f;
8687 }
8688 if (cos1)
8689 mask[14] |= 0xe0;
8690 if (proto)
8691 mask[16] = mask[17] = 0xff;
8692
8693 *maskp = mask;
8694 return 1;
8695 }
8696 if (cos2)
8697 mask[18] |= 0xe0;
8698 if (cos1)
8699 mask[14] |= 0xe0;
8700 if (proto)
8701 mask[12] = mask[13] = 0xff;
8702
8703 *maskp = mask;
8704 return 1;
8705}
8706
8707uword
8708unformat_classify_mask (unformat_input_t * input, va_list * args)
8709{
8710 u8 **maskp = va_arg (*args, u8 **);
8711 u32 *skipp = va_arg (*args, u32 *);
8712 u32 *matchp = va_arg (*args, u32 *);
8713 u32 match;
8714 u8 *mask = 0;
8715 u8 *l2 = 0;
8716 u8 *l3 = 0;
8717 u8 *l4 = 0;
8718 int i;
8719
8720 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8721 {
8722 if (unformat (input, "hex %U", unformat_hex_string, &mask))
8723 ;
8724 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8725 ;
8726 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8727 ;
8728 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8729 ;
8730 else
8731 break;
8732 }
8733
8734 if (l4 && !l3)
8735 {
8736 vec_free (mask);
8737 vec_free (l2);
8738 vec_free (l4);
8739 return 0;
8740 }
8741
8742 if (mask || l2 || l3 || l4)
8743 {
8744 if (l2 || l3 || l4)
8745 {
8746 /* "With a free Ethernet header in every package" */
8747 if (l2 == 0)
8748 vec_validate (l2, 13);
8749 mask = l2;
8750 if (vec_len (l3))
8751 {
8752 vec_append (mask, l3);
8753 vec_free (l3);
8754 }
8755 if (vec_len (l4))
8756 {
8757 vec_append (mask, l4);
8758 vec_free (l4);
8759 }
8760 }
8761
8762 /* Scan forward looking for the first significant mask octet */
8763 for (i = 0; i < vec_len (mask); i++)
8764 if (mask[i])
8765 break;
8766
8767 /* compute (skip, match) params */
8768 *skipp = i / sizeof (u32x4);
8769 vec_delete (mask, *skipp * sizeof (u32x4), 0);
8770
8771 /* Pad mask to an even multiple of the vector size */
8772 while (vec_len (mask) % sizeof (u32x4))
8773 vec_add1 (mask, 0);
8774
8775 match = vec_len (mask) / sizeof (u32x4);
8776
8777 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8778 {
8779 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8780 if (*tmp || *(tmp + 1))
8781 break;
8782 match--;
8783 }
8784 if (match == 0)
8785 clib_warning ("BUG: match 0");
8786
8787 _vec_len (mask) = match * sizeof (u32x4);
8788
8789 *matchp = match;
8790 *maskp = mask;
8791
8792 return 1;
8793 }
8794
8795 return 0;
8796}
8797
8798#define foreach_l2_next \
8799_(drop, DROP) \
8800_(ethernet, ETHERNET_INPUT) \
8801_(ip4, IP4_INPUT) \
8802_(ip6, IP6_INPUT)
8803
8804uword
8805unformat_l2_next_index (unformat_input_t * input, va_list * args)
8806{
8807 u32 *miss_next_indexp = va_arg (*args, u32 *);
8808 u32 next_index = 0;
8809 u32 tmp;
8810
8811#define _(n,N) \
8812 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8813 foreach_l2_next;
8814#undef _
8815
8816 if (unformat (input, "%d", &tmp))
8817 {
8818 next_index = tmp;
8819 goto out;
8820 }
8821
8822 return 0;
8823
8824out:
8825 *miss_next_indexp = next_index;
8826 return 1;
8827}
8828
8829#define foreach_ip_next \
8830_(drop, DROP) \
8831_(local, LOCAL) \
8832_(rewrite, REWRITE)
8833
8834uword
8835unformat_ip_next_index (unformat_input_t * input, va_list * args)
8836{
8837 u32 *miss_next_indexp = va_arg (*args, u32 *);
8838 u32 next_index = 0;
8839 u32 tmp;
8840
8841#define _(n,N) \
8842 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8843 foreach_ip_next;
8844#undef _
8845
8846 if (unformat (input, "%d", &tmp))
8847 {
8848 next_index = tmp;
8849 goto out;
8850 }
8851
8852 return 0;
8853
8854out:
8855 *miss_next_indexp = next_index;
8856 return 1;
8857}
8858
8859#define foreach_acl_next \
8860_(deny, DENY)
8861
8862uword
8863unformat_acl_next_index (unformat_input_t * input, va_list * args)
8864{
8865 u32 *miss_next_indexp = va_arg (*args, u32 *);
8866 u32 next_index = 0;
8867 u32 tmp;
8868
8869#define _(n,N) \
8870 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8871 foreach_acl_next;
8872#undef _
8873
8874 if (unformat (input, "permit"))
8875 {
8876 next_index = ~0;
8877 goto out;
8878 }
8879 else if (unformat (input, "%d", &tmp))
8880 {
8881 next_index = tmp;
8882 goto out;
8883 }
8884
8885 return 0;
8886
8887out:
8888 *miss_next_indexp = next_index;
8889 return 1;
8890}
8891
8892uword
8893unformat_policer_precolor (unformat_input_t * input, va_list * args)
8894{
8895 u32 *r = va_arg (*args, u32 *);
8896
8897 if (unformat (input, "conform-color"))
8898 *r = POLICE_CONFORM;
8899 else if (unformat (input, "exceed-color"))
8900 *r = POLICE_EXCEED;
8901 else
8902 return 0;
8903
8904 return 1;
8905}
8906
8907static int
8908api_classify_add_del_table (vat_main_t * vam)
8909{
8910 unformat_input_t *i = vam->input;
8911 vl_api_classify_add_del_table_t *mp;
8912
8913 u32 nbuckets = 2;
8914 u32 skip = ~0;
8915 u32 match = ~0;
8916 int is_add = 1;
8917 int del_chain = 0;
8918 u32 table_index = ~0;
8919 u32 next_table_index = ~0;
8920 u32 miss_next_index = ~0;
8921 u32 memory_size = 32 << 20;
8922 u8 *mask = 0;
8923 f64 timeout;
8924 u32 current_data_flag = 0;
8925 int current_data_offset = 0;
8926
8927 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8928 {
8929 if (unformat (i, "del"))
8930 is_add = 0;
8931 else if (unformat (i, "del-chain"))
8932 {
8933 is_add = 0;
8934 del_chain = 1;
8935 }
8936 else if (unformat (i, "buckets %d", &nbuckets))
8937 ;
8938 else if (unformat (i, "memory_size %d", &memory_size))
8939 ;
8940 else if (unformat (i, "skip %d", &skip))
8941 ;
8942 else if (unformat (i, "match %d", &match))
8943 ;
8944 else if (unformat (i, "table %d", &table_index))
8945 ;
8946 else if (unformat (i, "mask %U", unformat_classify_mask,
8947 &mask, &skip, &match))
8948 ;
8949 else if (unformat (i, "next-table %d", &next_table_index))
8950 ;
8951 else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8952 &miss_next_index))
8953 ;
8954 else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8955 &miss_next_index))
8956 ;
8957 else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8958 &miss_next_index))
8959 ;
8960 else if (unformat (i, "current-data-flag %d", &current_data_flag))
8961 ;
8962 else if (unformat (i, "current-data-offset %d", &current_data_offset))
8963 ;
8964 else
8965 break;
8966 }
8967
8968 if (is_add && mask == 0)
8969 {
8970 errmsg ("Mask required");
8971 return -99;
8972 }
8973
8974 if (is_add && skip == ~0)
8975 {
8976 errmsg ("skip count required");
8977 return -99;
8978 }
8979
8980 if (is_add && match == ~0)
8981 {
8982 errmsg ("match count required");
8983 return -99;
8984 }
8985
8986 if (!is_add && table_index == ~0)
8987 {
8988 errmsg ("table index required for delete");
8989 return -99;
8990 }
8991
8992 M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8993
8994 mp->is_add = is_add;
8995 mp->del_chain = del_chain;
8996 mp->table_index = ntohl (table_index);
8997 mp->nbuckets = ntohl (nbuckets);
8998 mp->memory_size = ntohl (memory_size);
8999 mp->skip_n_vectors = ntohl (skip);
9000 mp->match_n_vectors = ntohl (match);
9001 mp->next_table_index = ntohl (next_table_index);
9002 mp->miss_next_index = ntohl (miss_next_index);
9003 mp->current_data_flag = ntohl (current_data_flag);
9004 mp->current_data_offset = ntohl (current_data_offset);
9005 clib_memcpy (mp->mask, mask, vec_len (mask));
9006
9007 vec_free (mask);
9008
9009 S;
9010 W;
9011 /* NOTREACHED */
9012}
9013
9014uword
9015unformat_l4_match (unformat_input_t * input, va_list * args)
9016{
9017 u8 **matchp = va_arg (*args, u8 **);
9018
9019 u8 *proto_header = 0;
9020 int src_port = 0;
9021 int dst_port = 0;
9022
9023 tcpudp_header_t h;
9024
9025 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9026 {
9027 if (unformat (input, "src_port %d", &src_port))
9028 ;
9029 else if (unformat (input, "dst_port %d", &dst_port))
9030 ;
9031 else
9032 return 0;
9033 }
9034
9035 h.src_port = clib_host_to_net_u16 (src_port);
9036 h.dst_port = clib_host_to_net_u16 (dst_port);
9037 vec_validate (proto_header, sizeof (h) - 1);
9038 memcpy (proto_header, &h, sizeof (h));
9039
9040 *matchp = proto_header;
9041
9042 return 1;
9043}
9044
9045uword
9046unformat_ip4_match (unformat_input_t * input, va_list * args)
9047{
9048 u8 **matchp = va_arg (*args, u8 **);
9049 u8 *match = 0;
9050 ip4_header_t *ip;
9051 int version = 0;
9052 u32 version_val;
9053 int hdr_length = 0;
9054 u32 hdr_length_val;
9055 int src = 0, dst = 0;
9056 ip4_address_t src_val, dst_val;
9057 int proto = 0;
9058 u32 proto_val;
9059 int tos = 0;
9060 u32 tos_val;
9061 int length = 0;
9062 u32 length_val;
9063 int fragment_id = 0;
9064 u32 fragment_id_val;
9065 int ttl = 0;
9066 int ttl_val;
9067 int checksum = 0;
9068 u32 checksum_val;
9069
9070 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9071 {
9072 if (unformat (input, "version %d", &version_val))
9073 version = 1;
9074 else if (unformat (input, "hdr_length %d", &hdr_length_val))
9075 hdr_length = 1;
9076 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9077 src = 1;
9078 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9079 dst = 1;
9080 else if (unformat (input, "proto %d", &proto_val))
9081 proto = 1;
9082 else if (unformat (input, "tos %d", &tos_val))
9083 tos = 1;
9084 else if (unformat (input, "length %d", &length_val))
9085 length = 1;
9086 else if (unformat (input, "fragment_id %d", &fragment_id_val))
9087 fragment_id = 1;
9088 else if (unformat (input, "ttl %d", &ttl_val))
9089 ttl = 1;
9090 else if (unformat (input, "checksum %d", &checksum_val))
9091 checksum = 1;
9092 else
9093 break;
9094 }
9095
9096 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9097 + ttl + checksum == 0)
9098 return 0;
9099
9100 /*
9101 * Aligned because we use the real comparison functions
9102 */
9103 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9104
9105 ip = (ip4_header_t *) match;
9106
9107 /* These are realistically matched in practice */
9108 if (src)
9109 ip->src_address.as_u32 = src_val.as_u32;
9110
9111 if (dst)
9112 ip->dst_address.as_u32 = dst_val.as_u32;
9113
9114 if (proto)
9115 ip->protocol = proto_val;
9116
9117
9118 /* These are not, but they're included for completeness */
9119 if (version)
9120 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9121
9122 if (hdr_length)
9123 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9124
9125 if (tos)
9126 ip->tos = tos_val;
9127
9128 if (length)
9129 ip->length = clib_host_to_net_u16 (length_val);
9130
9131 if (ttl)
9132 ip->ttl = ttl_val;
9133
9134 if (checksum)
9135 ip->checksum = clib_host_to_net_u16 (checksum_val);
9136
9137 *matchp = match;
9138 return 1;
9139}
9140
9141uword
9142unformat_ip6_match (unformat_input_t * input, va_list * args)
9143{
9144 u8 **matchp = va_arg (*args, u8 **);
9145 u8 *match = 0;
9146 ip6_header_t *ip;
9147 int version = 0;
9148 u32 version_val;
9149 u8 traffic_class = 0;
9150 u32 traffic_class_val = 0;
9151 u8 flow_label = 0;
9152 u8 flow_label_val;
9153 int src = 0, dst = 0;
9154 ip6_address_t src_val, dst_val;
9155 int proto = 0;
9156 u32 proto_val;
9157 int payload_length = 0;
9158 u32 payload_length_val;
9159 int hop_limit = 0;
9160 int hop_limit_val;
9161 u32 ip_version_traffic_class_and_flow_label;
9162
9163 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9164 {
9165 if (unformat (input, "version %d", &version_val))
9166 version = 1;
9167 else if (unformat (input, "traffic_class %d", &traffic_class_val))
9168 traffic_class = 1;
9169 else if (unformat (input, "flow_label %d", &flow_label_val))
9170 flow_label = 1;
9171 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9172 src = 1;
9173 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9174 dst = 1;
9175 else if (unformat (input, "proto %d", &proto_val))
9176 proto = 1;
9177 else if (unformat (input, "payload_length %d", &payload_length_val))
9178 payload_length = 1;
9179 else if (unformat (input, "hop_limit %d", &hop_limit_val))
9180 hop_limit = 1;
9181 else
9182 break;
9183 }
9184
9185 if (version + traffic_class + flow_label + src + dst + proto +
9186 payload_length + hop_limit == 0)
9187 return 0;
9188
9189 /*
9190 * Aligned because we use the real comparison functions
9191 */
9192 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9193
9194 ip = (ip6_header_t *) match;
9195
9196 if (src)
9197 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9198
9199 if (dst)
9200 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9201
9202 if (proto)
9203 ip->protocol = proto_val;
9204
9205 ip_version_traffic_class_and_flow_label = 0;
9206
9207 if (version)
9208 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9209
9210 if (traffic_class)
9211 ip_version_traffic_class_and_flow_label |=
9212 (traffic_class_val & 0xFF) << 20;
9213
9214 if (flow_label)
9215 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9216
9217 ip->ip_version_traffic_class_and_flow_label =
9218 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9219
9220 if (payload_length)
9221 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9222
9223 if (hop_limit)
9224 ip->hop_limit = hop_limit_val;
9225
9226 *matchp = match;
9227 return 1;
9228}
9229
9230uword
9231unformat_l3_match (unformat_input_t * input, va_list * args)
9232{
9233 u8 **matchp = va_arg (*args, u8 **);
9234
9235 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9236 {
9237 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9238 return 1;
9239 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9240 return 1;
9241 else
9242 break;
9243 }
9244 return 0;
9245}
9246
9247uword
9248unformat_vlan_tag (unformat_input_t * input, va_list * args)
9249{
9250 u8 *tagp = va_arg (*args, u8 *);
9251 u32 tag;
9252
9253 if (unformat (input, "%d", &tag))
9254 {
9255 tagp[0] = (tag >> 8) & 0x0F;
9256 tagp[1] = tag & 0xFF;
9257 return 1;
9258 }
9259
9260 return 0;
9261}
9262
9263uword
9264unformat_l2_match (unformat_input_t * input, va_list * args)
9265{
9266 u8 **matchp = va_arg (*args, u8 **);
9267 u8 *match = 0;
9268 u8 src = 0;
9269 u8 src_val[6];
9270 u8 dst = 0;
9271 u8 dst_val[6];
9272 u8 proto = 0;
9273 u16 proto_val;
9274 u8 tag1 = 0;
9275 u8 tag1_val[2];
9276 u8 tag2 = 0;
9277 u8 tag2_val[2];
9278 int len = 14;
9279 u8 ignore_tag1 = 0;
9280 u8 ignore_tag2 = 0;
9281 u8 cos1 = 0;
9282 u8 cos2 = 0;
9283 u32 cos1_val = 0;
9284 u32 cos2_val = 0;
9285
9286 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9287 {
9288 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9289 src = 1;
9290 else
9291 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9292 dst = 1;
9293 else if (unformat (input, "proto %U",
9294 unformat_ethernet_type_host_byte_order, &proto_val))
9295 proto = 1;
9296 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9297 tag1 = 1;
9298 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9299 tag2 = 1;
9300 else if (unformat (input, "ignore-tag1"))
9301 ignore_tag1 = 1;
9302 else if (unformat (input, "ignore-tag2"))
9303 ignore_tag2 = 1;
9304 else if (unformat (input, "cos1 %d", &cos1_val))
9305 cos1 = 1;
9306 else if (unformat (input, "cos2 %d", &cos2_val))
9307 cos2 = 1;
9308 else
9309 break;
9310 }
9311 if ((src + dst + proto + tag1 + tag2 +
9312 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9313 return 0;
9314
9315 if (tag1 || ignore_tag1 || cos1)
9316 len = 18;
9317 if (tag2 || ignore_tag2 || cos2)
9318 len = 22;
9319
9320 vec_validate_aligned (match, len - 1, sizeof (u32x4));
9321
9322 if (dst)
9323 clib_memcpy (match, dst_val, 6);
9324
9325 if (src)
9326 clib_memcpy (match + 6, src_val, 6);
9327
9328 if (tag2)
9329 {
9330 /* inner vlan tag */
9331 match[19] = tag2_val[1];
9332 match[18] = tag2_val[0];
9333 if (cos2)
9334 match[18] |= (cos2_val & 0x7) << 5;
9335 if (proto)
9336 {
9337 match[21] = proto_val & 0xff;
9338 match[20] = proto_val >> 8;
9339 }
9340 if (tag1)
9341 {
9342 match[15] = tag1_val[1];
9343 match[14] = tag1_val[0];
9344 }
9345 if (cos1)
9346 match[14] |= (cos1_val & 0x7) << 5;
9347 *matchp = match;
9348 return 1;
9349 }
9350 if (tag1)
9351 {
9352 match[15] = tag1_val[1];
9353 match[14] = tag1_val[0];
9354 if (proto)
9355 {
9356 match[17] = proto_val & 0xff;
9357 match[16] = proto_val >> 8;
9358 }
9359 if (cos1)
9360 match[14] |= (cos1_val & 0x7) << 5;
9361
9362 *matchp = match;
9363 return 1;
9364 }
9365 if (cos2)
9366 match[18] |= (cos2_val & 0x7) << 5;
9367 if (cos1)
9368 match[14] |= (cos1_val & 0x7) << 5;
9369 if (proto)
9370 {
9371 match[13] = proto_val & 0xff;
9372 match[12] = proto_val >> 8;
9373 }
9374
9375 *matchp = match;
9376 return 1;
9377}
9378
9379
9380uword
9381unformat_classify_match (unformat_input_t * input, va_list * args)
9382{
9383 u8 **matchp = va_arg (*args, u8 **);
9384 u32 skip_n_vectors = va_arg (*args, u32);
9385 u32 match_n_vectors = va_arg (*args, u32);
9386
9387 u8 *match = 0;
9388 u8 *l2 = 0;
9389 u8 *l3 = 0;
9390 u8 *l4 = 0;
9391
9392 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9393 {
9394 if (unformat (input, "hex %U", unformat_hex_string, &match))
9395 ;
9396 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9397 ;
9398 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9399 ;
9400 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9401 ;
9402 else
9403 break;
9404 }
9405
9406 if (l4 && !l3)
9407 {
9408 vec_free (match);
9409 vec_free (l2);
9410 vec_free (l4);
9411 return 0;
9412 }
9413
9414 if (match || l2 || l3 || l4)
9415 {
9416 if (l2 || l3 || l4)
9417 {
9418 /* "Win a free Ethernet header in every packet" */
9419 if (l2 == 0)
9420 vec_validate_aligned (l2, 13, sizeof (u32x4));
9421 match = l2;
9422 if (vec_len (l3))
9423 {
9424 vec_append_aligned (match, l3, sizeof (u32x4));
9425 vec_free (l3);
9426 }
9427 if (vec_len (l4))
9428 {
9429 vec_append_aligned (match, l4, sizeof (u32x4));
9430 vec_free (l4);
9431 }
9432 }
9433
9434 /* Make sure the vector is big enough even if key is all 0's */
9435 vec_validate_aligned
9436 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9437 sizeof (u32x4));
9438
9439 /* Set size, include skipped vectors */
9440 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9441
9442 *matchp = match;
9443
9444 return 1;
9445 }
9446
9447 return 0;
9448}
9449
9450static int
9451api_classify_add_del_session (vat_main_t * vam)
9452{
9453 unformat_input_t *i = vam->input;
9454 vl_api_classify_add_del_session_t *mp;
9455 int is_add = 1;
9456 u32 table_index = ~0;
9457 u32 hit_next_index = ~0;
9458 u32 opaque_index = ~0;
9459 u8 *match = 0;
9460 i32 advance = 0;
9461 f64 timeout;
9462 u32 skip_n_vectors = 0;
9463 u32 match_n_vectors = 0;
9464 u32 action = 0;
9465 u32 metadata = 0;
9466
9467 /*
9468 * Warning: you have to supply skip_n and match_n
9469 * because the API client cant simply look at the classify
9470 * table object.
9471 */
9472
9473 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9474 {
9475 if (unformat (i, "del"))
9476 is_add = 0;
9477 else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9478 &hit_next_index))
9479 ;
9480 else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9481 &hit_next_index))
9482 ;
9483 else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9484 &hit_next_index))
9485 ;
9486 else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9487 ;
9488 else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9489 ;
9490 else if (unformat (i, "opaque-index %d", &opaque_index))
9491 ;
9492 else if (unformat (i, "skip_n %d", &skip_n_vectors))
9493 ;
9494 else if (unformat (i, "match_n %d", &match_n_vectors))
9495 ;
9496 else if (unformat (i, "match %U", unformat_classify_match,
9497 &match, skip_n_vectors, match_n_vectors))
9498 ;
9499 else if (unformat (i, "advance %d", &advance))
9500 ;
9501 else if (unformat (i, "table-index %d", &table_index))
9502 ;
9503 else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9504 action = 1;
9505 else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9506 action = 2;
9507 else if (unformat (i, "action %d", &action))
9508 ;
9509 else if (unformat (i, "metadata %d", &metadata))
9510 ;
9511 else
9512 break;
9513 }
9514
9515 if (table_index == ~0)
9516 {
9517 errmsg ("Table index required");
9518 return -99;
9519 }
9520
9521 if (is_add && match == 0)
9522 {
9523 errmsg ("Match value required");
9524 return -99;
9525 }
9526
9527 M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9528
9529 mp->is_add = is_add;
9530 mp->table_index = ntohl (table_index);
9531 mp->hit_next_index = ntohl (hit_next_index);
9532 mp->opaque_index = ntohl (opaque_index);
9533 mp->advance = ntohl (advance);
9534 mp->action = action;
9535 mp->metadata = ntohl (metadata);
9536 clib_memcpy (mp->match, match, vec_len (match));
9537 vec_free (match);
9538
9539 S;
9540 W;
9541 /* NOTREACHED */
9542}
9543
9544static int
9545api_classify_set_interface_ip_table (vat_main_t * vam)
9546{
9547 unformat_input_t *i = vam->input;
9548 vl_api_classify_set_interface_ip_table_t *mp;
9549 f64 timeout;
9550 u32 sw_if_index;
9551 int sw_if_index_set;
9552 u32 table_index = ~0;
9553 u8 is_ipv6 = 0;
9554
9555 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9556 {
9557 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9558 sw_if_index_set = 1;
9559 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9560 sw_if_index_set = 1;
9561 else if (unformat (i, "table %d", &table_index))
9562 ;
9563 else
9564 {
9565 clib_warning ("parse error '%U'", format_unformat_error, i);
9566 return -99;
9567 }
9568 }
9569
9570 if (sw_if_index_set == 0)
9571 {
9572 errmsg ("missing interface name or sw_if_index");
9573 return -99;
9574 }
9575
9576
9577 M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9578
9579 mp->sw_if_index = ntohl (sw_if_index);
9580 mp->table_index = ntohl (table_index);
9581 mp->is_ipv6 = is_ipv6;
9582
9583 S;
9584 W;
9585 /* NOTREACHED */
9586 return 0;
9587}
9588
9589static int
9590api_classify_set_interface_l2_tables (vat_main_t * vam)
9591{
9592 unformat_input_t *i = vam->input;
9593 vl_api_classify_set_interface_l2_tables_t *mp;
9594 f64 timeout;
9595 u32 sw_if_index;
9596 int sw_if_index_set;
9597 u32 ip4_table_index = ~0;
9598 u32 ip6_table_index = ~0;
9599 u32 other_table_index = ~0;
9600 u32 is_input = 1;
9601
9602 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9603 {
9604 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9605 sw_if_index_set = 1;
9606 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9607 sw_if_index_set = 1;
9608 else if (unformat (i, "ip4-table %d", &ip4_table_index))
9609 ;
9610 else if (unformat (i, "ip6-table %d", &ip6_table_index))
9611 ;
9612 else if (unformat (i, "other-table %d", &other_table_index))
9613 ;
9614 else if (unformat (i, "is-input %d", &is_input))
9615 ;
9616 else
9617 {
9618 clib_warning ("parse error '%U'", format_unformat_error, i);
9619 return -99;
9620 }
9621 }
9622
9623 if (sw_if_index_set == 0)
9624 {
9625 errmsg ("missing interface name or sw_if_index");
9626 return -99;
9627 }
9628
9629
9630 M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9631
9632 mp->sw_if_index = ntohl (sw_if_index);
9633 mp->ip4_table_index = ntohl (ip4_table_index);
9634 mp->ip6_table_index = ntohl (ip6_table_index);
9635 mp->other_table_index = ntohl (other_table_index);
9636 mp->is_input = (u8) is_input;
9637
9638 S;
9639 W;
9640 /* NOTREACHED */
9641 return 0;
9642}
9643
9644static int
9645api_set_ipfix_exporter (vat_main_t * vam)
9646{
9647 unformat_input_t *i = vam->input;
9648 vl_api_set_ipfix_exporter_t *mp;
9649 ip4_address_t collector_address;
9650 u8 collector_address_set = 0;
9651 u32 collector_port = ~0;
9652 ip4_address_t src_address;
9653 u8 src_address_set = 0;
9654 u32 vrf_id = ~0;
9655 u32 path_mtu = ~0;
9656 u32 template_interval = ~0;
9657 u8 udp_checksum = 0;
9658 f64 timeout;
9659
9660 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9661 {
9662 if (unformat (i, "collector_address %U", unformat_ip4_address,
9663 &collector_address))
9664 collector_address_set = 1;
9665 else if (unformat (i, "collector_port %d", &collector_port))
9666 ;
9667 else if (unformat (i, "src_address %U", unformat_ip4_address,
9668 &src_address))
9669 src_address_set = 1;
9670 else if (unformat (i, "vrf_id %d", &vrf_id))
9671 ;
9672 else if (unformat (i, "path_mtu %d", &path_mtu))
9673 ;
9674 else if (unformat (i, "template_interval %d", &template_interval))
9675 ;
9676 else if (unformat (i, "udp_checksum"))
9677 udp_checksum = 1;
9678 else
9679 break;
9680 }
9681
9682 if (collector_address_set == 0)
9683 {
9684 errmsg ("collector_address required");
9685 return -99;
9686 }
9687
9688 if (src_address_set == 0)
9689 {
9690 errmsg ("src_address required");
9691 return -99;
9692 }
9693
9694 M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9695
9696 memcpy (mp->collector_address, collector_address.data,
9697 sizeof (collector_address.data));
9698 mp->collector_port = htons ((u16) collector_port);
9699 memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9700 mp->vrf_id = htonl (vrf_id);
9701 mp->path_mtu = htonl (path_mtu);
9702 mp->template_interval = htonl (template_interval);
9703 mp->udp_checksum = udp_checksum;
9704
9705 S;
9706 W;
9707 /* NOTREACHED */
9708}
9709
9710static int
9711api_set_ipfix_classify_stream (vat_main_t * vam)
9712{
9713 unformat_input_t *i = vam->input;
9714 vl_api_set_ipfix_classify_stream_t *mp;
9715 u32 domain_id = 0;
9716 u32 src_port = UDP_DST_PORT_ipfix;
9717 f64 timeout;
9718
9719 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9720 {
9721 if (unformat (i, "domain %d", &domain_id))
9722 ;
9723 else if (unformat (i, "src_port %d", &src_port))
9724 ;
9725 else
9726 {
9727 errmsg ("unknown input `%U'", format_unformat_error, i);
9728 return -99;
9729 }
9730 }
9731
9732 M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9733
9734 mp->domain_id = htonl (domain_id);
9735 mp->src_port = htons ((u16) src_port);
9736
9737 S;
9738 W;
9739 /* NOTREACHED */
9740}
9741
9742static int
9743api_ipfix_classify_table_add_del (vat_main_t * vam)
9744{
9745 unformat_input_t *i = vam->input;
9746 vl_api_ipfix_classify_table_add_del_t *mp;
9747 int is_add = -1;
9748 u32 classify_table_index = ~0;
9749 u8 ip_version = 0;
9750 u8 transport_protocol = 255;
9751 f64 timeout;
9752
9753 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9754 {
9755 if (unformat (i, "add"))
9756 is_add = 1;
9757 else if (unformat (i, "del"))
9758 is_add = 0;
9759 else if (unformat (i, "table %d", &classify_table_index))
9760 ;
9761 else if (unformat (i, "ip4"))
9762 ip_version = 4;
9763 else if (unformat (i, "ip6"))
9764 ip_version = 6;
9765 else if (unformat (i, "tcp"))
9766 transport_protocol = 6;
9767 else if (unformat (i, "udp"))
9768 transport_protocol = 17;
9769 else
9770 {
9771 errmsg ("unknown input `%U'", format_unformat_error, i);
9772 return -99;
9773 }
9774 }
9775
9776 if (is_add == -1)
9777 {
9778 errmsg ("expecting: add|del");
9779 return -99;
9780 }
9781 if (classify_table_index == ~0)
9782 {
9783 errmsg ("classifier table not specified");
9784 return -99;
9785 }
9786 if (ip_version == 0)
9787 {
9788 errmsg ("IP version not specified");
9789 return -99;
9790 }
9791
9792 M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9793
9794 mp->is_add = is_add;
9795 mp->table_id = htonl (classify_table_index);
9796 mp->ip_version = ip_version;
9797 mp->transport_protocol = transport_protocol;
9798
9799 S;
9800 W;
9801 /* NOTREACHED */
9802}
9803
9804static int
9805api_get_node_index (vat_main_t * vam)
9806{
9807 unformat_input_t *i = vam->input;
9808 vl_api_get_node_index_t *mp;
9809 f64 timeout;
9810 u8 *name = 0;
9811
9812 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9813 {
9814 if (unformat (i, "node %s", &name))
9815 ;
9816 else
9817 break;
9818 }
9819 if (name == 0)
9820 {
9821 errmsg ("node name required");
9822 return -99;
9823 }
9824 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9825 {
9826 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9827 return -99;
9828 }
9829
9830 M (GET_NODE_INDEX, get_node_index);
9831 clib_memcpy (mp->node_name, name, vec_len (name));
9832 vec_free (name);
9833
9834 S;
9835 W;
9836 /* NOTREACHED */
9837 return 0;
9838}
9839
9840static int
9841api_get_next_index (vat_main_t * vam)
9842{
9843 unformat_input_t *i = vam->input;
9844 vl_api_get_next_index_t *mp;
9845 f64 timeout;
9846 u8 *node_name = 0, *next_node_name = 0;
9847
9848 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9849 {
9850 if (unformat (i, "node-name %s", &node_name))
9851 ;
9852 else if (unformat (i, "next-node-name %s", &next_node_name))
9853 break;
9854 }
9855
9856 if (node_name == 0)
9857 {
9858 errmsg ("node name required");
9859 return -99;
9860 }
9861 if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9862 {
9863 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9864 return -99;
9865 }
9866
9867 if (next_node_name == 0)
9868 {
9869 errmsg ("next node name required");
9870 return -99;
9871 }
9872 if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9873 {
9874 errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9875 return -99;
9876 }
9877
9878 M (GET_NEXT_INDEX, get_next_index);
9879 clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9880 clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9881 vec_free (node_name);
9882 vec_free (next_node_name);
9883
9884 S;
9885 W;
9886 /* NOTREACHED */
9887 return 0;
9888}
9889
9890static int
9891api_add_node_next (vat_main_t * vam)
9892{
9893 unformat_input_t *i = vam->input;
9894 vl_api_add_node_next_t *mp;
9895 f64 timeout;
9896 u8 *name = 0;
9897 u8 *next = 0;
9898
9899 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9900 {
9901 if (unformat (i, "node %s", &name))
9902 ;
9903 else if (unformat (i, "next %s", &next))
9904 ;
9905 else
9906 break;
9907 }
9908 if (name == 0)
9909 {
9910 errmsg ("node name required");
9911 return -99;
9912 }
9913 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9914 {
9915 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9916 return -99;
9917 }
9918 if (next == 0)
9919 {
9920 errmsg ("next node required");
9921 return -99;
9922 }
9923 if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9924 {
9925 errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9926 return -99;
9927 }
9928
9929 M (ADD_NODE_NEXT, add_node_next);
9930 clib_memcpy (mp->node_name, name, vec_len (name));
9931 clib_memcpy (mp->next_name, next, vec_len (next));
9932 vec_free (name);
9933 vec_free (next);
9934
9935 S;
9936 W;
9937 /* NOTREACHED */
9938 return 0;
9939}
9940
9941static int
9942api_l2tpv3_create_tunnel (vat_main_t * vam)
9943{
9944 unformat_input_t *i = vam->input;
9945 ip6_address_t client_address, our_address;
9946 int client_address_set = 0;
9947 int our_address_set = 0;
9948 u32 local_session_id = 0;
9949 u32 remote_session_id = 0;
9950 u64 local_cookie = 0;
9951 u64 remote_cookie = 0;
9952 u8 l2_sublayer_present = 0;
9953 vl_api_l2tpv3_create_tunnel_t *mp;
9954 f64 timeout;
9955
9956 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9957 {
9958 if (unformat (i, "client_address %U", unformat_ip6_address,
9959 &client_address))
9960 client_address_set = 1;
9961 else if (unformat (i, "our_address %U", unformat_ip6_address,
9962 &our_address))
9963 our_address_set = 1;
9964 else if (unformat (i, "local_session_id %d", &local_session_id))
9965 ;
9966 else if (unformat (i, "remote_session_id %d", &remote_session_id))
9967 ;
9968 else if (unformat (i, "local_cookie %lld", &local_cookie))
9969 ;
9970 else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9971 ;
9972 else if (unformat (i, "l2-sublayer-present"))
9973 l2_sublayer_present = 1;
9974 else
9975 break;
9976 }
9977
9978 if (client_address_set == 0)
9979 {
9980 errmsg ("client_address required");
9981 return -99;
9982 }
9983
9984 if (our_address_set == 0)
9985 {
9986 errmsg ("our_address required");
9987 return -99;
9988 }
9989
9990 M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9991
9992 clib_memcpy (mp->client_address, client_address.as_u8,
9993 sizeof (mp->client_address));
9994
9995 clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9996
9997 mp->local_session_id = ntohl (local_session_id);
9998 mp->remote_session_id = ntohl (remote_session_id);
9999 mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10000 mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10001 mp->l2_sublayer_present = l2_sublayer_present;
10002 mp->is_ipv6 = 1;
10003
10004 S;
10005 W;
10006 /* NOTREACHED */
10007 return 0;
10008}
10009
10010static int
10011api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10012{
10013 unformat_input_t *i = vam->input;
10014 u32 sw_if_index;
10015 u8 sw_if_index_set = 0;
10016 u64 new_local_cookie = 0;
10017 u64 new_remote_cookie = 0;
10018 vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10019 f64 timeout;
10020
10021 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10022 {
10023 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10024 sw_if_index_set = 1;
10025 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10026 sw_if_index_set = 1;
10027 else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10028 ;
10029 else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10030 ;
10031 else
10032 break;
10033 }
10034
10035 if (sw_if_index_set == 0)
10036 {
10037 errmsg ("missing interface name or sw_if_index");
10038 return -99;
10039 }
10040
10041 M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
10042
10043 mp->sw_if_index = ntohl (sw_if_index);
10044 mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10045 mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10046
10047 S;
10048 W;
10049 /* NOTREACHED */
10050 return 0;
10051}
10052
10053static int
10054api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10055{
10056 unformat_input_t *i = vam->input;
10057 vl_api_l2tpv3_interface_enable_disable_t *mp;
10058 f64 timeout;
10059 u32 sw_if_index;
10060 u8 sw_if_index_set = 0;
10061 u8 enable_disable = 1;
10062
10063 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10064 {
10065 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10066 sw_if_index_set = 1;
10067 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10068 sw_if_index_set = 1;
10069 else if (unformat (i, "enable"))
10070 enable_disable = 1;
10071 else if (unformat (i, "disable"))
10072 enable_disable = 0;
10073 else
10074 break;
10075 }
10076
10077 if (sw_if_index_set == 0)
10078 {
10079 errmsg ("missing interface name or sw_if_index");
10080 return -99;
10081 }
10082
10083 M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
10084
10085 mp->sw_if_index = ntohl (sw_if_index);
10086 mp->enable_disable = enable_disable;
10087
10088 S;
10089 W;
10090 /* NOTREACHED */
10091 return 0;
10092}
10093
10094static int
10095api_l2tpv3_set_lookup_key (vat_main_t * vam)
10096{
10097 unformat_input_t *i = vam->input;
10098 vl_api_l2tpv3_set_lookup_key_t *mp;
10099 f64 timeout;
10100 u8 key = ~0;
10101
10102 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10103 {
10104 if (unformat (i, "lookup_v6_src"))
10105 key = L2T_LOOKUP_SRC_ADDRESS;
10106 else if (unformat (i, "lookup_v6_dst"))
10107 key = L2T_LOOKUP_DST_ADDRESS;
10108 else if (unformat (i, "lookup_session_id"))
10109 key = L2T_LOOKUP_SESSION_ID;
10110 else
10111 break;
10112 }
10113
10114 if (key == (u8) ~ 0)
10115 {
10116 errmsg ("l2tp session lookup key unset");
10117 return -99;
10118 }
10119
10120 M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
10121
10122 mp->key = key;
10123
10124 S;
10125 W;
10126 /* NOTREACHED */
10127 return 0;
10128}
10129
10130static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10131 (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10132{
10133 vat_main_t *vam = &vat_main;
10134
10135 print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10136 format_ip6_address, mp->our_address,
10137 format_ip6_address, mp->client_address,
10138 clib_net_to_host_u32 (mp->sw_if_index));
10139
10140 print (vam->ofp,
10141 " local cookies %016llx %016llx remote cookie %016llx",
10142 clib_net_to_host_u64 (mp->local_cookie[0]),
10143 clib_net_to_host_u64 (mp->local_cookie[1]),
10144 clib_net_to_host_u64 (mp->remote_cookie));
10145
10146 print (vam->ofp, " local session-id %d remote session-id %d",
10147 clib_net_to_host_u32 (mp->local_session_id),
10148 clib_net_to_host_u32 (mp->remote_session_id));
10149
10150 print (vam->ofp, " l2 specific sublayer %s\n",
10151 mp->l2_sublayer_present ? "preset" : "absent");
10152
10153}
10154
10155static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10156 (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10157{
10158 vat_main_t *vam = &vat_main;
10159 vat_json_node_t *node = NULL;
10160 struct in6_addr addr;
10161
10162 if (VAT_JSON_ARRAY != vam->json_tree.type)
10163 {
10164 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10165 vat_json_init_array (&vam->json_tree);
10166 }
10167 node = vat_json_array_add (&vam->json_tree);
10168
10169 vat_json_init_object (node);
10170
10171 clib_memcpy (&addr, mp->our_address, sizeof (addr));
10172 vat_json_object_add_ip6 (node, "our_address", addr);
10173 clib_memcpy (&addr, mp->client_address, sizeof (addr));
10174 vat_json_object_add_ip6 (node, "client_address", addr);
10175
10176 vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10177 vat_json_init_array (lc);
10178 vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10179 vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10180 vat_json_object_add_uint (node, "remote_cookie",
10181 clib_net_to_host_u64 (mp->remote_cookie));
10182
10183 printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10184 vat_json_object_add_uint (node, "local_session_id",
10185 clib_net_to_host_u32 (mp->local_session_id));
10186 vat_json_object_add_uint (node, "remote_session_id",
10187 clib_net_to_host_u32 (mp->remote_session_id));
10188 vat_json_object_add_string_copy (node, "l2_sublayer",
10189 mp->l2_sublayer_present ? (u8 *) "present"
10190 : (u8 *) "absent");
10191}
10192
10193static int
10194api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10195{
10196 vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10197 f64 timeout;
10198
10199 /* Get list of l2tpv3-tunnel interfaces */
10200 M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10201 S;
10202
10203 /* Use a control ping for synchronization */
10204 {
10205 vl_api_control_ping_t *mp;
10206 M (CONTROL_PING, control_ping);
10207 S;
10208 }
10209 W;
10210}
10211
10212
10213static void vl_api_sw_interface_tap_details_t_handler
10214 (vl_api_sw_interface_tap_details_t * mp)
10215{
10216 vat_main_t *vam = &vat_main;
10217
10218 print (vam->ofp, "%-16s %d",
10219 mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10220}
10221
10222static void vl_api_sw_interface_tap_details_t_handler_json
10223 (vl_api_sw_interface_tap_details_t * mp)
10224{
10225 vat_main_t *vam = &vat_main;
10226 vat_json_node_t *node = NULL;
10227
10228 if (VAT_JSON_ARRAY != vam->json_tree.type)
10229 {
10230 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10231 vat_json_init_array (&vam->json_tree);
10232 }
10233 node = vat_json_array_add (&vam->json_tree);
10234
10235 vat_json_init_object (node);
10236 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10237 vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10238}
10239
10240static int
10241api_sw_interface_tap_dump (vat_main_t * vam)
10242{
10243 vl_api_sw_interface_tap_dump_t *mp;
10244 f64 timeout;
10245
10246 print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10247 /* Get list of tap interfaces */
10248 M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10249 S;
10250
10251 /* Use a control ping for synchronization */
10252 {
10253 vl_api_control_ping_t *mp;
10254 M (CONTROL_PING, control_ping);
10255 S;
10256 }
10257 W;
10258}
10259
10260static uword unformat_vxlan_decap_next
10261 (unformat_input_t * input, va_list * args)
10262{
10263 u32 *result = va_arg (*args, u32 *);
10264 u32 tmp;
10265
10266 if (unformat (input, "l2"))
10267 *result = VXLAN_INPUT_NEXT_L2_INPUT;
10268 else if (unformat (input, "%d", &tmp))
10269 *result = tmp;
10270 else
10271 return 0;
10272 return 1;
10273}
10274
10275static int
10276api_vxlan_add_del_tunnel (vat_main_t * vam)
10277{
10278 unformat_input_t *line_input = vam->input;
10279 vl_api_vxlan_add_del_tunnel_t *mp;
10280 f64 timeout;
10281 ip46_address_t src, dst;
10282 u8 is_add = 1;
10283 u8 ipv4_set = 0, ipv6_set = 0;
10284 u8 src_set = 0;
10285 u8 dst_set = 0;
10286 u8 grp_set = 0;
10287 u32 mcast_sw_if_index = ~0;
10288 u32 encap_vrf_id = 0;
10289 u32 decap_next_index = ~0;
10290 u32 vni = 0;
10291
10292 /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10293 memset (&src, 0, sizeof src);
10294 memset (&dst, 0, sizeof dst);
10295
10296 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10297 {
10298 if (unformat (line_input, "del"))
10299 is_add = 0;
10300 else
10301 if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10302 {
10303 ipv4_set = 1;
10304 src_set = 1;
10305 }
10306 else
10307 if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10308 {
10309 ipv4_set = 1;
10310 dst_set = 1;
10311 }
10312 else
10313 if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10314 {
10315 ipv6_set = 1;
10316 src_set = 1;
10317 }
10318 else
10319 if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10320 {
10321 ipv6_set = 1;
10322 dst_set = 1;
10323 }
10324 else if (unformat (line_input, "group %U %U",
10325 unformat_ip4_address, &dst.ip4,
10326 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10327 {
10328 grp_set = dst_set = 1;
10329 ipv4_set = 1;
10330 }
10331 else if (unformat (line_input, "group %U",
10332 unformat_ip4_address, &dst.ip4))
10333 {
10334 grp_set = dst_set = 1;
10335 ipv4_set = 1;
10336 }
10337 else if (unformat (line_input, "group %U %U",
10338 unformat_ip6_address, &dst.ip6,
10339 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10340 {
10341 grp_set = dst_set = 1;
10342 ipv6_set = 1;
10343 }
10344 else if (unformat (line_input, "group %U",
10345 unformat_ip6_address, &dst.ip6))
10346 {
10347 grp_set = dst_set = 1;
10348 ipv6_set = 1;
10349 }
10350 else
10351 if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10352 ;
10353 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10354 ;
10355 else if (unformat (line_input, "decap-next %U",
10356 unformat_vxlan_decap_next, &decap_next_index))
10357 ;
10358 else if (unformat (line_input, "vni %d", &vni))
10359 ;
10360 else
10361 {
10362 errmsg ("parse error '%U'", format_unformat_error, line_input);
10363 return -99;
10364 }
10365 }
10366
10367 if (src_set == 0)
10368 {
10369 errmsg ("tunnel src address not specified");
10370 return -99;
10371 }
10372 if (dst_set == 0)
10373 {
10374 errmsg ("tunnel dst address not specified");
10375 return -99;
10376 }
10377
10378 if (grp_set && !ip46_address_is_multicast (&dst))
10379 {
10380 errmsg ("tunnel group address not multicast");
10381 return -99;
10382 }
10383 if (grp_set && mcast_sw_if_index == ~0)
10384 {
10385 errmsg ("tunnel nonexistent multicast device");
10386 return -99;
10387 }
10388 if (grp_set == 0 && ip46_address_is_multicast (&dst))
10389 {
10390 errmsg ("tunnel dst address must be unicast");
10391 return -99;
10392 }
10393
10394
10395 if (ipv4_set && ipv6_set)
10396 {
10397 errmsg ("both IPv4 and IPv6 addresses specified");
10398 return -99;
10399 }
10400
10401 if ((vni == 0) || (vni >> 24))
10402 {
10403 errmsg ("vni not specified or out of range");
10404 return -99;
10405 }
10406
10407 M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10408
10409 if (ipv6_set)
10410 {
10411 clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10412 clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10413 }
10414 else
10415 {
10416 clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10417 clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10418 }
10419 mp->encap_vrf_id = ntohl (encap_vrf_id);
10420 mp->decap_next_index = ntohl (decap_next_index);
10421 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10422 mp->vni = ntohl (vni);
10423 mp->is_add = is_add;
10424 mp->is_ipv6 = ipv6_set;
10425
10426 S;
10427 W;
10428 /* NOTREACHED */
10429 return 0;
10430}
10431
10432static void vl_api_vxlan_tunnel_details_t_handler
10433 (vl_api_vxlan_tunnel_details_t * mp)
10434{
10435 vat_main_t *vam = &vat_main;
10436 ip46_address_t src, dst;
10437
10438 ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10439 ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10440
10441 print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10442 ntohl (mp->sw_if_index),
10443 format_ip46_address, &src, IP46_TYPE_ANY,
10444 format_ip46_address, &dst, IP46_TYPE_ANY,
10445 ntohl (mp->encap_vrf_id),
10446 ntohl (mp->decap_next_index), ntohl (mp->vni),
10447 ntohl (mp->mcast_sw_if_index));
10448}
10449
10450static void vl_api_vxlan_tunnel_details_t_handler_json
10451 (vl_api_vxlan_tunnel_details_t * mp)
10452{
10453 vat_main_t *vam = &vat_main;
10454 vat_json_node_t *node = NULL;
10455
10456 if (VAT_JSON_ARRAY != vam->json_tree.type)
10457 {
10458 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10459 vat_json_init_array (&vam->json_tree);
10460 }
10461 node = vat_json_array_add (&vam->json_tree);
10462
10463 vat_json_init_object (node);
10464 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10465 if (mp->is_ipv6)
10466 {
10467 struct in6_addr ip6;
10468
10469 clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10470 vat_json_object_add_ip6 (node, "src_address", ip6);
10471 clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10472 vat_json_object_add_ip6 (node, "dst_address", ip6);
10473 }
10474 else
10475 {
10476 struct in_addr ip4;
10477
10478 clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10479 vat_json_object_add_ip4 (node, "src_address", ip4);
10480 clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10481 vat_json_object_add_ip4 (node, "dst_address", ip4);
10482 }
10483 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10484 vat_json_object_add_uint (node, "decap_next_index",
10485 ntohl (mp->decap_next_index));
10486 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10487 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10488 vat_json_object_add_uint (node, "mcast_sw_if_index",
10489 ntohl (mp->mcast_sw_if_index));
10490}
10491
10492static int
10493api_vxlan_tunnel_dump (vat_main_t * vam)
10494{
10495 unformat_input_t *i = vam->input;
10496 vl_api_vxlan_tunnel_dump_t *mp;
10497 f64 timeout;
10498 u32 sw_if_index;
10499 u8 sw_if_index_set = 0;
10500
10501 /* Parse args required to build the message */
10502 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10503 {
10504 if (unformat (i, "sw_if_index %d", &sw_if_index))
10505 sw_if_index_set = 1;
10506 else
10507 break;
10508 }
10509
10510 if (sw_if_index_set == 0)
10511 {
10512 sw_if_index = ~0;
10513 }
10514
10515 if (!vam->json_output)
10516 {
10517 print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10518 "sw_if_index", "src_address", "dst_address",
10519 "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10520 }
10521
10522 /* Get list of vxlan-tunnel interfaces */
10523 M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10524
10525 mp->sw_if_index = htonl (sw_if_index);
10526
10527 S;
10528
10529 /* Use a control ping for synchronization */
10530 {
10531 vl_api_control_ping_t *mp;
10532 M (CONTROL_PING, control_ping);
10533 S;
10534 }
10535 W;
10536}
10537
10538static int
10539api_gre_add_del_tunnel (vat_main_t * vam)
10540{
10541 unformat_input_t *line_input = vam->input;
10542 vl_api_gre_add_del_tunnel_t *mp;
10543 f64 timeout;
10544 ip4_address_t src4, dst4;
10545 u8 is_add = 1;
10546 u8 teb = 0;
10547 u8 src_set = 0;
10548 u8 dst_set = 0;
10549 u32 outer_fib_id = 0;
10550
10551 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10552 {
10553 if (unformat (line_input, "del"))
10554 is_add = 0;
10555 else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10556 src_set = 1;
10557 else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10558 dst_set = 1;
10559 else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10560 ;
10561 else if (unformat (line_input, "teb"))
10562 teb = 1;
10563 else
10564 {
10565 errmsg ("parse error '%U'", format_unformat_error, line_input);
10566 return -99;
10567 }
10568 }
10569
10570 if (src_set == 0)
10571 {
10572 errmsg ("tunnel src address not specified");
10573 return -99;
10574 }
10575 if (dst_set == 0)
10576 {
10577 errmsg ("tunnel dst address not specified");
10578 return -99;
10579 }
10580
10581
10582 M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10583
10584 clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10585 clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10586 mp->outer_fib_id = ntohl (outer_fib_id);
10587 mp->is_add = is_add;
10588 mp->teb = teb;
10589
10590 S;
10591 W;
10592 /* NOTREACHED */
10593 return 0;
10594}
10595
10596static void vl_api_gre_tunnel_details_t_handler
10597 (vl_api_gre_tunnel_details_t * mp)
10598{
10599 vat_main_t *vam = &vat_main;
10600
10601 print (vam->ofp, "%11d%15U%15U%6d%14d",
10602 ntohl (mp->sw_if_index),
10603 format_ip4_address, &mp->src_address,
10604 format_ip4_address, &mp->dst_address,
10605 mp->teb, ntohl (mp->outer_fib_id));
10606}
10607
10608static void vl_api_gre_tunnel_details_t_handler_json
10609 (vl_api_gre_tunnel_details_t * mp)
10610{
10611 vat_main_t *vam = &vat_main;
10612 vat_json_node_t *node = NULL;
10613 struct in_addr ip4;
10614
10615 if (VAT_JSON_ARRAY != vam->json_tree.type)
10616 {
10617 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10618 vat_json_init_array (&vam->json_tree);
10619 }
10620 node = vat_json_array_add (&vam->json_tree);
10621
10622 vat_json_init_object (node);
10623 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10624 clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10625 vat_json_object_add_ip4 (node, "src_address", ip4);
10626 clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10627 vat_json_object_add_ip4 (node, "dst_address", ip4);
10628 vat_json_object_add_uint (node, "teb", mp->teb);
10629 vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10630}
10631
10632static int
10633api_gre_tunnel_dump (vat_main_t * vam)
10634{
10635 unformat_input_t *i = vam->input;
10636 vl_api_gre_tunnel_dump_t *mp;
10637 f64 timeout;
10638 u32 sw_if_index;
10639 u8 sw_if_index_set = 0;
10640
10641 /* Parse args required to build the message */
10642 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10643 {
10644 if (unformat (i, "sw_if_index %d", &sw_if_index))
10645 sw_if_index_set = 1;
10646 else
10647 break;
10648 }
10649
10650 if (sw_if_index_set == 0)
10651 {
10652 sw_if_index = ~0;
10653 }
10654
10655 if (!vam->json_output)
10656 {
10657 print (vam->ofp, "%11s%15s%15s%6s%14s",
10658 "sw_if_index", "src_address", "dst_address", "teb",
10659 "outer_fib_id");
10660 }
10661
10662 /* Get list of gre-tunnel interfaces */
10663 M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10664
10665 mp->sw_if_index = htonl (sw_if_index);
10666
10667 S;
10668
10669 /* Use a control ping for synchronization */
10670 {
10671 vl_api_control_ping_t *mp;
10672 M (CONTROL_PING, control_ping);
10673 S;
10674 }
10675 W;
10676}
10677
10678static int
10679api_l2_fib_clear_table (vat_main_t * vam)
10680{
10681// unformat_input_t * i = vam->input;
10682 vl_api_l2_fib_clear_table_t *mp;
10683 f64 timeout;
10684
10685 M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10686
10687 S;
10688 W;
10689 /* NOTREACHED */
10690 return 0;
10691}
10692
10693static int
10694api_l2_interface_efp_filter (vat_main_t * vam)
10695{
10696 unformat_input_t *i = vam->input;
10697 vl_api_l2_interface_efp_filter_t *mp;
10698 f64 timeout;
10699 u32 sw_if_index;
10700 u8 enable = 1;
10701 u8 sw_if_index_set = 0;
10702
10703 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10704 {
10705 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10706 sw_if_index_set = 1;
10707 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10708 sw_if_index_set = 1;
10709 else if (unformat (i, "enable"))
10710 enable = 1;
10711 else if (unformat (i, "disable"))
10712 enable = 0;
10713 else
10714 {
10715 clib_warning ("parse error '%U'", format_unformat_error, i);
10716 return -99;
10717 }
10718 }
10719
10720 if (sw_if_index_set == 0)
10721 {
10722 errmsg ("missing sw_if_index");
10723 return -99;
10724 }
10725
10726 M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10727
10728 mp->sw_if_index = ntohl (sw_if_index);
10729 mp->enable_disable = enable;
10730
10731 S;
10732 W;
10733 /* NOTREACHED */
10734 return 0;
10735}
10736
10737#define foreach_vtr_op \
10738_("disable", L2_VTR_DISABLED) \
10739_("push-1", L2_VTR_PUSH_1) \
10740_("push-2", L2_VTR_PUSH_2) \
10741_("pop-1", L2_VTR_POP_1) \
10742_("pop-2", L2_VTR_POP_2) \
10743_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
10744_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
10745_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
10746_("translate-2-2", L2_VTR_TRANSLATE_2_2)
10747
10748static int
10749api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10750{
10751 unformat_input_t *i = vam->input;
10752 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10753 f64 timeout;
10754 u32 sw_if_index;
10755 u8 sw_if_index_set = 0;
10756 u8 vtr_op_set = 0;
10757 u32 vtr_op = 0;
10758 u32 push_dot1q = 1;
10759 u32 tag1 = ~0;
10760 u32 tag2 = ~0;
10761
10762 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10763 {
10764 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10765 sw_if_index_set = 1;
10766 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10767 sw_if_index_set = 1;
10768 else if (unformat (i, "vtr_op %d", &vtr_op))
10769 vtr_op_set = 1;
10770#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10771 foreach_vtr_op
10772#undef _
10773 else if (unformat (i, "push_dot1q %d", &push_dot1q))
10774 ;
10775 else if (unformat (i, "tag1 %d", &tag1))
10776 ;
10777 else if (unformat (i, "tag2 %d", &tag2))
10778 ;
10779 else
10780 {
10781 clib_warning ("parse error '%U'", format_unformat_error, i);
10782 return -99;
10783 }
10784 }
10785
10786 if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10787 {
10788 errmsg ("missing vtr operation or sw_if_index");
10789 return -99;
10790 }
10791
10792 M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10793 mp->sw_if_index = ntohl (sw_if_index);
10794 mp->vtr_op = ntohl (vtr_op);
10795 mp->push_dot1q = ntohl (push_dot1q);
10796 mp->tag1 = ntohl (tag1);
10797 mp->tag2 = ntohl (tag2);
10798
10799 S;
10800 W;
10801 /* NOTREACHED */
10802 return 0;
10803}
10804
10805static int
10806api_create_vhost_user_if (vat_main_t * vam)
10807{
10808 unformat_input_t *i = vam->input;
10809 vl_api_create_vhost_user_if_t *mp;
10810 f64 timeout;
10811 u8 *file_name;
10812 u8 is_server = 0;
10813 u8 file_name_set = 0;
10814 u32 custom_dev_instance = ~0;
10815 u8 hwaddr[6];
10816 u8 use_custom_mac = 0;
10817 u8 *tag = 0;
10818
10819 /* Shut up coverity */
10820 memset (hwaddr, 0, sizeof (hwaddr));
10821
10822 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10823 {
10824 if (unformat (i, "socket %s", &file_name))
10825 {
10826 file_name_set = 1;
10827 }
10828 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10829 ;
10830 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10831 use_custom_mac = 1;
10832 else if (unformat (i, "server"))
10833 is_server = 1;
10834 else if (unformat (i, "tag %s", &tag))
10835 ;
10836 else
10837 break;
10838 }
10839
10840 if (file_name_set == 0)
10841 {
10842 errmsg ("missing socket file name");
10843 return -99;
10844 }
10845
10846 if (vec_len (file_name) > 255)
10847 {
10848 errmsg ("socket file name too long");
10849 return -99;
10850 }
10851 vec_add1 (file_name, 0);
10852
10853 M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10854
10855 mp->is_server = is_server;
10856 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10857 vec_free (file_name);
10858 if (custom_dev_instance != ~0)
10859 {
10860 mp->renumber = 1;
10861 mp->custom_dev_instance = ntohl (custom_dev_instance);
10862 }
10863 mp->use_custom_mac = use_custom_mac;
10864 clib_memcpy (mp->mac_address, hwaddr, 6);
10865 if (tag)
10866 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10867 vec_free (tag);
10868
10869 S;
10870 W;
10871 /* NOTREACHED */
10872 return 0;
10873}
10874
10875static int
10876api_modify_vhost_user_if (vat_main_t * vam)
10877{
10878 unformat_input_t *i = vam->input;
10879 vl_api_modify_vhost_user_if_t *mp;
10880 f64 timeout;
10881 u8 *file_name;
10882 u8 is_server = 0;
10883 u8 file_name_set = 0;
10884 u32 custom_dev_instance = ~0;
10885 u8 sw_if_index_set = 0;
10886 u32 sw_if_index = (u32) ~ 0;
10887
10888 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10889 {
10890 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10891 sw_if_index_set = 1;
10892 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10893 sw_if_index_set = 1;
10894 else if (unformat (i, "socket %s", &file_name))
10895 {
10896 file_name_set = 1;
10897 }
10898 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10899 ;
10900 else if (unformat (i, "server"))
10901 is_server = 1;
10902 else
10903 break;
10904 }
10905
10906 if (sw_if_index_set == 0)
10907 {
10908 errmsg ("missing sw_if_index or interface name");
10909 return -99;
10910 }
10911
10912 if (file_name_set == 0)
10913 {
10914 errmsg ("missing socket file name");
10915 return -99;
10916 }
10917
10918 if (vec_len (file_name) > 255)
10919 {
10920 errmsg ("socket file name too long");
10921 return -99;
10922 }
10923 vec_add1 (file_name, 0);
10924
10925 M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10926
10927 mp->sw_if_index = ntohl (sw_if_index);
10928 mp->is_server = is_server;
10929 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10930 vec_free (file_name);
10931 if (custom_dev_instance != ~0)
10932 {
10933 mp->renumber = 1;
10934 mp->custom_dev_instance = ntohl (custom_dev_instance);
10935 }
10936
10937 S;
10938 W;
10939 /* NOTREACHED */
10940 return 0;
10941}
10942
10943static int
10944api_delete_vhost_user_if (vat_main_t * vam)
10945{
10946 unformat_input_t *i = vam->input;
10947 vl_api_delete_vhost_user_if_t *mp;
10948 f64 timeout;
10949 u32 sw_if_index = ~0;
10950 u8 sw_if_index_set = 0;
10951
10952 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10953 {
10954 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10955 sw_if_index_set = 1;
10956 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10957 sw_if_index_set = 1;
10958 else
10959 break;
10960 }
10961
10962 if (sw_if_index_set == 0)
10963 {
10964 errmsg ("missing sw_if_index or interface name");
10965 return -99;
10966 }
10967
10968
10969 M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10970
10971 mp->sw_if_index = ntohl (sw_if_index);
10972
10973 S;
10974 W;
10975 /* NOTREACHED */
10976 return 0;
10977}
10978
10979static void vl_api_sw_interface_vhost_user_details_t_handler
10980 (vl_api_sw_interface_vhost_user_details_t * mp)
10981{
10982 vat_main_t *vam = &vat_main;
10983
10984 print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
10985 (char *) mp->interface_name,
10986 ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10987 clib_net_to_host_u64 (mp->features), mp->is_server,
10988 ntohl (mp->num_regions), (char *) mp->sock_filename);
10989 print (vam->ofp, " Status: '%s'", strerror (ntohl (mp->sock_errno)));
10990}
10991
10992static void vl_api_sw_interface_vhost_user_details_t_handler_json
10993 (vl_api_sw_interface_vhost_user_details_t * mp)
10994{
10995 vat_main_t *vam = &vat_main;
10996 vat_json_node_t *node = NULL;
10997
10998 if (VAT_JSON_ARRAY != vam->json_tree.type)
10999 {
11000 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11001 vat_json_init_array (&vam->json_tree);
11002 }
11003 node = vat_json_array_add (&vam->json_tree);
11004
11005 vat_json_init_object (node);
11006 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11007 vat_json_object_add_string_copy (node, "interface_name",
11008 mp->interface_name);
11009 vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11010 ntohl (mp->virtio_net_hdr_sz));
11011 vat_json_object_add_uint (node, "features",
11012 clib_net_to_host_u64 (mp->features));
11013 vat_json_object_add_uint (node, "is_server", mp->is_server);
11014 vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11015 vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11016 vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11017}
11018
11019static int
11020api_sw_interface_vhost_user_dump (vat_main_t * vam)
11021{
11022 vl_api_sw_interface_vhost_user_dump_t *mp;
11023 f64 timeout;
11024 print (vam->ofp,
11025 "Interface name idx hdr_sz features server regions filename");
11026
11027 /* Get list of vhost-user interfaces */
11028 M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
11029 S;
11030
11031 /* Use a control ping for synchronization */
11032 {
11033 vl_api_control_ping_t *mp;
11034 M (CONTROL_PING, control_ping);
11035 S;
11036 }
11037 W;
11038}
11039
11040static int
11041api_show_version (vat_main_t * vam)
11042{
11043 vl_api_show_version_t *mp;
11044 f64 timeout;
11045
11046 M (SHOW_VERSION, show_version);
11047
11048 S;
11049 W;
11050 /* NOTREACHED */
11051 return 0;
11052}
11053
11054
11055static int
11056api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11057{
11058 unformat_input_t *line_input = vam->input;
11059 vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11060 f64 timeout;
11061 ip4_address_t local4, remote4;
11062 ip6_address_t local6, remote6;
11063 u8 is_add = 1;
11064 u8 ipv4_set = 0, ipv6_set = 0;
11065 u8 local_set = 0;
11066 u8 remote_set = 0;
11067 u32 encap_vrf_id = 0;
11068 u32 decap_vrf_id = 0;
11069 u8 protocol = ~0;
11070 u32 vni;
11071 u8 vni_set = 0;
11072
11073 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11074 {
11075 if (unformat (line_input, "del"))
11076 is_add = 0;
11077 else if (unformat (line_input, "local %U",
11078 unformat_ip4_address, &local4))
11079 {
11080 local_set = 1;
11081 ipv4_set = 1;
11082 }
11083 else if (unformat (line_input, "remote %U",
11084 unformat_ip4_address, &remote4))
11085 {
11086 remote_set = 1;
11087 ipv4_set = 1;
11088 }
11089 else if (unformat (line_input, "local %U",
11090 unformat_ip6_address, &local6))
11091 {
11092 local_set = 1;
11093 ipv6_set = 1;
11094 }
11095 else if (unformat (line_input, "remote %U",
11096 unformat_ip6_address, &remote6))
11097 {
11098 remote_set = 1;
11099 ipv6_set = 1;
11100 }
11101 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11102 ;
11103 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11104 ;
11105 else if (unformat (line_input, "vni %d", &vni))
11106 vni_set = 1;
11107 else if (unformat (line_input, "next-ip4"))
11108 protocol = 1;
11109 else if (unformat (line_input, "next-ip6"))
11110 protocol = 2;
11111 else if (unformat (line_input, "next-ethernet"))
11112 protocol = 3;
11113 else if (unformat (line_input, "next-nsh"))
11114 protocol = 4;
11115 else
11116 {
11117 errmsg ("parse error '%U'", format_unformat_error, line_input);
11118 return -99;
11119 }
11120 }
11121
11122 if (local_set == 0)
11123 {
11124 errmsg ("tunnel local address not specified");
11125 return -99;
11126 }
11127 if (remote_set == 0)
11128 {
11129 errmsg ("tunnel remote address not specified");
11130 return -99;
11131 }
11132 if (ipv4_set && ipv6_set)
11133 {
11134 errmsg ("both IPv4 and IPv6 addresses specified");
11135 return -99;
11136 }
11137
11138 if (vni_set == 0)
11139 {
11140 errmsg ("vni not specified");
11141 return -99;
11142 }
11143
11144 M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
11145
11146
11147 if (ipv6_set)
11148 {
11149 clib_memcpy (&mp->local, &local6, sizeof (local6));
11150 clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11151 }
11152 else
11153 {
11154 clib_memcpy (&mp->local, &local4, sizeof (local4));
11155 clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11156 }
11157
11158 mp->encap_vrf_id = ntohl (encap_vrf_id);
11159 mp->decap_vrf_id = ntohl (decap_vrf_id);
11160 mp->protocol = protocol;
11161 mp->vni = ntohl (vni);
11162 mp->is_add = is_add;
11163 mp->is_ipv6 = ipv6_set;
11164
11165 S;
11166 W;
11167 /* NOTREACHED */
11168 return 0;
11169}
11170
11171static void vl_api_vxlan_gpe_tunnel_details_t_handler
11172 (vl_api_vxlan_gpe_tunnel_details_t * mp)
11173{
11174 vat_main_t *vam = &vat_main;
11175
11176 print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11177 ntohl (mp->sw_if_index),
11178 format_ip46_address, &(mp->local[0]),
11179 format_ip46_address, &(mp->remote[0]),
11180 ntohl (mp->vni),
11181 ntohl (mp->protocol),
11182 ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11183}
11184
11185static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11186 (vl_api_vxlan_gpe_tunnel_details_t * mp)
11187{
11188 vat_main_t *vam = &vat_main;
11189 vat_json_node_t *node = NULL;
11190 struct in_addr ip4;
11191 struct in6_addr ip6;
11192
11193 if (VAT_JSON_ARRAY != vam->json_tree.type)
11194 {
11195 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11196 vat_json_init_array (&vam->json_tree);
11197 }
11198 node = vat_json_array_add (&vam->json_tree);
11199
11200 vat_json_init_object (node);
11201 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11202 if (mp->is_ipv6)
11203 {
11204 clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11205 vat_json_object_add_ip6 (node, "local", ip6);
11206 clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11207 vat_json_object_add_ip6 (node, "remote", ip6);
11208 }
11209 else
11210 {
11211 clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11212 vat_json_object_add_ip4 (node, "local", ip4);
11213 clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11214 vat_json_object_add_ip4 (node, "remote", ip4);
11215 }
11216 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11217 vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11218 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11219 vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11220 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11221}
11222
11223static int
11224api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11225{
11226 unformat_input_t *i = vam->input;
11227 vl_api_vxlan_gpe_tunnel_dump_t *mp;
11228 f64 timeout;
11229 u32 sw_if_index;
11230 u8 sw_if_index_set = 0;
11231
11232 /* Parse args required to build the message */
11233 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11234 {
11235 if (unformat (i, "sw_if_index %d", &sw_if_index))
11236 sw_if_index_set = 1;
11237 else
11238 break;
11239 }
11240
11241 if (sw_if_index_set == 0)
11242 {
11243 sw_if_index = ~0;
11244 }
11245
11246 if (!vam->json_output)
11247 {
11248 print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11249 "sw_if_index", "local", "remote", "vni",
11250 "protocol", "encap_vrf_id", "decap_vrf_id");
11251 }
11252
11253 /* Get list of vxlan-tunnel interfaces */
11254 M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11255
11256 mp->sw_if_index = htonl (sw_if_index);
11257
11258 S;
11259
11260 /* Use a control ping for synchronization */
11261 {
11262 vl_api_control_ping_t *mp;
11263 M (CONTROL_PING, control_ping);
11264 S;
11265 }
11266 W;
11267}
11268
11269u8 *
11270format_l2_fib_mac_address (u8 * s, va_list * args)
11271{
11272 u8 *a = va_arg (*args, u8 *);
11273
11274 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11275 a[2], a[3], a[4], a[5], a[6], a[7]);
11276}
11277
11278static void vl_api_l2_fib_table_entry_t_handler
11279 (vl_api_l2_fib_table_entry_t * mp)
11280{
11281 vat_main_t *vam = &vat_main;
11282
11283 print (vam->ofp, "%3" PRIu32 " %U %3" PRIu32
11284 " %d %d %d",
11285 ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11286 ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11287 mp->bvi_mac);
11288}
11289
11290static void vl_api_l2_fib_table_entry_t_handler_json
11291 (vl_api_l2_fib_table_entry_t * mp)
11292{
11293 vat_main_t *vam = &vat_main;
11294 vat_json_node_t *node = NULL;
11295
11296 if (VAT_JSON_ARRAY != vam->json_tree.type)
11297 {
11298 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11299 vat_json_init_array (&vam->json_tree);
11300 }
11301 node = vat_json_array_add (&vam->json_tree);
11302
11303 vat_json_init_object (node);
11304 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11305 vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11306 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11307 vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11308 vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11309 vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11310}
11311
11312static int
11313api_l2_fib_table_dump (vat_main_t * vam)
11314{
11315 unformat_input_t *i = vam->input;
11316 vl_api_l2_fib_table_dump_t *mp;
11317 f64 timeout;
11318 u32 bd_id;
11319 u8 bd_id_set = 0;
11320
11321 /* Parse args required to build the message */
11322 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11323 {
11324 if (unformat (i, "bd_id %d", &bd_id))
11325 bd_id_set = 1;
11326 else
11327 break;
11328 }
11329
11330 if (bd_id_set == 0)
11331 {
11332 errmsg ("missing bridge domain");
11333 return -99;
11334 }
11335
11336 print (vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI");
11337
11338 /* Get list of l2 fib entries */
11339 M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11340
11341 mp->bd_id = ntohl (bd_id);
11342 S;
11343
11344 /* Use a control ping for synchronization */
11345 {
11346 vl_api_control_ping_t *mp;
11347 M (CONTROL_PING, control_ping);
11348 S;
11349 }
11350 W;
11351}
11352
11353
11354static int
11355api_interface_name_renumber (vat_main_t * vam)
11356{
11357 unformat_input_t *line_input = vam->input;
11358 vl_api_interface_name_renumber_t *mp;
11359 u32 sw_if_index = ~0;
11360 f64 timeout;
11361 u32 new_show_dev_instance = ~0;
11362
11363 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11364 {
11365 if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11366 &sw_if_index))
11367 ;
11368 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11369 ;
11370 else if (unformat (line_input, "new_show_dev_instance %d",
11371 &new_show_dev_instance))
11372 ;
11373 else
11374 break;
11375 }
11376
11377 if (sw_if_index == ~0)
11378 {
11379 errmsg ("missing interface name or sw_if_index");
11380 return -99;
11381 }
11382
11383 if (new_show_dev_instance == ~0)
11384 {
11385 errmsg ("missing new_show_dev_instance");
11386 return -99;
11387 }
11388
11389 M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11390
11391 mp->sw_if_index = ntohl (sw_if_index);
11392 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11393
11394 S;
11395 W;
11396}
11397
11398static int
11399api_want_ip4_arp_events (vat_main_t * vam)
11400{
11401 unformat_input_t *line_input = vam->input;
11402 vl_api_want_ip4_arp_events_t *mp;
11403 f64 timeout;
11404 ip4_address_t address;
11405 int address_set = 0;
11406 u32 enable_disable = 1;
11407
11408 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11409 {
11410 if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11411 address_set = 1;
11412 else if (unformat (line_input, "del"))
11413 enable_disable = 0;
11414 else
11415 break;
11416 }
11417
11418 if (address_set == 0)
11419 {
11420 errmsg ("missing addresses");
11421 return -99;
11422 }
11423
11424 M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11425 mp->enable_disable = enable_disable;
11426 mp->pid = getpid ();
11427 mp->address = address.as_u32;
11428
11429 S;
11430 W;
11431}
11432
11433static int
11434api_want_ip6_nd_events (vat_main_t * vam)
11435{
11436 unformat_input_t *line_input = vam->input;
11437 vl_api_want_ip6_nd_events_t *mp;
11438 f64 timeout;
11439 ip6_address_t address;
11440 int address_set = 0;
11441 u32 enable_disable = 1;
11442
11443 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11444 {
11445 if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11446 address_set = 1;
11447 else if (unformat (line_input, "del"))
11448 enable_disable = 0;
11449 else
11450 break;
11451 }
11452
11453 if (address_set == 0)
11454 {
11455 errmsg ("missing addresses");
11456 return -99;
11457 }
11458
11459 M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11460 mp->enable_disable = enable_disable;
11461 mp->pid = getpid ();
11462 clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11463
11464 S;
11465 W;
11466}
11467
11468static int
11469api_input_acl_set_interface (vat_main_t * vam)
11470{
11471 unformat_input_t *i = vam->input;
11472 vl_api_input_acl_set_interface_t *mp;
11473 f64 timeout;
11474 u32 sw_if_index;
11475 int sw_if_index_set;
11476 u32 ip4_table_index = ~0;
11477 u32 ip6_table_index = ~0;
11478 u32 l2_table_index = ~0;
11479 u8 is_add = 1;
11480
11481 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11482 {
11483 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11484 sw_if_index_set = 1;
11485 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11486 sw_if_index_set = 1;
11487 else if (unformat (i, "del"))
11488 is_add = 0;
11489 else if (unformat (i, "ip4-table %d", &ip4_table_index))
11490 ;
11491 else if (unformat (i, "ip6-table %d", &ip6_table_index))
11492 ;
11493 else if (unformat (i, "l2-table %d", &l2_table_index))
11494 ;
11495 else
11496 {
11497 clib_warning ("parse error '%U'", format_unformat_error, i);
11498 return -99;
11499 }
11500 }
11501
11502 if (sw_if_index_set == 0)
11503 {
11504 errmsg ("missing interface name or sw_if_index");
11505 return -99;
11506 }
11507
11508 M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11509
11510 mp->sw_if_index = ntohl (sw_if_index);
11511 mp->ip4_table_index = ntohl (ip4_table_index);
11512 mp->ip6_table_index = ntohl (ip6_table_index);
11513 mp->l2_table_index = ntohl (l2_table_index);
11514 mp->is_add = is_add;
11515
11516 S;
11517 W;
11518 /* NOTREACHED */
11519 return 0;
11520}
11521
11522static int
11523api_ip_address_dump (vat_main_t * vam)
11524{
11525 unformat_input_t *i = vam->input;
11526 vl_api_ip_address_dump_t *mp;
11527 u32 sw_if_index = ~0;
11528 u8 sw_if_index_set = 0;
11529 u8 ipv4_set = 0;
11530 u8 ipv6_set = 0;
11531 f64 timeout;
11532
11533 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11534 {
11535 if (unformat (i, "sw_if_index %d", &sw_if_index))
11536 sw_if_index_set = 1;
11537 else
11538 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11539 sw_if_index_set = 1;
11540 else if (unformat (i, "ipv4"))
11541 ipv4_set = 1;
11542 else if (unformat (i, "ipv6"))
11543 ipv6_set = 1;
11544 else
11545 break;
11546 }
11547
11548 if (ipv4_set && ipv6_set)
11549 {
11550 errmsg ("ipv4 and ipv6 flags cannot be both set");
11551 return -99;
11552 }
11553
11554 if ((!ipv4_set) && (!ipv6_set))
11555 {
11556 errmsg ("no ipv4 nor ipv6 flag set");
11557 return -99;
11558 }
11559
11560 if (sw_if_index_set == 0)
11561 {
11562 errmsg ("missing interface name or sw_if_index");
11563 return -99;
11564 }
11565
11566 vam->current_sw_if_index = sw_if_index;
11567 vam->is_ipv6 = ipv6_set;
11568
11569 M (IP_ADDRESS_DUMP, ip_address_dump);
11570 mp->sw_if_index = ntohl (sw_if_index);
11571 mp->is_ipv6 = ipv6_set;
11572 S;
11573
11574 /* Use a control ping for synchronization */
11575 {
11576 vl_api_control_ping_t *mp;
11577 M (CONTROL_PING, control_ping);
11578 S;
11579 }
11580 W;
11581}
11582
11583static int
11584api_ip_dump (vat_main_t * vam)
11585{
11586 vl_api_ip_dump_t *mp;
11587 unformat_input_t *in = vam->input;
11588 int ipv4_set = 0;
11589 int ipv6_set = 0;
11590 int is_ipv6;
11591 f64 timeout;
11592 int i;
11593
11594 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11595 {
11596 if (unformat (in, "ipv4"))
11597 ipv4_set = 1;
11598 else if (unformat (in, "ipv6"))
11599 ipv6_set = 1;
11600 else
11601 break;
11602 }
11603
11604 if (ipv4_set && ipv6_set)
11605 {
11606 errmsg ("ipv4 and ipv6 flags cannot be both set");
11607 return -99;
11608 }
11609
11610 if ((!ipv4_set) && (!ipv6_set))
11611 {
11612 errmsg ("no ipv4 nor ipv6 flag set");
11613 return -99;
11614 }
11615
11616 is_ipv6 = ipv6_set;
11617 vam->is_ipv6 = is_ipv6;
11618
11619 /* free old data */
11620 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11621 {
11622 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11623 }
11624 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11625
11626 M (IP_DUMP, ip_dump);
11627 mp->is_ipv6 = ipv6_set;
11628 S;
11629
11630 /* Use a control ping for synchronization */
11631 {
11632 vl_api_control_ping_t *mp;
11633 M (CONTROL_PING, control_ping);
11634 S;
11635 }
11636 W;
11637}
11638
11639static int
11640api_ipsec_spd_add_del (vat_main_t * vam)
11641{
11642 unformat_input_t *i = vam->input;
11643 vl_api_ipsec_spd_add_del_t *mp;
11644 f64 timeout;
11645 u32 spd_id = ~0;
11646 u8 is_add = 1;
11647
11648 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11649 {
11650 if (unformat (i, "spd_id %d", &spd_id))
11651 ;
11652 else if (unformat (i, "del"))
11653 is_add = 0;
11654 else
11655 {
11656 clib_warning ("parse error '%U'", format_unformat_error, i);
11657 return -99;
11658 }
11659 }
11660 if (spd_id == ~0)
11661 {
11662 errmsg ("spd_id must be set");
11663 return -99;
11664 }
11665
11666 M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11667
11668 mp->spd_id = ntohl (spd_id);
11669 mp->is_add = is_add;
11670
11671 S;
11672 W;
11673 /* NOTREACHED */
11674 return 0;
11675}
11676
11677static int
11678api_ipsec_interface_add_del_spd (vat_main_t * vam)
11679{
11680 unformat_input_t *i = vam->input;
11681 vl_api_ipsec_interface_add_del_spd_t *mp;
11682 f64 timeout;
11683 u32 sw_if_index;
11684 u8 sw_if_index_set = 0;
11685 u32 spd_id = (u32) ~ 0;
11686 u8 is_add = 1;
11687
11688 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11689 {
11690 if (unformat (i, "del"))
11691 is_add = 0;
11692 else if (unformat (i, "spd_id %d", &spd_id))
11693 ;
11694 else
11695 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11696 sw_if_index_set = 1;
11697 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11698 sw_if_index_set = 1;
11699 else
11700 {
11701 clib_warning ("parse error '%U'", format_unformat_error, i);
11702 return -99;
11703 }
11704
11705 }
11706
11707 if (spd_id == (u32) ~ 0)
11708 {
11709 errmsg ("spd_id must be set");
11710 return -99;
11711 }
11712
11713 if (sw_if_index_set == 0)
11714 {
11715 errmsg ("missing interface name or sw_if_index");
11716 return -99;
11717 }
11718
11719 M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11720
11721 mp->spd_id = ntohl (spd_id);
11722 mp->sw_if_index = ntohl (sw_if_index);
11723 mp->is_add = is_add;
11724
11725 S;
11726 W;
11727 /* NOTREACHED */
11728 return 0;
11729}
11730
11731static int
11732api_ipsec_spd_add_del_entry (vat_main_t * vam)
11733{
11734 unformat_input_t *i = vam->input;
11735 vl_api_ipsec_spd_add_del_entry_t *mp;
11736 f64 timeout;
11737 u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11738 u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11739 i32 priority = 0;
11740 u32 rport_start = 0, rport_stop = (u32) ~ 0;
11741 u32 lport_start = 0, lport_stop = (u32) ~ 0;
11742 ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11743 ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11744
11745 laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11746 laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11747 laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11748 laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11749 laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11750 laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11751
11752 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11753 {
11754 if (unformat (i, "del"))
11755 is_add = 0;
11756 if (unformat (i, "outbound"))
11757 is_outbound = 1;
11758 if (unformat (i, "inbound"))
11759 is_outbound = 0;
11760 else if (unformat (i, "spd_id %d", &spd_id))
11761 ;
11762 else if (unformat (i, "sa_id %d", &sa_id))
11763 ;
11764 else if (unformat (i, "priority %d", &priority))
11765 ;
11766 else if (unformat (i, "protocol %d", &protocol))
11767 ;
11768 else if (unformat (i, "lport_start %d", &lport_start))
11769 ;
11770 else if (unformat (i, "lport_stop %d", &lport_stop))
11771 ;
11772 else if (unformat (i, "rport_start %d", &rport_start))
11773 ;
11774 else if (unformat (i, "rport_stop %d", &rport_stop))
11775 ;
11776 else
11777 if (unformat
11778 (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11779 {
11780 is_ipv6 = 0;
11781 is_ip_any = 0;
11782 }
11783 else
11784 if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11785 {
11786 is_ipv6 = 0;
11787 is_ip_any = 0;
11788 }
11789 else
11790 if (unformat
11791 (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11792 {
11793 is_ipv6 = 0;
11794 is_ip_any = 0;
11795 }
11796 else
11797 if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11798 {
11799 is_ipv6 = 0;
11800 is_ip_any = 0;
11801 }
11802 else
11803 if (unformat
11804 (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11805 {
11806 is_ipv6 = 1;
11807 is_ip_any = 0;
11808 }
11809 else
11810 if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11811 {
11812 is_ipv6 = 1;
11813 is_ip_any = 0;
11814 }
11815 else
11816 if (unformat
11817 (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11818 {
11819 is_ipv6 = 1;
11820 is_ip_any = 0;
11821 }
11822 else
11823 if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11824 {
11825 is_ipv6 = 1;
11826 is_ip_any = 0;
11827 }
11828 else
11829 if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11830 {
11831 if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11832 {
11833 clib_warning ("unsupported action: 'resolve'");
11834 return -99;
11835 }
11836 }
11837 else
11838 {
11839 clib_warning ("parse error '%U'", format_unformat_error, i);
11840 return -99;
11841 }
11842
11843 }
11844
11845 M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11846
11847 mp->spd_id = ntohl (spd_id);
11848 mp->priority = ntohl (priority);
11849 mp->is_outbound = is_outbound;
11850
11851 mp->is_ipv6 = is_ipv6;
11852 if (is_ipv6 || is_ip_any)
11853 {
11854 clib_memcpy (mp->remote_address_start, &raddr6_start,
11855 sizeof (ip6_address_t));
11856 clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11857 sizeof (ip6_address_t));
11858 clib_memcpy (mp->local_address_start, &laddr6_start,
11859 sizeof (ip6_address_t));
11860 clib_memcpy (mp->local_address_stop, &laddr6_stop,
11861 sizeof (ip6_address_t));
11862 }
11863 else
11864 {
11865 clib_memcpy (mp->remote_address_start, &raddr4_start,
11866 sizeof (ip4_address_t));
11867 clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11868 sizeof (ip4_address_t));
11869 clib_memcpy (mp->local_address_start, &laddr4_start,
11870 sizeof (ip4_address_t));
11871 clib_memcpy (mp->local_address_stop, &laddr4_stop,
11872 sizeof (ip4_address_t));
11873 }
11874 mp->protocol = (u8) protocol;
11875 mp->local_port_start = ntohs ((u16) lport_start);
11876 mp->local_port_stop = ntohs ((u16) lport_stop);
11877 mp->remote_port_start = ntohs ((u16) rport_start);
11878 mp->remote_port_stop = ntohs ((u16) rport_stop);
11879 mp->policy = (u8) policy;
11880 mp->sa_id = ntohl (sa_id);
11881 mp->is_add = is_add;
11882 mp->is_ip_any = is_ip_any;
11883 S;
11884 W;
11885 /* NOTREACHED */
11886 return 0;
11887}
11888
11889static int
11890api_ipsec_sad_add_del_entry (vat_main_t * vam)
11891{
11892 unformat_input_t *i = vam->input;
11893 vl_api_ipsec_sad_add_del_entry_t *mp;
11894 f64 timeout;
11895 u32 sad_id = 0, spi = 0;
11896 u8 *ck = 0, *ik = 0;
11897 u8 is_add = 1;
11898
11899 u8 protocol = IPSEC_PROTOCOL_AH;
11900 u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11901 u32 crypto_alg = 0, integ_alg = 0;
11902 ip4_address_t tun_src4;
11903 ip4_address_t tun_dst4;
11904 ip6_address_t tun_src6;
11905 ip6_address_t tun_dst6;
11906
11907 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11908 {
11909 if (unformat (i, "del"))
11910 is_add = 0;
11911 else if (unformat (i, "sad_id %d", &sad_id))
11912 ;
11913 else if (unformat (i, "spi %d", &spi))
11914 ;
11915 else if (unformat (i, "esp"))
11916 protocol = IPSEC_PROTOCOL_ESP;
11917 else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11918 {
11919 is_tunnel = 1;
11920 is_tunnel_ipv6 = 0;
11921 }
11922 else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11923 {
11924 is_tunnel = 1;
11925 is_tunnel_ipv6 = 0;
11926 }
11927 else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11928 {
11929 is_tunnel = 1;
11930 is_tunnel_ipv6 = 1;
11931 }
11932 else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11933 {
11934 is_tunnel = 1;
11935 is_tunnel_ipv6 = 1;
11936 }
11937 else
11938 if (unformat
11939 (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11940 {
11941 if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11942 crypto_alg >= IPSEC_CRYPTO_N_ALG)
11943 {
11944 clib_warning ("unsupported crypto-alg: '%U'",
11945 format_ipsec_crypto_alg, crypto_alg);
11946 return -99;
11947 }
11948 }
11949 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11950 ;
11951 else
11952 if (unformat
11953 (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11954 {
11955#if DPDK_CRYPTO==1
11956 if (integ_alg < IPSEC_INTEG_ALG_NONE ||
11957#else
11958 if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11959#endif
11960 integ_alg >= IPSEC_INTEG_N_ALG)
11961 {
11962 clib_warning ("unsupported integ-alg: '%U'",
11963 format_ipsec_integ_alg, integ_alg);
11964 return -99;
11965 }
11966 }
11967 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11968 ;
11969 else
11970 {
11971 clib_warning ("parse error '%U'", format_unformat_error, i);
11972 return -99;
11973 }
11974
11975 }
11976
11977#if DPDK_CRYPTO==1
11978 /*Special cases, aes-gcm-128 encryption */
11979 if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
11980 {
11981 if (integ_alg != IPSEC_INTEG_ALG_NONE
11982 && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
11983 {
11984 clib_warning
11985 ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
11986 return -99;
11987 }
11988 else /*set integ-alg internally to aes-gcm-128 */
11989 integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
11990 }
11991 else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
11992 {
11993 clib_warning ("unsupported integ-alg: aes-gcm-128");
11994 return -99;
11995 }
11996 else if (integ_alg == IPSEC_INTEG_ALG_NONE)
11997 {
11998 clib_warning ("unsupported integ-alg: none");
11999 return -99;
12000 }
12001#endif
12002
12003
12004 M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
12005
12006 mp->sad_id = ntohl (sad_id);
12007 mp->is_add = is_add;
12008 mp->protocol = protocol;
12009 mp->spi = ntohl (spi);
12010 mp->is_tunnel = is_tunnel;
12011 mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12012 mp->crypto_algorithm = crypto_alg;
12013 mp->integrity_algorithm = integ_alg;
12014 mp->crypto_key_length = vec_len (ck);
12015 mp->integrity_key_length = vec_len (ik);
12016
12017 if (mp->crypto_key_length > sizeof (mp->crypto_key))
12018 mp->crypto_key_length = sizeof (mp->crypto_key);
12019
12020 if (mp->integrity_key_length > sizeof (mp->integrity_key))
12021 mp->integrity_key_length = sizeof (mp->integrity_key);
12022
12023 if (ck)
12024 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12025 if (ik)
12026 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12027
12028 if (is_tunnel)
12029 {
12030 if (is_tunnel_ipv6)
12031 {
12032 clib_memcpy (mp->tunnel_src_address, &tun_src6,
12033 sizeof (ip6_address_t));
12034 clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12035 sizeof (ip6_address_t));
12036 }
12037 else
12038 {
12039 clib_memcpy (mp->tunnel_src_address, &tun_src4,
12040 sizeof (ip4_address_t));
12041 clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12042 sizeof (ip4_address_t));
12043 }
12044 }
12045
12046 S;
12047 W;
12048 /* NOTREACHED */
12049 return 0;
12050}
12051
12052static int
12053api_ipsec_sa_set_key (vat_main_t * vam)
12054{
12055 unformat_input_t *i = vam->input;
12056 vl_api_ipsec_sa_set_key_t *mp;
12057 f64 timeout;
12058 u32 sa_id;
12059 u8 *ck = 0, *ik = 0;
12060
12061 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12062 {
12063 if (unformat (i, "sa_id %d", &sa_id))
12064 ;
12065 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12066 ;
12067 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12068 ;
12069 else
12070 {
12071 clib_warning ("parse error '%U'", format_unformat_error, i);
12072 return -99;
12073 }
12074 }
12075
12076 M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
12077
12078 mp->sa_id = ntohl (sa_id);
12079 mp->crypto_key_length = vec_len (ck);
12080 mp->integrity_key_length = vec_len (ik);
12081
12082 if (mp->crypto_key_length > sizeof (mp->crypto_key))
12083 mp->crypto_key_length = sizeof (mp->crypto_key);
12084
12085 if (mp->integrity_key_length > sizeof (mp->integrity_key))
12086 mp->integrity_key_length = sizeof (mp->integrity_key);
12087
12088 if (ck)
12089 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12090 if (ik)
12091 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12092
12093 S;
12094 W;
12095 /* NOTREACHED */
12096 return 0;
12097}
12098
12099static int
12100api_ikev2_profile_add_del (vat_main_t * vam)
12101{
12102 unformat_input_t *i = vam->input;
12103 vl_api_ikev2_profile_add_del_t *mp;
12104 f64 timeout;
12105 u8 is_add = 1;
12106 u8 *name = 0;
12107
12108 const char *valid_chars = "a-zA-Z0-9_";
12109
12110 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12111 {
12112 if (unformat (i, "del"))
12113 is_add = 0;
12114 else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12115 vec_add1 (name, 0);
12116 else
12117 {
12118 errmsg ("parse error '%U'", format_unformat_error, i);
12119 return -99;
12120 }
12121 }
12122
12123 if (!vec_len (name))
12124 {
12125 errmsg ("profile name must be specified");
12126 return -99;
12127 }
12128
12129 if (vec_len (name) > 64)
12130 {
12131 errmsg ("profile name too long");
12132 return -99;
12133 }
12134
12135 M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
12136
12137 clib_memcpy (mp->name, name, vec_len (name));
12138 mp->is_add = is_add;
12139 vec_free (name);
12140
12141 S;
12142 W;
12143 /* NOTREACHED */
12144 return 0;
12145}
12146
12147static int
12148api_ikev2_profile_set_auth (vat_main_t * vam)
12149{
12150 unformat_input_t *i = vam->input;
12151 vl_api_ikev2_profile_set_auth_t *mp;
12152 f64 timeout;
12153 u8 *name = 0;
12154 u8 *data = 0;
12155 u32 auth_method = 0;
12156 u8 is_hex = 0;
12157
12158 const char *valid_chars = "a-zA-Z0-9_";
12159
12160 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12161 {
12162 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12163 vec_add1 (name, 0);
12164 else if (unformat (i, "auth_method %U",
12165 unformat_ikev2_auth_method, &auth_method))
12166 ;
12167 else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12168 is_hex = 1;
12169 else if (unformat (i, "auth_data %v", &data))
12170 ;
12171 else
12172 {
12173 errmsg ("parse error '%U'", format_unformat_error, i);
12174 return -99;
12175 }
12176 }
12177
12178 if (!vec_len (name))
12179 {
12180 errmsg ("profile name must be specified");
12181 return -99;
12182 }
12183
12184 if (vec_len (name) > 64)
12185 {
12186 errmsg ("profile name too long");
12187 return -99;
12188 }
12189
12190 if (!vec_len (data))
12191 {
12192 errmsg ("auth_data must be specified");
12193 return -99;
12194 }
12195
12196 if (!auth_method)
12197 {
12198 errmsg ("auth_method must be specified");
12199 return -99;
12200 }
12201
12202 M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12203
12204 mp->is_hex = is_hex;
12205 mp->auth_method = (u8) auth_method;
12206 mp->data_len = vec_len (data);
12207 clib_memcpy (mp->name, name, vec_len (name));
12208 clib_memcpy (mp->data, data, vec_len (data));
12209 vec_free (name);
12210 vec_free (data);
12211
12212 S;
12213 W;
12214 /* NOTREACHED */
12215 return 0;
12216}
12217
12218static int
12219api_ikev2_profile_set_id (vat_main_t * vam)
12220{
12221 unformat_input_t *i = vam->input;
12222 vl_api_ikev2_profile_set_id_t *mp;
12223 f64 timeout;
12224 u8 *name = 0;
12225 u8 *data = 0;
12226 u8 is_local = 0;
12227 u32 id_type = 0;
12228 ip4_address_t ip4;
12229
12230 const char *valid_chars = "a-zA-Z0-9_";
12231
12232 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12233 {
12234 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12235 vec_add1 (name, 0);
12236 else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12237 ;
12238 else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12239 {
12240 data = vec_new (u8, 4);
12241 clib_memcpy (data, ip4.as_u8, 4);
12242 }
12243 else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12244 ;
12245 else if (unformat (i, "id_data %v", &data))
12246 ;
12247 else if (unformat (i, "local"))
12248 is_local = 1;
12249 else if (unformat (i, "remote"))
12250 is_local = 0;
12251 else
12252 {
12253 errmsg ("parse error '%U'", format_unformat_error, i);
12254 return -99;
12255 }
12256 }
12257
12258 if (!vec_len (name))
12259 {
12260 errmsg ("profile name must be specified");
12261 return -99;
12262 }
12263
12264 if (vec_len (name) > 64)
12265 {
12266 errmsg ("profile name too long");
12267 return -99;
12268 }
12269
12270 if (!vec_len (data))
12271 {
12272 errmsg ("id_data must be specified");
12273 return -99;
12274 }
12275
12276 if (!id_type)
12277 {
12278 errmsg ("id_type must be specified");
12279 return -99;
12280 }
12281
12282 M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12283
12284 mp->is_local = is_local;
12285 mp->id_type = (u8) id_type;
12286 mp->data_len = vec_len (data);
12287 clib_memcpy (mp->name, name, vec_len (name));
12288 clib_memcpy (mp->data, data, vec_len (data));
12289 vec_free (name);
12290 vec_free (data);
12291
12292 S;
12293 W;
12294 /* NOTREACHED */
12295 return 0;
12296}
12297
12298static int
12299api_ikev2_profile_set_ts (vat_main_t * vam)
12300{
12301 unformat_input_t *i = vam->input;
12302 vl_api_ikev2_profile_set_ts_t *mp;
12303 f64 timeout;
12304 u8 *name = 0;
12305 u8 is_local = 0;
12306 u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12307 ip4_address_t start_addr, end_addr;
12308
12309 const char *valid_chars = "a-zA-Z0-9_";
12310
12311 start_addr.as_u32 = 0;
12312 end_addr.as_u32 = (u32) ~ 0;
12313
12314 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12315 {
12316 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12317 vec_add1 (name, 0);
12318 else if (unformat (i, "protocol %d", &proto))
12319 ;
12320 else if (unformat (i, "start_port %d", &start_port))
12321 ;
12322 else if (unformat (i, "end_port %d", &end_port))
12323 ;
12324 else
12325 if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12326 ;
12327 else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12328 ;
12329 else if (unformat (i, "local"))
12330 is_local = 1;
12331 else if (unformat (i, "remote"))
12332 is_local = 0;
12333 else
12334 {
12335 errmsg ("parse error '%U'", format_unformat_error, i);
12336 return -99;
12337 }
12338 }
12339
12340 if (!vec_len (name))
12341 {
12342 errmsg ("profile name must be specified");
12343 return -99;
12344 }
12345
12346 if (vec_len (name) > 64)
12347 {
12348 errmsg ("profile name too long");
12349 return -99;
12350 }
12351
12352 M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12353
12354 mp->is_local = is_local;
12355 mp->proto = (u8) proto;
12356 mp->start_port = (u16) start_port;
12357 mp->end_port = (u16) end_port;
12358 mp->start_addr = start_addr.as_u32;
12359 mp->end_addr = end_addr.as_u32;
12360 clib_memcpy (mp->name, name, vec_len (name));
12361 vec_free (name);
12362
12363 S;
12364 W;
12365 /* NOTREACHED */
12366 return 0;
12367}
12368
12369static int
12370api_ikev2_set_local_key (vat_main_t * vam)
12371{
12372 unformat_input_t *i = vam->input;
12373 vl_api_ikev2_set_local_key_t *mp;
12374 f64 timeout;
12375 u8 *file = 0;
12376
12377 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12378 {
12379 if (unformat (i, "file %v", &file))
12380 vec_add1 (file, 0);
12381 else
12382 {
12383 errmsg ("parse error '%U'", format_unformat_error, i);
12384 return -99;
12385 }
12386 }
12387
12388 if (!vec_len (file))
12389 {
12390 errmsg ("RSA key file must be specified");
12391 return -99;
12392 }
12393
12394 if (vec_len (file) > 256)
12395 {
12396 errmsg ("file name too long");
12397 return -99;
12398 }
12399
12400 M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12401
12402 clib_memcpy (mp->key_file, file, vec_len (file));
12403 vec_free (file);
12404
12405 S;
12406 W;
12407 /* NOTREACHED */
12408 return 0;
12409}
12410
12411/*
12412 * MAP
12413 */
12414static int
12415api_map_add_domain (vat_main_t * vam)
12416{
12417 unformat_input_t *i = vam->input;
12418 vl_api_map_add_domain_t *mp;
12419 f64 timeout;
12420
12421 ip4_address_t ip4_prefix;
12422 ip6_address_t ip6_prefix;
12423 ip6_address_t ip6_src;
12424 u32 num_m_args = 0;
12425 u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12426 0, psid_length = 0;
12427 u8 is_translation = 0;
12428 u32 mtu = 0;
12429 u32 ip6_src_len = 128;
12430
12431 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12432 {
12433 if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12434 &ip4_prefix, &ip4_prefix_len))
12435 num_m_args++;
12436 else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12437 &ip6_prefix, &ip6_prefix_len))
12438 num_m_args++;
12439 else
12440 if (unformat
12441 (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12442 &ip6_src_len))
12443 num_m_args++;
12444 else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12445 num_m_args++;
12446 else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12447 num_m_args++;
12448 else if (unformat (i, "psid-offset %d", &psid_offset))
12449 num_m_args++;
12450 else if (unformat (i, "psid-len %d", &psid_length))
12451 num_m_args++;
12452 else if (unformat (i, "mtu %d", &mtu))
12453 num_m_args++;
12454 else if (unformat (i, "map-t"))
12455 is_translation = 1;
12456 else
12457 {
12458 clib_warning ("parse error '%U'", format_unformat_error, i);
12459 return -99;
12460 }
12461 }
12462
12463 if (num_m_args < 3)
12464 {
12465 errmsg ("mandatory argument(s) missing");
12466 return -99;
12467 }
12468
12469 /* Construct the API message */
12470 M (MAP_ADD_DOMAIN, map_add_domain);
12471
12472 clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12473 mp->ip4_prefix_len = ip4_prefix_len;
12474
12475 clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12476 mp->ip6_prefix_len = ip6_prefix_len;
12477
12478 clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12479 mp->ip6_src_prefix_len = ip6_src_len;
12480
12481 mp->ea_bits_len = ea_bits_len;
12482 mp->psid_offset = psid_offset;
12483 mp->psid_length = psid_length;
12484 mp->is_translation = is_translation;
12485 mp->mtu = htons (mtu);
12486
12487 /* send it... */
12488 S;
12489
12490 /* Wait for a reply, return good/bad news */
12491 W;
12492}
12493
12494static int
12495api_map_del_domain (vat_main_t * vam)
12496{
12497 unformat_input_t *i = vam->input;
12498 vl_api_map_del_domain_t *mp;
12499 f64 timeout;
12500
12501 u32 num_m_args = 0;
12502 u32 index;
12503
12504 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12505 {
12506 if (unformat (i, "index %d", &index))
12507 num_m_args++;
12508 else
12509 {
12510 clib_warning ("parse error '%U'", format_unformat_error, i);
12511 return -99;
12512 }
12513 }
12514
12515 if (num_m_args != 1)
12516 {
12517 errmsg ("mandatory argument(s) missing");
12518 return -99;
12519 }
12520
12521 /* Construct the API message */
12522 M (MAP_DEL_DOMAIN, map_del_domain);
12523
12524 mp->index = ntohl (index);
12525
12526 /* send it... */
12527 S;
12528
12529 /* Wait for a reply, return good/bad news */
12530 W;
12531}
12532
12533static int
12534api_map_add_del_rule (vat_main_t * vam)
12535{
12536 unformat_input_t *i = vam->input;
12537 vl_api_map_add_del_rule_t *mp;
12538 f64 timeout;
12539 u8 is_add = 1;
12540 ip6_address_t ip6_dst;
12541 u32 num_m_args = 0, index, psid = 0;
12542
12543 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12544 {
12545 if (unformat (i, "index %d", &index))
12546 num_m_args++;
12547 else if (unformat (i, "psid %d", &psid))
12548 num_m_args++;
12549 else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12550 num_m_args++;
12551 else if (unformat (i, "del"))
12552 {
12553 is_add = 0;
12554 }
12555 else
12556 {
12557 clib_warning ("parse error '%U'", format_unformat_error, i);
12558 return -99;
12559 }
12560 }
12561
12562 /* Construct the API message */
12563 M (MAP_ADD_DEL_RULE, map_add_del_rule);
12564
12565 mp->index = ntohl (index);
12566 mp->is_add = is_add;
12567 clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12568 mp->psid = ntohs (psid);
12569
12570 /* send it... */
12571 S;
12572
12573 /* Wait for a reply, return good/bad news */
12574 W;
12575}
12576
12577static int
12578api_map_domain_dump (vat_main_t * vam)
12579{
12580 vl_api_map_domain_dump_t *mp;
12581 f64 timeout;
12582
12583 /* Construct the API message */
12584 M (MAP_DOMAIN_DUMP, map_domain_dump);
12585
12586 /* send it... */
12587 S;
12588
12589 /* Use a control ping for synchronization */
12590 {
12591 vl_api_control_ping_t *mp;
12592 M (CONTROL_PING, control_ping);
12593 S;
12594 }
12595 W;
12596}
12597
12598static int
12599api_map_rule_dump (vat_main_t * vam)
12600{
12601 unformat_input_t *i = vam->input;
12602 vl_api_map_rule_dump_t *mp;
12603 f64 timeout;
12604 u32 domain_index = ~0;
12605
12606 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12607 {
12608 if (unformat (i, "index %u", &domain_index))
12609 ;
12610 else
12611 break;
12612 }
12613
12614 if (domain_index == ~0)
12615 {
12616 clib_warning ("parse error: domain index expected");
12617 return -99;
12618 }
12619
12620 /* Construct the API message */
12621 M (MAP_RULE_DUMP, map_rule_dump);
12622
12623 mp->domain_index = htonl (domain_index);
12624
12625 /* send it... */
12626 S;
12627
12628 /* Use a control ping for synchronization */
12629 {
12630 vl_api_control_ping_t *mp;
12631 M (CONTROL_PING, control_ping);
12632 S;
12633 }
12634 W;
12635}
12636
12637static void vl_api_map_add_domain_reply_t_handler
12638 (vl_api_map_add_domain_reply_t * mp)
12639{
12640 vat_main_t *vam = &vat_main;
12641 i32 retval = ntohl (mp->retval);
12642
12643 if (vam->async_mode)
12644 {
12645 vam->async_errors += (retval < 0);
12646 }
12647 else
12648 {
12649 vam->retval = retval;
12650 vam->result_ready = 1;
12651 }
12652}
12653
12654static void vl_api_map_add_domain_reply_t_handler_json
12655 (vl_api_map_add_domain_reply_t * mp)
12656{
12657 vat_main_t *vam = &vat_main;
12658 vat_json_node_t node;
12659
12660 vat_json_init_object (&node);
12661 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12662 vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12663
12664 vat_json_print (vam->ofp, &node);
12665 vat_json_free (&node);
12666
12667 vam->retval = ntohl (mp->retval);
12668 vam->result_ready = 1;
12669}
12670
12671static int
12672api_get_first_msg_id (vat_main_t * vam)
12673{
12674 vl_api_get_first_msg_id_t *mp;
12675 f64 timeout;
12676 unformat_input_t *i = vam->input;
12677 u8 *name;
12678 u8 name_set = 0;
12679
12680 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12681 {
12682 if (unformat (i, "client %s", &name))
12683 name_set = 1;
12684 else
12685 break;
12686 }
12687
12688 if (name_set == 0)
12689 {
12690 errmsg ("missing client name");
12691 return -99;
12692 }
12693 vec_add1 (name, 0);
12694
12695 if (vec_len (name) > 63)
12696 {
12697 errmsg ("client name too long");
12698 return -99;
12699 }
12700
12701 M (GET_FIRST_MSG_ID, get_first_msg_id);
12702 clib_memcpy (mp->name, name, vec_len (name));
12703 S;
12704 W;
12705 /* NOTREACHED */
12706 return 0;
12707}
12708
12709static int
12710api_cop_interface_enable_disable (vat_main_t * vam)
12711{
12712 unformat_input_t *line_input = vam->input;
12713 vl_api_cop_interface_enable_disable_t *mp;
12714 f64 timeout;
12715 u32 sw_if_index = ~0;
12716 u8 enable_disable = 1;
12717
12718 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12719 {
12720 if (unformat (line_input, "disable"))
12721 enable_disable = 0;
12722 if (unformat (line_input, "enable"))
12723 enable_disable = 1;
12724 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12725 vam, &sw_if_index))
12726 ;
12727 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12728 ;
12729 else
12730 break;
12731 }
12732
12733 if (sw_if_index == ~0)
12734 {
12735 errmsg ("missing interface name or sw_if_index");
12736 return -99;
12737 }
12738
12739 /* Construct the API message */
12740 M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12741 mp->sw_if_index = ntohl (sw_if_index);
12742 mp->enable_disable = enable_disable;
12743
12744 /* send it... */
12745 S;
12746 /* Wait for the reply */
12747 W;
12748}
12749
12750static int
12751api_cop_whitelist_enable_disable (vat_main_t * vam)
12752{
12753 unformat_input_t *line_input = vam->input;
12754 vl_api_cop_whitelist_enable_disable_t *mp;
12755 f64 timeout;
12756 u32 sw_if_index = ~0;
12757 u8 ip4 = 0, ip6 = 0, default_cop = 0;
12758 u32 fib_id = 0;
12759
12760 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12761 {
12762 if (unformat (line_input, "ip4"))
12763 ip4 = 1;
12764 else if (unformat (line_input, "ip6"))
12765 ip6 = 1;
12766 else if (unformat (line_input, "default"))
12767 default_cop = 1;
12768 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12769 vam, &sw_if_index))
12770 ;
12771 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12772 ;
12773 else if (unformat (line_input, "fib-id %d", &fib_id))
12774 ;
12775 else
12776 break;
12777 }
12778
12779 if (sw_if_index == ~0)
12780 {
12781 errmsg ("missing interface name or sw_if_index");
12782 return -99;
12783 }
12784
12785 /* Construct the API message */
12786 M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12787 mp->sw_if_index = ntohl (sw_if_index);
12788 mp->fib_id = ntohl (fib_id);
12789 mp->ip4 = ip4;
12790 mp->ip6 = ip6;
12791 mp->default_cop = default_cop;
12792
12793 /* send it... */
12794 S;
12795 /* Wait for the reply */
12796 W;
12797}
12798
12799static int
12800api_get_node_graph (vat_main_t * vam)
12801{
12802 vl_api_get_node_graph_t *mp;
12803 f64 timeout;
12804
12805 M (GET_NODE_GRAPH, get_node_graph);
12806
12807 /* send it... */
12808 S;
12809 /* Wait for the reply */
12810 W;
12811}
12812
12813/* *INDENT-OFF* */
12814/** Used for parsing LISP eids */
12815typedef CLIB_PACKED(struct{
12816 u8 addr[16]; /**< eid address */
12817 u32 len; /**< prefix length if IP */
12818 u8 type; /**< type of eid */
12819}) lisp_eid_vat_t;
12820/* *INDENT-ON* */
12821
12822static uword
12823unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12824{
12825 lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12826
12827 memset (a, 0, sizeof (a[0]));
12828
12829 if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12830 {
12831 a->type = 0; /* ipv4 type */
12832 }
12833 else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12834 {
12835 a->type = 1; /* ipv6 type */
12836 }
12837 else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12838 {
12839 a->type = 2; /* mac type */
12840 }
12841 else
12842 {
12843 return 0;
12844 }
12845
12846 if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12847 {
12848 return 0;
12849 }
12850
12851 return 1;
12852}
12853
12854static int
12855lisp_eid_size_vat (u8 type)
12856{
12857 switch (type)
12858 {
12859 case 0:
12860 return 4;
12861 case 1:
12862 return 16;
12863 case 2:
12864 return 6;
12865 }
12866 return 0;
12867}
12868
12869static void
12870lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12871{
12872 clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12873}
12874
12875/* *INDENT-OFF* */
12876/** Used for transferring locators via VPP API */
12877typedef CLIB_PACKED(struct
12878{
12879 u32 sw_if_index; /**< locator sw_if_index */
12880 u8 priority; /**< locator priority */
12881 u8 weight; /**< locator weight */
12882}) ls_locator_t;
12883/* *INDENT-ON* */
12884
12885static int
12886api_lisp_add_del_locator_set (vat_main_t * vam)
12887{
12888 unformat_input_t *input = vam->input;
12889 vl_api_lisp_add_del_locator_set_t *mp;
12890 f64 timeout = ~0;
12891 u8 is_add = 1;
12892 u8 *locator_set_name = NULL;
12893 u8 locator_set_name_set = 0;
12894 ls_locator_t locator, *locators = 0;
12895 u32 sw_if_index, priority, weight;
12896 u32 data_len = 0;
12897
12898 /* Parse args required to build the message */
12899 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12900 {
12901 if (unformat (input, "del"))
12902 {
12903 is_add = 0;
12904 }
12905 else if (unformat (input, "locator-set %s", &locator_set_name))
12906 {
12907 locator_set_name_set = 1;
12908 }
12909 else if (unformat (input, "sw_if_index %u p %u w %u",
12910 &sw_if_index, &priority, &weight))
12911 {
12912 locator.sw_if_index = htonl (sw_if_index);
12913 locator.priority = priority;
12914 locator.weight = weight;
12915 vec_add1 (locators, locator);
12916 }
12917 else
12918 if (unformat
12919 (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
12920 &sw_if_index, &priority, &weight))
12921 {
12922 locator.sw_if_index = htonl (sw_if_index);
12923 locator.priority = priority;
12924 locator.weight = weight;
12925 vec_add1 (locators, locator);
12926 }
12927 else
12928 break;
12929 }
12930
12931 if (locator_set_name_set == 0)
12932 {
12933 errmsg ("missing locator-set name");
12934 vec_free (locators);
12935 return -99;
12936 }
12937
12938 if (vec_len (locator_set_name) > 64)
12939 {
12940 errmsg ("locator-set name too long");
12941 vec_free (locator_set_name);
12942 vec_free (locators);
12943 return -99;
12944 }
12945 vec_add1 (locator_set_name, 0);
12946
12947 data_len = sizeof (ls_locator_t) * vec_len (locators);
12948
12949 /* Construct the API message */
12950 M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12951
12952 mp->is_add = is_add;
12953 clib_memcpy (mp->locator_set_name, locator_set_name,
12954 vec_len (locator_set_name));
12955 vec_free (locator_set_name);
12956
12957 mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12958 if (locators)
12959 clib_memcpy (mp->locators, locators, data_len);
12960 vec_free (locators);
12961
12962 /* send it... */
12963 S;
12964
12965 /* Wait for a reply... */
12966 W;
12967
12968 /* NOTREACHED */
12969 return 0;
12970}
12971
12972static int
12973api_lisp_add_del_locator (vat_main_t * vam)
12974{
12975 unformat_input_t *input = vam->input;
12976 vl_api_lisp_add_del_locator_t *mp;
12977 f64 timeout = ~0;
12978 u32 tmp_if_index = ~0;
12979 u32 sw_if_index = ~0;
12980 u8 sw_if_index_set = 0;
12981 u8 sw_if_index_if_name_set = 0;
12982 u32 priority = ~0;
12983 u8 priority_set = 0;
12984 u32 weight = ~0;
12985 u8 weight_set = 0;
12986 u8 is_add = 1;
12987 u8 *locator_set_name = NULL;
12988 u8 locator_set_name_set = 0;
12989
12990 /* Parse args required to build the message */
12991 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12992 {
12993 if (unformat (input, "del"))
12994 {
12995 is_add = 0;
12996 }
12997 else if (unformat (input, "locator-set %s", &locator_set_name))
12998 {
12999 locator_set_name_set = 1;
13000 }
13001 else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13002 &tmp_if_index))
13003 {
13004 sw_if_index_if_name_set = 1;
13005 sw_if_index = tmp_if_index;
13006 }
13007 else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13008 {
13009 sw_if_index_set = 1;
13010 sw_if_index = tmp_if_index;
13011 }
13012 else if (unformat (input, "p %d", &priority))
13013 {
13014 priority_set = 1;
13015 }
13016 else if (unformat (input, "w %d", &weight))
13017 {
13018 weight_set = 1;
13019 }
13020 else
13021 break;
13022 }
13023
13024 if (locator_set_name_set == 0)
13025 {
13026 errmsg ("missing locator-set name");
13027 return -99;
13028 }
13029
13030 if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13031 {
13032 errmsg ("missing sw_if_index");
13033 vec_free (locator_set_name);
13034 return -99;
13035 }
13036
13037 if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13038 {
13039 errmsg ("cannot use both params interface name and sw_if_index");
13040 vec_free (locator_set_name);
13041 return -99;
13042 }
13043
13044 if (priority_set == 0)
13045 {
13046 errmsg ("missing locator-set priority");
13047 vec_free (locator_set_name);
13048 return -99;
13049 }
13050
13051 if (weight_set == 0)
13052 {
13053 errmsg ("missing locator-set weight");
13054 vec_free (locator_set_name);
13055 return -99;
13056 }
13057
13058 if (vec_len (locator_set_name) > 64)
13059 {
13060 errmsg ("locator-set name too long");
13061 vec_free (locator_set_name);
13062 return -99;
13063 }
13064 vec_add1 (locator_set_name, 0);
13065
13066 /* Construct the API message */
13067 M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
13068
13069 mp->is_add = is_add;
13070 mp->sw_if_index = ntohl (sw_if_index);
13071 mp->priority = priority;
13072 mp->weight = weight;
13073 clib_memcpy (mp->locator_set_name, locator_set_name,
13074 vec_len (locator_set_name));
13075 vec_free (locator_set_name);
13076
13077 /* send it... */
13078 S;
13079
13080 /* Wait for a reply... */
13081 W;
13082
13083 /* NOTREACHED */
13084 return 0;
13085}
13086
13087uword
13088unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13089{
13090 u32 *key_id = va_arg (*args, u32 *);
13091 u8 *s = 0;
13092
13093 if (unformat (input, "%s", &s))
13094 {
13095 if (!strcmp ((char *) s, "sha1"))
13096 key_id[0] = HMAC_SHA_1_96;
13097 else if (!strcmp ((char *) s, "sha256"))
13098 key_id[0] = HMAC_SHA_256_128;
13099 else
13100 {
13101 clib_warning ("invalid key_id: '%s'", s);
13102 key_id[0] = HMAC_NO_KEY;
13103 }
13104 }
13105 else
13106 return 0;
13107
13108 vec_free (s);
13109 return 1;
13110}
13111
13112static int
13113api_lisp_add_del_local_eid (vat_main_t * vam)
13114{
13115 unformat_input_t *input = vam->input;
13116 vl_api_lisp_add_del_local_eid_t *mp;
13117 f64 timeout = ~0;
13118 u8 is_add = 1;
13119 u8 eid_set = 0;
13120 lisp_eid_vat_t _eid, *eid = &_eid;
13121 u8 *locator_set_name = 0;
13122 u8 locator_set_name_set = 0;
13123 u32 vni = 0;
13124 u16 key_id = 0;
13125 u8 *key = 0;
13126
13127 /* Parse args required to build the message */
13128 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13129 {
13130 if (unformat (input, "del"))
13131 {
13132 is_add = 0;
13133 }
13134 else if (unformat (input, "vni %d", &vni))
13135 {
13136 ;
13137 }
13138 else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13139 {
13140 eid_set = 1;
13141 }
13142 else if (unformat (input, "locator-set %s", &locator_set_name))
13143 {
13144 locator_set_name_set = 1;
13145 }
13146 else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13147 ;
13148 else if (unformat (input, "secret-key %_%v%_", &key))
13149 ;
13150 else
13151 break;
13152 }
13153
13154 if (locator_set_name_set == 0)
13155 {
13156 errmsg ("missing locator-set name");
13157 return -99;
13158 }
13159
13160 if (0 == eid_set)
13161 {
13162 errmsg ("EID address not set!");
13163 vec_free (locator_set_name);
13164 return -99;
13165 }
13166
13167 if (key && (0 == key_id))
13168 {
13169 errmsg ("invalid key_id!");
13170 return -99;
13171 }
13172
13173 if (vec_len (key) > 64)
13174 {
13175 errmsg ("key too long");
13176 vec_free (key);
13177 return -99;
13178 }
13179
13180 if (vec_len (locator_set_name) > 64)
13181 {
13182 errmsg ("locator-set name too long");
13183 vec_free (locator_set_name);
13184 return -99;
13185 }
13186 vec_add1 (locator_set_name, 0);
13187
13188 /* Construct the API message */
13189 M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
13190
13191 mp->is_add = is_add;
13192 lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13193 mp->eid_type = eid->type;
13194 mp->prefix_len = eid->len;
13195 mp->vni = clib_host_to_net_u32 (vni);
13196 mp->key_id = clib_host_to_net_u16 (key_id);
13197 clib_memcpy (mp->locator_set_name, locator_set_name,
13198 vec_len (locator_set_name));
13199 clib_memcpy (mp->key, key, vec_len (key));
13200
13201 vec_free (locator_set_name);
13202 vec_free (key);
13203
13204 /* send it... */
13205 S;
13206
13207 /* Wait for a reply... */
13208 W;
13209
13210 /* NOTREACHED */
13211 return 0;
13212}
13213
13214/* *INDENT-OFF* */
13215/** Used for transferring locators via VPP API */
13216typedef CLIB_PACKED(struct
13217{
13218 u8 is_ip4; /**< is locator an IPv4 address? */
13219 u8 priority; /**< locator priority */
13220 u8 weight; /**< locator weight */
13221 u8 addr[16]; /**< IPv4/IPv6 address */
13222}) rloc_t;
13223/* *INDENT-ON* */
13224
13225static int
13226api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13227{
13228 unformat_input_t *input = vam->input;
13229 vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13230 f64 timeout = ~0;
13231 u8 is_add = 1;
13232 lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13233 lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13234 u8 rmt_eid_set = 0, lcl_eid_set = 0;
13235 u32 action = ~0, p, w;
13236 ip4_address_t rmt_rloc4, lcl_rloc4;
13237 ip6_address_t rmt_rloc6, lcl_rloc6;
13238 rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13239
13240 memset (&rloc, 0, sizeof (rloc));
13241
13242 /* Parse args required to build the message */
13243 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13244 {
13245 if (unformat (input, "del"))
13246 {
13247 is_add = 0;
13248 }
13249 else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
13250 {
13251 rmt_eid_set = 1;
13252 }
13253 else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
13254 {
13255 lcl_eid_set = 1;
13256 }
13257 else if (unformat (input, "p %d w %d", &p, &w))
13258 {
13259 if (!curr_rloc)
13260 {
13261 errmsg ("No RLOC configured for setting priority/weight!");
13262 return -99;
13263 }
13264 curr_rloc->priority = p;
13265 curr_rloc->weight = w;
13266 }
13267 else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13268 &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13269 {
13270 rloc.is_ip4 = 1;
13271
13272 clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13273 rloc.priority = rloc.weight = 0;
13274 vec_add1 (lcl_locs, rloc);
13275
13276 clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13277 vec_add1 (rmt_locs, rloc);
13278 /* priority and weight saved in rmt loc */
13279 curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13280 }
13281 else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13282 &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13283 {
13284 rloc.is_ip4 = 0;
13285 clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13286 rloc.priority = rloc.weight = 0;
13287 vec_add1 (lcl_locs, rloc);
13288
13289 clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13290 vec_add1 (rmt_locs, rloc);
13291 /* priority and weight saved in rmt loc */
13292 curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13293 }
13294 else if (unformat (input, "action %d", &action))
13295 {
13296 ;
13297 }
13298 else
13299 {
13300 clib_warning ("parse error '%U'", format_unformat_error, input);
13301 return -99;
13302 }
13303 }
13304
13305 if (!rmt_eid_set)
13306 {
13307 errmsg ("remote eid addresses not set");
13308 return -99;
13309 }
13310
13311 if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13312 {
13313 errmsg ("eid types don't match");
13314 return -99;
13315 }
13316
13317 if (0 == rmt_locs && (u32) ~ 0 == action)
13318 {
13319 errmsg ("action not set for negative mapping");
13320 return -99;
13321 }
13322
13323 /* Construct the API message */
13324 M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13325
13326 mp->is_add = is_add;
13327 lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13328 lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13329 mp->eid_type = rmt_eid->type;
13330 mp->rmt_len = rmt_eid->len;
13331 mp->lcl_len = lcl_eid->len;
13332 mp->action = action;
13333
13334 if (0 != rmt_locs && 0 != lcl_locs)
13335 {
13336 mp->loc_num = vec_len (rmt_locs);
13337 clib_memcpy (mp->lcl_locs, lcl_locs,
13338 (sizeof (rloc_t) * vec_len (lcl_locs)));
13339 clib_memcpy (mp->rmt_locs, rmt_locs,
13340 (sizeof (rloc_t) * vec_len (rmt_locs)));
13341 }
13342 vec_free (lcl_locs);
13343 vec_free (rmt_locs);
13344
13345 /* send it... */
13346 S;
13347
13348 /* Wait for a reply... */
13349 W;
13350
13351 /* NOTREACHED */
13352 return 0;
13353}
13354
13355static int
13356api_lisp_add_del_map_server (vat_main_t * vam)
13357{
13358 unformat_input_t *input = vam->input;
13359 vl_api_lisp_add_del_map_server_t *mp;
13360 f64 timeout = ~0;
13361 u8 is_add = 1;
13362 u8 ipv4_set = 0;
13363 u8 ipv6_set = 0;
13364 ip4_address_t ipv4;
13365 ip6_address_t ipv6;
13366
13367 /* Parse args required to build the message */
13368 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13369 {
13370 if (unformat (input, "del"))
13371 {
13372 is_add = 0;
13373 }
13374 else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13375 {
13376 ipv4_set = 1;
13377 }
13378 else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13379 {
13380 ipv6_set = 1;
13381 }
13382 else
13383 break;
13384 }
13385
13386 if (ipv4_set && ipv6_set)
13387 {
13388 errmsg ("both eid v4 and v6 addresses set");
13389 return -99;
13390 }
13391
13392 if (!ipv4_set && !ipv6_set)
13393 {
13394 errmsg ("eid addresses not set");
13395 return -99;
13396 }
13397
13398 /* Construct the API message */
13399 M (LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server);
13400
13401 mp->is_add = is_add;
13402 if (ipv6_set)
13403 {
13404 mp->is_ipv6 = 1;
13405 clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13406 }
13407 else
13408 {
13409 mp->is_ipv6 = 0;
13410 clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13411 }
13412
13413 /* send it... */
13414 S;
13415
13416 /* Wait for a reply... */
13417 W;
13418
13419 /* NOTREACHED */
13420 return 0;
13421}
13422
13423static int
13424api_lisp_add_del_map_resolver (vat_main_t * vam)
13425{
13426 unformat_input_t *input = vam->input;
13427 vl_api_lisp_add_del_map_resolver_t *mp;
13428 f64 timeout = ~0;
13429 u8 is_add = 1;
13430 u8 ipv4_set = 0;
13431 u8 ipv6_set = 0;
13432 ip4_address_t ipv4;
13433 ip6_address_t ipv6;
13434
13435 /* Parse args required to build the message */
13436 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13437 {
13438 if (unformat (input, "del"))
13439 {
13440 is_add = 0;
13441 }
13442 else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13443 {
13444 ipv4_set = 1;
13445 }
13446 else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13447 {
13448 ipv6_set = 1;
13449 }
13450 else
13451 break;
13452 }
13453
13454 if (ipv4_set && ipv6_set)
13455 {
13456 errmsg ("both eid v4 and v6 addresses set");
13457 return -99;
13458 }
13459
13460 if (!ipv4_set && !ipv6_set)
13461 {
13462 errmsg ("eid addresses not set");
13463 return -99;
13464 }
13465
13466 /* Construct the API message */
13467 M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13468
13469 mp->is_add = is_add;
13470 if (ipv6_set)
13471 {
13472 mp->is_ipv6 = 1;
13473 clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13474 }
13475 else
13476 {
13477 mp->is_ipv6 = 0;
13478 clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13479 }
13480
13481 /* send it... */
13482 S;
13483
13484 /* Wait for a reply... */
13485 W;
13486
13487 /* NOTREACHED */
13488 return 0;
13489}
13490
13491static int
13492api_lisp_gpe_enable_disable (vat_main_t * vam)
13493{
13494 unformat_input_t *input = vam->input;
13495 vl_api_lisp_gpe_enable_disable_t *mp;
13496 f64 timeout = ~0;
13497 u8 is_set = 0;
13498 u8 is_en = 1;
13499
13500 /* Parse args required to build the message */
13501 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13502 {
13503 if (unformat (input, "enable"))
13504 {
13505 is_set = 1;
13506 is_en = 1;
13507 }
13508 else if (unformat (input, "disable"))
13509 {
13510 is_set = 1;
13511 is_en = 0;
13512 }
13513 else
13514 break;
13515 }
13516
13517 if (is_set == 0)
13518 {
13519 errmsg ("Value not set");
13520 return -99;
13521 }
13522
13523 /* Construct the API message */
13524 M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13525
13526 mp->is_en = is_en;
13527
13528 /* send it... */
13529 S;
13530
13531 /* Wait for a reply... */
13532 W;
13533
13534 /* NOTREACHED */
13535 return 0;
13536}
13537
13538static int
13539api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
13540{
13541 unformat_input_t *input = vam->input;
13542 vl_api_lisp_rloc_probe_enable_disable_t *mp;
13543 f64 timeout = ~0;
13544 u8 is_set = 0;
13545 u8 is_en = 0;
13546
13547 /* Parse args required to build the message */
13548 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13549 {
13550 if (unformat (input, "enable"))
13551 {
13552 is_set = 1;
13553 is_en = 1;
13554 }
13555 else if (unformat (input, "disable"))
13556 is_set = 1;
13557 else
13558 break;
13559 }
13560
13561 if (!is_set)
13562 {
13563 errmsg ("Value not set");
13564 return -99;
13565 }
13566
13567 /* Construct the API message */
13568 M (LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable);
13569
13570 mp->is_enabled = is_en;
13571
13572 /* send it... */
13573 S;
13574
13575 /* Wait for a reply... */
13576 W;
13577
13578 /* NOTREACHED */
13579 return 0;
13580}
13581
13582static int
13583api_lisp_map_register_enable_disable (vat_main_t * vam)
13584{
13585 unformat_input_t *input = vam->input;
13586 vl_api_lisp_map_register_enable_disable_t *mp;
13587 f64 timeout = ~0;
13588 u8 is_set = 0;
13589 u8 is_en = 0;
13590
13591 /* Parse args required to build the message */
13592 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13593 {
13594 if (unformat (input, "enable"))
13595 {
13596 is_set = 1;
13597 is_en = 1;
13598 }
13599 else if (unformat (input, "disable"))
13600 is_set = 1;
13601 else
13602 break;
13603 }
13604
13605 if (!is_set)
13606 {
13607 errmsg ("Value not set");
13608 return -99;
13609 }
13610
13611 /* Construct the API message */
13612 M (LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable);
13613
13614 mp->is_enabled = is_en;
13615
13616 /* send it... */
13617 S;
13618
13619 /* Wait for a reply... */
13620 W;
13621
13622 /* NOTREACHED */
13623 return 0;
13624}
13625
13626static int
13627api_lisp_enable_disable (vat_main_t * vam)
13628{
13629 unformat_input_t *input = vam->input;
13630 vl_api_lisp_enable_disable_t *mp;
13631 f64 timeout = ~0;
13632 u8 is_set = 0;
13633 u8 is_en = 0;
13634
13635 /* Parse args required to build the message */
13636 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13637 {
13638 if (unformat (input, "enable"))
13639 {
13640 is_set = 1;
13641 is_en = 1;
13642 }
13643 else if (unformat (input, "disable"))
13644 {
13645 is_set = 1;
13646 }
13647 else
13648 break;
13649 }
13650
13651 if (!is_set)
13652 {
13653 errmsg ("Value not set");
13654 return -99;
13655 }
13656
13657 /* Construct the API message */
13658 M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13659
13660 mp->is_en = is_en;
13661
13662 /* send it... */
13663 S;
13664
13665 /* Wait for a reply... */
13666 W;
13667
13668 /* NOTREACHED */
13669 return 0;
13670}
13671
13672static int
13673api_show_lisp_map_register_state (vat_main_t * vam)
13674{
13675 f64 timeout = ~0;
13676 vl_api_show_lisp_map_register_state_t *mp;
13677
13678 M (SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state);
13679
13680 /* send */
13681 S;
13682
13683 /* wait for reply */
13684 W;
13685
13686 return 0;
13687}
13688
13689static int
13690api_show_lisp_rloc_probe_state (vat_main_t * vam)
13691{
13692 f64 timeout = ~0;
13693 vl_api_show_lisp_rloc_probe_state_t *mp;
13694
13695 M (SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state);
13696
13697 /* send */
13698 S;
13699
13700 /* wait for reply */
13701 W;
13702
13703 return 0;
13704}
13705
13706static int
13707api_show_lisp_map_request_mode (vat_main_t * vam)
13708{
13709 f64 timeout = ~0;
13710 vl_api_show_lisp_map_request_mode_t *mp;
13711
13712 M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13713
13714 /* send */
13715 S;
13716
13717 /* wait for reply */
13718 W;
13719
13720 return 0;
13721}
13722
13723static int
13724api_lisp_map_request_mode (vat_main_t * vam)
13725{
13726 f64 timeout = ~0;
13727 unformat_input_t *input = vam->input;
13728 vl_api_lisp_map_request_mode_t *mp;
13729 u8 mode = 0;
13730
13731 /* Parse args required to build the message */
13732 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13733 {
13734 if (unformat (input, "dst-only"))
13735 mode = 0;
13736 else if (unformat (input, "src-dst"))
13737 mode = 1;
13738 else
13739 {
13740 errmsg ("parse error '%U'", format_unformat_error, input);
13741 return -99;
13742 }
13743 }
13744
13745 M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13746
13747 mp->mode = mode;
13748
13749 /* send */
13750 S;
13751
13752 /* wait for reply */
13753 W;
13754
13755 /* notreached */
13756 return 0;
13757}
13758
13759/**
13760 * Enable/disable LISP proxy ITR.
13761 *
13762 * @param vam vpp API test context
13763 * @return return code
13764 */
13765static int
13766api_lisp_pitr_set_locator_set (vat_main_t * vam)
13767{
13768 f64 timeout = ~0;
13769 u8 ls_name_set = 0;
13770 unformat_input_t *input = vam->input;
13771 vl_api_lisp_pitr_set_locator_set_t *mp;
13772 u8 is_add = 1;
13773 u8 *ls_name = 0;
13774
13775 /* Parse args required to build the message */
13776 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13777 {
13778 if (unformat (input, "del"))
13779 is_add = 0;
13780 else if (unformat (input, "locator-set %s", &ls_name))
13781 ls_name_set = 1;
13782 else
13783 {
13784 errmsg ("parse error '%U'", format_unformat_error, input);
13785 return -99;
13786 }
13787 }
13788
13789 if (!ls_name_set)
13790 {
13791 errmsg ("locator-set name not set!");
13792 return -99;
13793 }
13794
13795 M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13796
13797 mp->is_add = is_add;
13798 clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13799 vec_free (ls_name);
13800
13801 /* send */
13802 S;
13803
13804 /* wait for reply */
13805 W;
13806
13807 /* notreached */
13808 return 0;
13809}
13810
13811static int
13812api_show_lisp_pitr (vat_main_t * vam)
13813{
13814 vl_api_show_lisp_pitr_t *mp;
13815 f64 timeout = ~0;
13816
13817 if (!vam->json_output)
13818 {
13819 print (vam->ofp, "%=20s", "lisp status:");
13820 }
13821
13822 M (SHOW_LISP_PITR, show_lisp_pitr);
13823 /* send it... */
13824 S;
13825
13826 /* Wait for a reply... */
13827 W;
13828
13829 /* NOTREACHED */
13830 return 0;
13831}
13832
13833/**
13834 * Add/delete mapping between vni and vrf
13835 */
13836static int
13837api_lisp_eid_table_add_del_map (vat_main_t * vam)
13838{
13839 f64 timeout = ~0;
13840 unformat_input_t *input = vam->input;
13841 vl_api_lisp_eid_table_add_del_map_t *mp;
13842 u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13843 u32 vni, vrf, bd_index;
13844
13845 /* Parse args required to build the message */
13846 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13847 {
13848 if (unformat (input, "del"))
13849 is_add = 0;
13850 else if (unformat (input, "vrf %d", &vrf))
13851 vrf_set = 1;
13852 else if (unformat (input, "bd_index %d", &bd_index))
13853 bd_index_set = 1;
13854 else if (unformat (input, "vni %d", &vni))
13855 vni_set = 1;
13856 else
13857 break;
13858 }
13859
13860 if (!vni_set || (!vrf_set && !bd_index_set))
13861 {
13862 errmsg ("missing arguments!");
13863 return -99;
13864 }
13865
13866 if (vrf_set && bd_index_set)
13867 {
13868 errmsg ("error: both vrf and bd entered!");
13869 return -99;
13870 }
13871
13872 M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13873
13874 mp->is_add = is_add;
13875 mp->vni = htonl (vni);
13876 mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13877 mp->is_l2 = bd_index_set;
13878
13879 /* send */
13880 S;
13881
13882 /* wait for reply */
13883 W;
13884
13885 /* notreached */
13886 return 0;
13887}
13888
13889uword
13890unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13891{
13892 u32 *action = va_arg (*args, u32 *);
13893 u8 *s = 0;
13894
13895 if (unformat (input, "%s", &s))
13896 {
13897 if (!strcmp ((char *) s, "no-action"))
13898 action[0] = 0;
13899 else if (!strcmp ((char *) s, "natively-forward"))
13900 action[0] = 1;
13901 else if (!strcmp ((char *) s, "send-map-request"))
13902 action[0] = 2;
13903 else if (!strcmp ((char *) s, "drop"))
13904 action[0] = 3;
13905 else
13906 {
13907 clib_warning ("invalid action: '%s'", s);
13908 action[0] = 3;
13909 }
13910 }
13911 else
13912 return 0;
13913
13914 vec_free (s);
13915 return 1;
13916}
13917
13918/**
13919 * Add/del remote mapping to/from LISP control plane
13920 *
13921 * @param vam vpp API test context
13922 * @return return code
13923 */
13924static int
13925api_lisp_add_del_remote_mapping (vat_main_t * vam)
13926{
13927 unformat_input_t *input = vam->input;
13928 vl_api_lisp_add_del_remote_mapping_t *mp;
13929 f64 timeout = ~0;
13930 u32 vni = 0;
13931 lisp_eid_vat_t _eid, *eid = &_eid;
13932 lisp_eid_vat_t _seid, *seid = &_seid;
13933 u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13934 u32 action = ~0, p, w, data_len;
13935 ip4_address_t rloc4;
13936 ip6_address_t rloc6;
13937 rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13938
13939 memset (&rloc, 0, sizeof (rloc));
13940
13941 /* Parse args required to build the message */
13942 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13943 {
13944 if (unformat (input, "del-all"))
13945 {
13946 del_all = 1;
13947 }
13948 else if (unformat (input, "del"))
13949 {
13950 is_add = 0;
13951 }
13952 else if (unformat (input, "add"))
13953 {
13954 is_add = 1;
13955 }
13956 else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13957 {
13958 eid_set = 1;
13959 }
13960 else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13961 {
13962 seid_set = 1;
13963 }
13964 else if (unformat (input, "vni %d", &vni))
13965 {
13966 ;
13967 }
13968 else if (unformat (input, "p %d w %d", &p, &w))
13969 {
13970 if (!curr_rloc)
13971 {
13972 errmsg ("No RLOC configured for setting priority/weight!");
13973 return -99;
13974 }
13975 curr_rloc->priority = p;
13976 curr_rloc->weight = w;
13977 }
13978 else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13979 {
13980 rloc.is_ip4 = 1;
13981 clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13982 vec_add1 (rlocs, rloc);
13983 curr_rloc = &rlocs[vec_len (rlocs) - 1];
13984 }
13985 else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13986 {
13987 rloc.is_ip4 = 0;
13988 clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13989 vec_add1 (rlocs, rloc);
13990 curr_rloc = &rlocs[vec_len (rlocs) - 1];
13991 }
13992 else if (unformat (input, "action %U",
13993 unformat_negative_mapping_action, &action))
13994 {
13995 ;
13996 }
13997 else
13998 {
13999 clib_warning ("parse error '%U'", format_unformat_error, input);
14000 return -99;
14001 }
14002 }
14003
14004 if (0 == eid_set)
14005 {
14006 errmsg ("missing params!");
14007 return -99;
14008 }
14009
14010 if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14011 {
14012 errmsg ("no action set for negative map-reply!");
14013 return -99;
14014 }
14015
14016 data_len = vec_len (rlocs) * sizeof (rloc_t);
14017
14018 M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
14019 mp->is_add = is_add;
14020 mp->vni = htonl (vni);
14021 mp->action = (u8) action;
14022 mp->is_src_dst = seid_set;
14023 mp->eid_len = eid->len;
14024 mp->seid_len = seid->len;
14025 mp->del_all = del_all;
14026 mp->eid_type = eid->type;
14027 lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14028 lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14029
14030 mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14031 clib_memcpy (mp->rlocs, rlocs, data_len);
14032 vec_free (rlocs);
14033
14034 /* send it... */
14035 S;
14036
14037 /* Wait for a reply... */
14038 W;
14039
14040 /* NOTREACHED */
14041 return 0;
14042}
14043
14044/**
14045 * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14046 * forwarding entries in data-plane accordingly.
14047 *
14048 * @param vam vpp API test context
14049 * @return return code
14050 */
14051static int
14052api_lisp_add_del_adjacency (vat_main_t * vam)
14053{
14054 unformat_input_t *input = vam->input;
14055 vl_api_lisp_add_del_adjacency_t *mp;
14056 f64 timeout = ~0;
14057 u32 vni = 0;
14058 ip4_address_t leid4, reid4;
14059 ip6_address_t leid6, reid6;
14060 u8 reid_mac[6] = { 0 };
14061 u8 leid_mac[6] = { 0 };
14062 u8 reid_type, leid_type;
14063 u32 leid_len = 0, reid_len = 0, len;
14064 u8 is_add = 1;
14065
14066 leid_type = reid_type = (u8) ~ 0;
14067
14068 /* Parse args required to build the message */
14069 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14070 {
14071 if (unformat (input, "del"))
14072 {
14073 is_add = 0;
14074 }
14075 else if (unformat (input, "add"))
14076 {
14077 is_add = 1;
14078 }
14079 else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14080 &reid4, &len))
14081 {
14082 reid_type = 0; /* ipv4 */
14083 reid_len = len;
14084 }
14085 else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14086 &reid6, &len))
14087 {
14088 reid_type = 1; /* ipv6 */
14089 reid_len = len;
14090 }
14091 else if (unformat (input, "reid %U", unformat_ethernet_address,
14092 reid_mac))
14093 {
14094 reid_type = 2; /* mac */
14095 }
14096 else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14097 &leid4, &len))
14098 {
14099 leid_type = 0; /* ipv4 */
14100 leid_len = len;
14101 }
14102 else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14103 &leid6, &len))
14104 {
14105 leid_type = 1; /* ipv6 */
14106 leid_len = len;
14107 }
14108 else if (unformat (input, "leid %U", unformat_ethernet_address,
14109 leid_mac))
14110 {
14111 leid_type = 2; /* mac */
14112 }
14113 else if (unformat (input, "vni %d", &vni))
14114 {
14115 ;
14116 }
14117 else
14118 {
14119 errmsg ("parse error '%U'", format_unformat_error, input);
14120 return -99;
14121 }
14122 }
14123
14124 if ((u8) ~ 0 == reid_type)
14125 {
14126 errmsg ("missing params!");
14127 return -99;
14128 }
14129
14130 if (leid_type != reid_type)
14131 {
14132 errmsg ("remote and local EIDs are of different types!");
14133 return -99;
14134 }
14135
14136 M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
14137 mp->is_add = is_add;
14138 mp->vni = htonl (vni);
14139 mp->leid_len = leid_len;
14140 mp->reid_len = reid_len;
14141 mp->eid_type = reid_type;
14142
14143 switch (mp->eid_type)
14144 {
14145 case 0:
14146 clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14147 clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14148 break;
14149 case 1:
14150 clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14151 clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14152 break;
14153 case 2:
14154 clib_memcpy (mp->leid, leid_mac, 6);
14155 clib_memcpy (mp->reid, reid_mac, 6);
14156 break;
14157 default:
14158 errmsg ("unknown EID type %d!", mp->eid_type);
14159 return 0;
14160 }
14161
14162 /* send it... */
14163 S;
14164
14165 /* Wait for a reply... */
14166 W;
14167
14168 /* NOTREACHED */
14169 return 0;
14170}
14171
14172static int
14173api_lisp_gpe_add_del_iface (vat_main_t * vam)
14174{
14175 unformat_input_t *input = vam->input;
14176 vl_api_lisp_gpe_add_del_iface_t *mp;
14177 f64 timeout = ~0;
14178 u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14179 u32 dp_table = 0, vni = 0;
14180
14181 /* Parse args required to build the message */
14182 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14183 {
14184 if (unformat (input, "up"))
14185 {
14186 action_set = 1;
14187 is_add = 1;
14188 }
14189 else if (unformat (input, "down"))
14190 {
14191 action_set = 1;
14192 is_add = 0;
14193 }
14194 else if (unformat (input, "table_id %d", &dp_table))
14195 {
14196 dp_table_set = 1;
14197 }
14198 else if (unformat (input, "bd_id %d", &dp_table))
14199 {
14200 dp_table_set = 1;
14201 is_l2 = 1;
14202 }
14203 else if (unformat (input, "vni %d", &vni))
14204 {
14205 vni_set = 1;
14206 }
14207 else
14208 break;
14209 }
14210
14211 if (action_set == 0)
14212 {
14213 errmsg ("Action not set");
14214 return -99;
14215 }
14216 if (dp_table_set == 0 || vni_set == 0)
14217 {
14218 errmsg ("vni and dp_table must be set");
14219 return -99;
14220 }
14221
14222 /* Construct the API message */
14223 M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
14224
14225 mp->is_add = is_add;
14226 mp->dp_table = dp_table;
14227 mp->is_l2 = is_l2;
14228 mp->vni = vni;
14229
14230 /* send it... */
14231 S;
14232
14233 /* Wait for a reply... */
14234 W;
14235
14236 /* NOTREACHED */
14237 return 0;
14238}
14239
14240/**
14241 * Add/del map request itr rlocs from LISP control plane and updates
14242 *
14243 * @param vam vpp API test context
14244 * @return return code
14245 */
14246static int
14247api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14248{
14249 unformat_input_t *input = vam->input;
14250 vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14251 f64 timeout = ~0;
14252 u8 *locator_set_name = 0;
14253 u8 locator_set_name_set = 0;
14254 u8 is_add = 1;
14255
14256 /* Parse args required to build the message */
14257 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14258 {
14259 if (unformat (input, "del"))
14260 {
14261 is_add = 0;
14262 }
14263 else if (unformat (input, "%_%v%_", &locator_set_name))
14264 {
14265 locator_set_name_set = 1;
14266 }
14267 else
14268 {
14269 clib_warning ("parse error '%U'", format_unformat_error, input);
14270 return -99;
14271 }
14272 }
14273
14274 if (is_add && !locator_set_name_set)
14275 {
14276 errmsg ("itr-rloc is not set!");
14277 return -99;
14278 }
14279
14280 if (is_add && vec_len (locator_set_name) > 64)
14281 {
14282 errmsg ("itr-rloc locator-set name too long");
14283 vec_free (locator_set_name);
14284 return -99;
14285 }
14286
14287 M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
14288 mp->is_add = is_add;
14289 if (is_add)
14290 {
14291 clib_memcpy (mp->locator_set_name, locator_set_name,
14292 vec_len (locator_set_name));
14293 }
14294 else
14295 {
14296 memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14297 }
14298 vec_free (locator_set_name);
14299
14300 /* send it... */
14301 S;
14302
14303 /* Wait for a reply... */
14304 W;
14305
14306 /* NOTREACHED */
14307 return 0;
14308}
14309
14310static int
14311api_lisp_locator_dump (vat_main_t * vam)
14312{
14313 unformat_input_t *input = vam->input;
14314 vl_api_lisp_locator_dump_t *mp;
14315 f64 timeout = ~0;
14316 u8 is_index_set = 0, is_name_set = 0;
14317 u8 *ls_name = 0;
14318 u32 ls_index = ~0;
14319
14320 /* Parse args required to build the message */
14321 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14322 {
14323 if (unformat (input, "ls_name %_%v%_", &ls_name))
14324 {
14325 is_name_set = 1;
14326 }
14327 else if (unformat (input, "ls_index %d", &ls_index))
14328 {
14329 is_index_set = 1;
14330 }
14331 else
14332 {
14333 errmsg ("parse error '%U'", format_unformat_error, input);
14334 return -99;
14335 }
14336 }
14337
14338 if (!is_index_set && !is_name_set)
14339 {
14340 errmsg ("error: expected one of index or name!");
14341 return -99;
14342 }
14343
14344 if (is_index_set && is_name_set)
14345 {
14346 errmsg ("error: only one param expected!");
14347 return -99;
14348 }
14349
14350 if (vec_len (ls_name) > 62)
14351 {
14352 errmsg ("error: locator set name too long!");
14353 return -99;
14354 }
14355
14356 if (!vam->json_output)
14357 {
14358 print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14359 }
14360
14361 M (LISP_LOCATOR_DUMP, lisp_locator_dump);
14362 mp->is_index_set = is_index_set;
14363
14364 if (is_index_set)
14365 mp->ls_index = clib_host_to_net_u32 (ls_index);
14366 else
14367 {
14368 vec_add1 (ls_name, 0);
14369 strncpy ((char *) mp->ls_name, (char *) ls_name,
14370 sizeof (mp->ls_name) - 1);
14371 }
14372
14373 /* send it... */
14374 S;
14375
14376 /* Use a control ping for synchronization */
14377 {
14378 vl_api_control_ping_t *mp;
14379 M (CONTROL_PING, control_ping);
14380 S;
14381 }
14382 /* Wait for a reply... */
14383 W;
14384
14385 /* NOTREACHED */
14386 return 0;
14387}
14388
14389static int
14390api_lisp_locator_set_dump (vat_main_t * vam)
14391{
14392 vl_api_lisp_locator_set_dump_t *mp;
14393 unformat_input_t *input = vam->input;
14394 f64 timeout = ~0;
14395 u8 filter = 0;
14396
14397 /* Parse args required to build the message */
14398 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14399 {
14400 if (unformat (input, "local"))
14401 {
14402 filter = 1;
14403 }
14404 else if (unformat (input, "remote"))
14405 {
14406 filter = 2;
14407 }
14408 else
14409 {
14410 errmsg ("parse error '%U'", format_unformat_error, input);
14411 return -99;
14412 }
14413 }
14414
14415 if (!vam->json_output)
14416 {
14417 print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14418 }
14419
14420 M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14421
14422 mp->filter = filter;
14423
14424 /* send it... */
14425 S;
14426
14427 /* Use a control ping for synchronization */
14428 {
14429 vl_api_control_ping_t *mp;
14430 M (CONTROL_PING, control_ping);
14431 S;
14432 }
14433 /* Wait for a reply... */
14434 W;
14435
14436 /* NOTREACHED */
14437 return 0;
14438}
14439
14440static int
14441api_lisp_eid_table_map_dump (vat_main_t * vam)
14442{
14443 u8 is_l2 = 0;
14444 u8 mode_set = 0;
14445 unformat_input_t *input = vam->input;
14446 vl_api_lisp_eid_table_map_dump_t *mp;
14447 f64 timeout = ~0;
14448
14449 /* Parse args required to build the message */
14450 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14451 {
14452 if (unformat (input, "l2"))
14453 {
14454 is_l2 = 1;
14455 mode_set = 1;
14456 }
14457 else if (unformat (input, "l3"))
14458 {
14459 is_l2 = 0;
14460 mode_set = 1;
14461 }
14462 else
14463 {
14464 errmsg ("parse error '%U'", format_unformat_error, input);
14465 return -99;
14466 }
14467 }
14468
14469 if (!mode_set)
14470 {
14471 errmsg ("expected one of 'l2' or 'l3' parameter!");
14472 return -99;
14473 }
14474
14475 if (!vam->json_output)
14476 {
14477 print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
14478 }
14479
14480 M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14481 mp->is_l2 = is_l2;
14482
14483 /* send it... */
14484 S;
14485
14486 /* Use a control ping for synchronization */
14487 {
14488 vl_api_control_ping_t *mp;
14489 M (CONTROL_PING, control_ping);
14490 S;
14491 }
14492 /* Wait for a reply... */
14493 W;
14494
14495 /* NOTREACHED */
14496 return 0;
14497}
14498
14499static int
14500api_lisp_eid_table_vni_dump (vat_main_t * vam)
14501{
14502 vl_api_lisp_eid_table_vni_dump_t *mp;
14503 f64 timeout = ~0;
14504
14505 if (!vam->json_output)
14506 {
14507 print (vam->ofp, "VNI");
14508 }
14509
14510 M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14511
14512 /* send it... */
14513 S;
14514
14515 /* Use a control ping for synchronization */
14516 {
14517 vl_api_control_ping_t *mp;
14518 M (CONTROL_PING, control_ping);
14519 S;
14520 }
14521 /* Wait for a reply... */
14522 W;
14523
14524 /* NOTREACHED */
14525 return 0;
14526}
14527
14528static int
14529api_lisp_eid_table_dump (vat_main_t * vam)
14530{
14531 unformat_input_t *i = vam->input;
14532 vl_api_lisp_eid_table_dump_t *mp;
14533 f64 timeout = ~0;
14534 struct in_addr ip4;
14535 struct in6_addr ip6;
14536 u8 mac[6];
14537 u8 eid_type = ~0, eid_set = 0;
14538 u32 prefix_length = ~0, t, vni = 0;
14539 u8 filter = 0;
14540
14541 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14542 {
14543 if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14544 {
14545 eid_set = 1;
14546 eid_type = 0;
14547 prefix_length = t;
14548 }
14549 else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14550 {
14551 eid_set = 1;
14552 eid_type = 1;
14553 prefix_length = t;
14554 }
14555 else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14556 {
14557 eid_set = 1;
14558 eid_type = 2;
14559 }
14560 else if (unformat (i, "vni %d", &t))
14561 {
14562 vni = t;
14563 }
14564 else if (unformat (i, "local"))
14565 {
14566 filter = 1;
14567 }
14568 else if (unformat (i, "remote"))
14569 {
14570 filter = 2;
14571 }
14572 else
14573 {
14574 errmsg ("parse error '%U'", format_unformat_error, i);
14575 return -99;
14576 }
14577 }
14578
14579 if (!vam->json_output)
14580 {
14581 print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
14582 "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14583 }
14584
14585 M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14586
14587 mp->filter = filter;
14588 if (eid_set)
14589 {
14590 mp->eid_set = 1;
14591 mp->vni = htonl (vni);
14592 mp->eid_type = eid_type;
14593 switch (eid_type)
14594 {
14595 case 0:
14596 mp->prefix_length = prefix_length;
14597 clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14598 break;
14599 case 1:
14600 mp->prefix_length = prefix_length;
14601 clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14602 break;
14603 case 2:
14604 clib_memcpy (mp->eid, mac, sizeof (mac));
14605 break;
14606 default:
14607 errmsg ("unknown EID type %d!", eid_type);
14608 return -99;
14609 }
14610 }
14611
14612 /* send it... */
14613 S;
14614
14615 /* Use a control ping for synchronization */
14616 {
14617 vl_api_control_ping_t *mp;
14618 M (CONTROL_PING, control_ping);
14619 S;
14620 }
14621
14622 /* Wait for a reply... */
14623 W;
14624
14625 /* NOTREACHED */
14626 return 0;
14627}
14628
14629static int
14630api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14631{
14632 vl_api_lisp_gpe_tunnel_dump_t *mp;
14633 f64 timeout = ~0;
14634
14635 if (!vam->json_output)
14636 {
14637 print (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14638 "%=16s%=16s%=16s%=16s%=16s",
14639 "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14640 "Decap next", "Lisp version", "Flags", "Next protocol",
14641 "ver_res", "res", "iid");
14642 }
14643
14644 M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14645 /* send it... */
14646 S;
14647
14648 /* Use a control ping for synchronization */
14649 {
14650 vl_api_control_ping_t *mp;
14651 M (CONTROL_PING, control_ping);
14652 S;
14653 }
14654 /* Wait for a reply... */
14655 W;
14656
14657 /* NOTREACHED */
14658 return 0;
14659}
14660
14661static int
14662api_lisp_adjacencies_get (vat_main_t * vam)
14663{
14664 unformat_input_t *i = vam->input;
14665 vl_api_lisp_adjacencies_get_t *mp;
14666 f64 timeout = ~0;
14667 u8 vni_set = 0;
14668 u32 vni = ~0;
14669
14670 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14671 {
14672 if (unformat (i, "vni %d", &vni))
14673 {
14674 vni_set = 1;
14675 }
14676 else
14677 {
14678 errmsg ("parse error '%U'", format_unformat_error, i);
14679 return -99;
14680 }
14681 }
14682
14683 if (!vni_set)
14684 {
14685 errmsg ("vni not set!");
14686 return -99;
14687 }
14688
14689 if (!vam->json_output)
14690 {
14691 print (vam->ofp, "%s %40s", "leid", "reid");
14692 }
14693
14694 M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14695 mp->vni = clib_host_to_net_u32 (vni);
14696
14697 /* send it... */
14698 S;
14699
14700 /* Wait for a reply... */
14701 W;
14702
14703 /* NOTREACHED */
14704 return 0;
14705}
14706
14707static int
14708api_lisp_map_server_dump (vat_main_t * vam)
14709{
14710 vl_api_lisp_map_server_dump_t *mp;
14711 f64 timeout = ~0;
14712
14713 if (!vam->json_output)
14714 {
14715 print (vam->ofp, "%=20s", "Map server");
14716 }
14717
14718 M (LISP_MAP_SERVER_DUMP, lisp_map_server_dump);
14719 /* send it... */
14720 S;
14721
14722 /* Use a control ping for synchronization */
14723 {
14724 vl_api_control_ping_t *mp;
14725 M (CONTROL_PING, control_ping);
14726 S;
14727 }
14728 /* Wait for a reply... */
14729 W;
14730
14731 /* NOTREACHED */
14732 return 0;
14733}
14734
14735static int
14736api_lisp_map_resolver_dump (vat_main_t * vam)
14737{
14738 vl_api_lisp_map_resolver_dump_t *mp;
14739 f64 timeout = ~0;
14740
14741 if (!vam->json_output)
14742 {
14743 print (vam->ofp, "%=20s", "Map resolver");
14744 }
14745
14746 M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14747 /* send it... */
14748 S;
14749
14750 /* Use a control ping for synchronization */
14751 {
14752 vl_api_control_ping_t *mp;
14753 M (CONTROL_PING, control_ping);
14754 S;
14755 }
14756 /* Wait for a reply... */
14757 W;
14758
14759 /* NOTREACHED */
14760 return 0;
14761}
14762
14763static int
14764api_show_lisp_status (vat_main_t * vam)
14765{
14766 vl_api_show_lisp_status_t *mp;
14767 f64 timeout = ~0;
14768
14769 if (!vam->json_output)
14770 {
14771 print (vam->ofp, "%-20s%-16s", "lisp status", "locator-set");
14772 }
14773
14774 M (SHOW_LISP_STATUS, show_lisp_status);
14775 /* send it... */
14776 S;
14777 /* Wait for a reply... */
14778 W;
14779
14780 /* NOTREACHED */
14781 return 0;
14782}
14783
14784static int
14785api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14786{
14787 vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14788 f64 timeout = ~0;
14789
14790 if (!vam->json_output)
14791 {
14792 print (vam->ofp, "%=20s", "itr-rlocs:");
14793 }
14794
14795 M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14796 /* send it... */
14797 S;
14798 /* Wait for a reply... */
14799 W;
14800
14801 /* NOTREACHED */
14802 return 0;
14803}
14804
14805static int
14806api_af_packet_create (vat_main_t * vam)
14807{
14808 unformat_input_t *i = vam->input;
14809 vl_api_af_packet_create_t *mp;
14810 f64 timeout;
14811 u8 *host_if_name = 0;
14812 u8 hw_addr[6];
14813 u8 random_hw_addr = 1;
14814
14815 memset (hw_addr, 0, sizeof (hw_addr));
14816
14817 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14818 {
14819 if (unformat (i, "name %s", &host_if_name))
14820 vec_add1 (host_if_name, 0);
14821 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14822 random_hw_addr = 0;
14823 else
14824 break;
14825 }
14826
14827 if (!vec_len (host_if_name))
14828 {
14829 errmsg ("host-interface name must be specified");
14830 return -99;
14831 }
14832
14833 if (vec_len (host_if_name) > 64)
14834 {
14835 errmsg ("host-interface name too long");
14836 return -99;
14837 }
14838
14839 M (AF_PACKET_CREATE, af_packet_create);
14840
14841 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14842 clib_memcpy (mp->hw_addr, hw_addr, 6);
14843 mp->use_random_hw_addr = random_hw_addr;
14844 vec_free (host_if_name);
14845
14846 S;
14847 W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14848 /* NOTREACHED */
14849 return 0;
14850}
14851
14852static int
14853api_af_packet_delete (vat_main_t * vam)
14854{
14855 unformat_input_t *i = vam->input;
14856 vl_api_af_packet_delete_t *mp;
14857 f64 timeout;
14858 u8 *host_if_name = 0;
14859
14860 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14861 {
14862 if (unformat (i, "name %s", &host_if_name))
14863 vec_add1 (host_if_name, 0);
14864 else
14865 break;
14866 }
14867
14868 if (!vec_len (host_if_name))
14869 {
14870 errmsg ("host-interface name must be specified");
14871 return -99;
14872 }
14873
14874 if (vec_len (host_if_name) > 64)
14875 {
14876 errmsg ("host-interface name too long");
14877 return -99;
14878 }
14879
14880 M (AF_PACKET_DELETE, af_packet_delete);
14881
14882 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14883 vec_free (host_if_name);
14884
14885 S;
14886 W;
14887 /* NOTREACHED */
14888 return 0;
14889}
14890
14891static int
14892api_policer_add_del (vat_main_t * vam)
14893{
14894 unformat_input_t *i = vam->input;
14895 vl_api_policer_add_del_t *mp;
14896 f64 timeout;
14897 u8 is_add = 1;
14898 u8 *name = 0;
14899 u32 cir = 0;
14900 u32 eir = 0;
14901 u64 cb = 0;
14902 u64 eb = 0;
14903 u8 rate_type = 0;
14904 u8 round_type = 0;
14905 u8 type = 0;
14906 u8 color_aware = 0;
14907 sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14908
14909 conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14910 conform_action.dscp = 0;
14911 exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14912 exceed_action.dscp = 0;
14913 violate_action.action_type = SSE2_QOS_ACTION_DROP;
14914 violate_action.dscp = 0;
14915
14916 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14917 {
14918 if (unformat (i, "del"))
14919 is_add = 0;
14920 else if (unformat (i, "name %s", &name))
14921 vec_add1 (name, 0);
14922 else if (unformat (i, "cir %u", &cir))
14923 ;
14924 else if (unformat (i, "eir %u", &eir))
14925 ;
14926 else if (unformat (i, "cb %u", &cb))
14927 ;
14928 else if (unformat (i, "eb %u", &eb))
14929 ;
14930 else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14931 &rate_type))
14932 ;
14933 else if (unformat (i, "round_type %U", unformat_policer_round_type,
14934 &round_type))
14935 ;
14936 else if (unformat (i, "type %U", unformat_policer_type, &type))
14937 ;
14938 else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14939 &conform_action))
14940 ;
14941 else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14942 &exceed_action))
14943 ;
14944 else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14945 &violate_action))
14946 ;
14947 else if (unformat (i, "color-aware"))
14948 color_aware = 1;
14949 else
14950 break;
14951 }
14952
14953 if (!vec_len (name))
14954 {
14955 errmsg ("policer name must be specified");
14956 return -99;
14957 }
14958
14959 if (vec_len (name) > 64)
14960 {
14961 errmsg ("policer name too long");
14962 return -99;
14963 }
14964
14965 M (POLICER_ADD_DEL, policer_add_del);
14966
14967 clib_memcpy (mp->name, name, vec_len (name));
14968 vec_free (name);
14969 mp->is_add = is_add;
14970 mp->cir = cir;
14971 mp->eir = eir;
14972 mp->cb = cb;
14973 mp->eb = eb;
14974 mp->rate_type = rate_type;
14975 mp->round_type = round_type;
14976 mp->type = type;
14977 mp->conform_action_type = conform_action.action_type;
14978 mp->conform_dscp = conform_action.dscp;
14979 mp->exceed_action_type = exceed_action.action_type;
14980 mp->exceed_dscp = exceed_action.dscp;
14981 mp->violate_action_type = violate_action.action_type;
14982 mp->violate_dscp = violate_action.dscp;
14983 mp->color_aware = color_aware;
14984
14985 S;
14986 W;
14987 /* NOTREACHED */
14988 return 0;
14989}
14990
14991static int
14992api_policer_dump (vat_main_t * vam)
14993{
14994 unformat_input_t *i = vam->input;
14995 vl_api_policer_dump_t *mp;
14996 f64 timeout = ~0;
14997 u8 *match_name = 0;
14998 u8 match_name_valid = 0;
14999
15000 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15001 {
15002 if (unformat (i, "name %s", &match_name))
15003 {
15004 vec_add1 (match_name, 0);
15005 match_name_valid = 1;
15006 }
15007 else
15008 break;
15009 }
15010
15011 M (POLICER_DUMP, policer_dump);
15012 mp->match_name_valid = match_name_valid;
15013 clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15014 vec_free (match_name);
15015 /* send it... */
15016 S;
15017
15018 /* Use a control ping for synchronization */
15019 {
15020 vl_api_control_ping_t *mp;
15021 M (CONTROL_PING, control_ping);
15022 S;
15023 }
15024 /* Wait for a reply... */
15025 W;
15026
15027 /* NOTREACHED */
15028 return 0;
15029}
15030
15031static int
15032api_policer_classify_set_interface (vat_main_t * vam)
15033{
15034 unformat_input_t *i = vam->input;
15035 vl_api_policer_classify_set_interface_t *mp;
15036 f64 timeout;
15037 u32 sw_if_index;
15038 int sw_if_index_set;
15039 u32 ip4_table_index = ~0;
15040 u32 ip6_table_index = ~0;
15041 u32 l2_table_index = ~0;
15042 u8 is_add = 1;
15043
15044 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15045 {
15046 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15047 sw_if_index_set = 1;
15048 else if (unformat (i, "sw_if_index %d", &sw_if_index))
15049 sw_if_index_set = 1;
15050 else if (unformat (i, "del"))
15051 is_add = 0;
15052 else if (unformat (i, "ip4-table %d", &ip4_table_index))
15053 ;
15054 else if (unformat (i, "ip6-table %d", &ip6_table_index))
15055 ;
15056 else if (unformat (i, "l2-table %d", &l2_table_index))
15057 ;
15058 else
15059 {
15060 clib_warning ("parse error '%U'", format_unformat_error, i);
15061 return -99;
15062 }
15063 }
15064
15065 if (sw_if_index_set == 0)
15066 {
15067 errmsg ("missing interface name or sw_if_index");
15068 return -99;
15069 }
15070
15071 M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
15072
15073 mp->sw_if_index = ntohl (sw_if_index);
15074 mp->ip4_table_index = ntohl (ip4_table_index);
15075 mp->ip6_table_index = ntohl (ip6_table_index);
15076 mp->l2_table_index = ntohl (l2_table_index);
15077 mp->is_add = is_add;
15078
15079 S;
15080 W;
15081 /* NOTREACHED */
15082 return 0;
15083}
15084
15085static int
15086api_policer_classify_dump (vat_main_t * vam)
15087{
15088 unformat_input_t *i = vam->input;
15089 vl_api_policer_classify_dump_t *mp;
15090 f64 timeout = ~0;
15091 u8 type = POLICER_CLASSIFY_N_TABLES;
15092
15093 if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15094 ;
15095 else
15096 {
15097 errmsg ("classify table type must be specified");
15098 return -99;
15099 }
15100
15101 if (!vam->json_output)
15102 {
15103 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15104 }
15105
15106 M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
15107 mp->type = type;
15108 /* send it... */
15109 S;
15110
15111 /* Use a control ping for synchronization */
15112 {
15113 vl_api_control_ping_t *mp;
15114 M (CONTROL_PING, control_ping);
15115 S;
15116 }
15117 /* Wait for a reply... */
15118 W;
15119
15120 /* NOTREACHED */
15121 return 0;
15122}
15123
15124static int
15125api_netmap_create (vat_main_t * vam)
15126{
15127 unformat_input_t *i = vam->input;
15128 vl_api_netmap_create_t *mp;
15129 f64 timeout;
15130 u8 *if_name = 0;
15131 u8 hw_addr[6];
15132 u8 random_hw_addr = 1;
15133 u8 is_pipe = 0;
15134 u8 is_master = 0;
15135
15136 memset (hw_addr, 0, sizeof (hw_addr));
15137
15138 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15139 {
15140 if (unformat (i, "name %s", &if_name))
15141 vec_add1 (if_name, 0);
15142 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15143 random_hw_addr = 0;
15144 else if (unformat (i, "pipe"))
15145 is_pipe = 1;
15146 else if (unformat (i, "master"))
15147 is_master = 1;
15148 else if (unformat (i, "slave"))
15149 is_master = 0;
15150 else
15151 break;
15152 }
15153
15154 if (!vec_len (if_name))
15155 {
15156 errmsg ("interface name must be specified");
15157 return -99;
15158 }
15159
15160 if (vec_len (if_name) > 64)
15161 {
15162 errmsg ("interface name too long");
15163 return -99;
15164 }
15165
15166 M (NETMAP_CREATE, netmap_create);
15167
15168 clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15169 clib_memcpy (mp->hw_addr, hw_addr, 6);
15170 mp->use_random_hw_addr = random_hw_addr;
15171 mp->is_pipe = is_pipe;
15172 mp->is_master = is_master;
15173 vec_free (if_name);
15174
15175 S;
15176 W;
15177 /* NOTREACHED */
15178 return 0;
15179}
15180
15181static int
15182api_netmap_delete (vat_main_t * vam)
15183{
15184 unformat_input_t *i = vam->input;
15185 vl_api_netmap_delete_t *mp;
15186 f64 timeout;
15187 u8 *if_name = 0;
15188
15189 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15190 {
15191 if (unformat (i, "name %s", &if_name))
15192 vec_add1 (if_name, 0);
15193 else
15194 break;
15195 }
15196
15197 if (!vec_len (if_name))
15198 {
15199 errmsg ("interface name must be specified");
15200 return -99;
15201 }
15202
15203 if (vec_len (if_name) > 64)
15204 {
15205 errmsg ("interface name too long");
15206 return -99;
15207 }
15208
15209 M (NETMAP_DELETE, netmap_delete);
15210
15211 clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15212 vec_free (if_name);
15213
15214 S;
15215 W;
15216 /* NOTREACHED */
15217 return 0;
15218}
15219
15220static void vl_api_mpls_tunnel_details_t_handler
15221 (vl_api_mpls_tunnel_details_t * mp)
15222{
15223 vat_main_t *vam = &vat_main;
15224 i32 len = mp->mt_next_hop_n_labels;
15225 i32 i;
15226
15227 print (vam->ofp, "[%d]: via %U %d labels ",
15228 mp->tunnel_index,
15229 format_ip4_address, mp->mt_next_hop,
15230 ntohl (mp->mt_next_hop_sw_if_index));
15231 for (i = 0; i < len; i++)
15232 {
15233 print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15234 }
15235 print (vam->ofp, "");
15236}
15237
15238static void vl_api_mpls_tunnel_details_t_handler_json
15239 (vl_api_mpls_tunnel_details_t * mp)
15240{
15241 vat_main_t *vam = &vat_main;
15242 vat_json_node_t *node = NULL;
15243 struct in_addr ip4;
15244 i32 i;
15245 i32 len = mp->mt_next_hop_n_labels;
15246
15247 if (VAT_JSON_ARRAY != vam->json_tree.type)
15248 {
15249 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15250 vat_json_init_array (&vam->json_tree);
15251 }
15252 node = vat_json_array_add (&vam->json_tree);
15253
15254 vat_json_init_object (node);
15255 vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15256 clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15257 vat_json_object_add_ip4 (node, "next_hop", ip4);
15258 vat_json_object_add_uint (node, "next_hop_sw_if_index",
15259 ntohl (mp->mt_next_hop_sw_if_index));
15260 vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15261 vat_json_object_add_uint (node, "label_count", len);
15262 for (i = 0; i < len; i++)
15263 {
15264 vat_json_object_add_uint (node, "label",
15265 ntohl (mp->mt_next_hop_out_labels[i]));
15266 }
15267}
15268
15269static int
15270api_mpls_tunnel_dump (vat_main_t * vam)
15271{
15272 vl_api_mpls_tunnel_dump_t *mp;
15273 f64 timeout;
15274 i32 index = -1;
15275
15276 /* Parse args required to build the message */
15277 while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15278 {
15279 if (!unformat (vam->input, "tunnel_index %d", &index))
15280 {
15281 index = -1;
15282 break;
15283 }
15284 }
15285
15286 print (vam->ofp, " tunnel_index %d", index);
15287
15288 M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
15289 mp->tunnel_index = htonl (index);
15290 S;
15291
15292 /* Use a control ping for synchronization */
15293 {
15294 vl_api_control_ping_t *mp;
15295 M (CONTROL_PING, control_ping);
15296 S;
15297 }
15298 W;
15299}
15300
15301#define vl_api_mpls_fib_details_t_endian vl_noop_handler
15302#define vl_api_mpls_fib_details_t_print vl_noop_handler
15303
15304static void
15305vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15306{
15307 vat_main_t *vam = &vat_main;
15308 int count = ntohl (mp->count);
15309 vl_api_fib_path2_t *fp;
15310 int i;
15311
15312 print (vam->ofp,
15313 "table-id %d, label %u, ess_bit %u",
15314 ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15315 fp = mp->path;
15316 for (i = 0; i < count; i++)
15317 {
15318 if (fp->afi == IP46_TYPE_IP6)
15319 print (vam->ofp,
15320 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15321 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15322 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15323 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15324 format_ip6_address, fp->next_hop);
15325 else if (fp->afi == IP46_TYPE_IP4)
15326 print (vam->ofp,
15327 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15328 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15329 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15330 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15331 format_ip4_address, fp->next_hop);
15332 fp++;
15333 }
15334}
15335
15336static void vl_api_mpls_fib_details_t_handler_json
15337 (vl_api_mpls_fib_details_t * mp)
15338{
15339 vat_main_t *vam = &vat_main;
15340 int count = ntohl (mp->count);
15341 vat_json_node_t *node = NULL;
15342 struct in_addr ip4;
15343 struct in6_addr ip6;
15344 vl_api_fib_path2_t *fp;
15345 int i;
15346
15347 if (VAT_JSON_ARRAY != vam->json_tree.type)
15348 {
15349 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15350 vat_json_init_array (&vam->json_tree);
15351 }
15352 node = vat_json_array_add (&vam->json_tree);
15353
15354 vat_json_init_object (node);
15355 vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15356 vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15357 vat_json_object_add_uint (node, "label", ntohl (mp->label));
15358 vat_json_object_add_uint (node, "path_count", count);
15359 fp = mp->path;
15360 for (i = 0; i < count; i++)
15361 {
15362 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15363 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15364 vat_json_object_add_uint (node, "is_local", fp->is_local);
15365 vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15366 vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15367 vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15368 vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15369 if (fp->afi == IP46_TYPE_IP4)
15370 {
15371 clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15372 vat_json_object_add_ip4 (node, "next_hop", ip4);
15373 }
15374 else if (fp->afi == IP46_TYPE_IP6)
15375 {
15376 clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15377 vat_json_object_add_ip6 (node, "next_hop", ip6);
15378 }
15379 }
15380}
15381
15382static int
15383api_mpls_fib_dump (vat_main_t * vam)
15384{
15385 vl_api_mpls_fib_dump_t *mp;
15386 f64 timeout;
15387
15388 M (MPLS_FIB_DUMP, mpls_fib_dump);
15389 S;
15390
15391 /* Use a control ping for synchronization */
15392 {
15393 vl_api_control_ping_t *mp;
15394 M (CONTROL_PING, control_ping);
15395 S;
15396 }
15397 W;
15398}
15399
15400#define vl_api_ip_fib_details_t_endian vl_noop_handler
15401#define vl_api_ip_fib_details_t_print vl_noop_handler
15402
15403static void
15404vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15405{
15406 vat_main_t *vam = &vat_main;
15407 int count = ntohl (mp->count);
15408 vl_api_fib_path_t *fp;
15409 int i;
15410
15411 print (vam->ofp,
15412 "table-id %d, prefix %U/%d",
15413 ntohl (mp->table_id), format_ip4_address, mp->address,
15414 mp->address_length);
15415 fp = mp->path;
15416 for (i = 0; i < count; i++)
15417 {
15418 if (fp->afi == IP46_TYPE_IP6)
15419 print (vam->ofp,
15420 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15421 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15422 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15423 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15424 format_ip6_address, fp->next_hop);
15425 else if (fp->afi == IP46_TYPE_IP4)
15426 print (vam->ofp,
15427 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15428 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15429 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15430 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15431 format_ip4_address, fp->next_hop);
15432 fp++;
15433 }
15434}
15435
15436static void vl_api_ip_fib_details_t_handler_json
15437 (vl_api_ip_fib_details_t * mp)
15438{
15439 vat_main_t *vam = &vat_main;
15440 int count = ntohl (mp->count);
15441 vat_json_node_t *node = NULL;
15442 struct in_addr ip4;
15443 struct in6_addr ip6;
15444 vl_api_fib_path_t *fp;
15445 int i;
15446
15447 if (VAT_JSON_ARRAY != vam->json_tree.type)
15448 {
15449 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15450 vat_json_init_array (&vam->json_tree);
15451 }
15452 node = vat_json_array_add (&vam->json_tree);
15453
15454 vat_json_init_object (node);
15455 vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15456 clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15457 vat_json_object_add_ip4 (node, "prefix", ip4);
15458 vat_json_object_add_uint (node, "mask_length", mp->address_length);
15459 vat_json_object_add_uint (node, "path_count", count);
15460 fp = mp->path;
15461 for (i = 0; i < count; i++)
15462 {
15463 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15464 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15465 vat_json_object_add_uint (node, "is_local", fp->is_local);
15466 vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15467 vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15468 vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15469 vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15470 if (fp->afi == IP46_TYPE_IP4)
15471 {
15472 clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15473 vat_json_object_add_ip4 (node, "next_hop", ip4);
15474 }
15475 else if (fp->afi == IP46_TYPE_IP6)
15476 {
15477 clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15478 vat_json_object_add_ip6 (node, "next_hop", ip6);
15479 }
15480 }
15481}
15482
15483static int
15484api_ip_fib_dump (vat_main_t * vam)
15485{
15486 vl_api_ip_fib_dump_t *mp;
15487 f64 timeout;
15488
15489 M (IP_FIB_DUMP, ip_fib_dump);
15490 S;
15491
15492 /* Use a control ping for synchronization */
15493 {
15494 vl_api_control_ping_t *mp;
15495 M (CONTROL_PING, control_ping);
15496 S;
15497 }
15498 W;
15499}
15500
15501static void vl_api_ip_neighbor_details_t_handler
15502 (vl_api_ip_neighbor_details_t * mp)
15503{
15504 vat_main_t *vam = &vat_main;
15505
15506 print (vam->ofp, "%c %U %U",
15507 (mp->is_static) ? 'S' : 'D',
15508 format_ethernet_address, &mp->mac_address,
15509 (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15510 &mp->ip_address);
15511}
15512
15513static void vl_api_ip_neighbor_details_t_handler_json
15514 (vl_api_ip_neighbor_details_t * mp)
15515{
15516
15517 vat_main_t *vam = &vat_main;
15518 vat_json_node_t *node;
15519 struct in_addr ip4;
15520 struct in6_addr ip6;
15521
15522 if (VAT_JSON_ARRAY != vam->json_tree.type)
15523 {
15524 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15525 vat_json_init_array (&vam->json_tree);
15526 }
15527 node = vat_json_array_add (&vam->json_tree);
15528
15529 vat_json_init_object (node);
15530 vat_json_object_add_string_copy (node, "flag",
15531 (mp->is_static) ? (u8 *) "static" : (u8 *)
15532 "dynamic");
15533
15534 vat_json_object_add_string_copy (node, "link_layer",
15535 format (0, "%U", format_ethernet_address,
15536 &mp->mac_address));
15537
15538 if (mp->is_ipv6)
15539 {
15540 clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15541 vat_json_object_add_ip6 (node, "ip_address", ip6);
15542 }
15543 else
15544 {
15545 clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15546 vat_json_object_add_ip4 (node, "ip_address", ip4);
15547 }
15548}
15549
15550static int
15551api_ip_neighbor_dump (vat_main_t * vam)
15552{
15553 unformat_input_t *i = vam->input;
15554 vl_api_ip_neighbor_dump_t *mp;
15555 f64 timeout;
15556 u8 is_ipv6 = 0;
15557 u32 sw_if_index = ~0;
15558
15559 /* Parse args required to build the message */
15560 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15561 {
15562 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15563 ;
15564 else if (unformat (i, "sw_if_index %d", &sw_if_index))
15565 ;
15566 else if (unformat (i, "ip6"))
15567 is_ipv6 = 1;
15568 else
15569 break;
15570 }
15571
15572 if (sw_if_index == ~0)
15573 {
15574 errmsg ("missing interface name or sw_if_index");
15575 return -99;
15576 }
15577
15578 M (IP_NEIGHBOR_DUMP, ip_neighbor_dump);
15579 mp->is_ipv6 = (u8) is_ipv6;
15580 mp->sw_if_index = ntohl (sw_if_index);
15581 S;
15582
15583 /* Use a control ping for synchronization */
15584 {
15585 vl_api_control_ping_t *mp;
15586 M (CONTROL_PING, control_ping);
15587 S;
15588 }
15589 W;
15590}
15591
15592#define vl_api_ip6_fib_details_t_endian vl_noop_handler
15593#define vl_api_ip6_fib_details_t_print vl_noop_handler
15594
15595static void
15596vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15597{
15598 vat_main_t *vam = &vat_main;
15599 int count = ntohl (mp->count);
15600 vl_api_fib_path_t *fp;
15601 int i;
15602
15603 print (vam->ofp,
15604 "table-id %d, prefix %U/%d",
15605 ntohl (mp->table_id), format_ip6_address, mp->address,
15606 mp->address_length);
15607 fp = mp->path;
15608 for (i = 0; i < count; i++)
15609 {
15610 if (fp->afi == IP46_TYPE_IP6)
15611 print (vam->ofp,
15612 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15613 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15614 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15615 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15616 format_ip6_address, fp->next_hop);
15617 else if (fp->afi == IP46_TYPE_IP4)
15618 print (vam->ofp,
15619 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15620 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15621 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15622 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15623 format_ip4_address, fp->next_hop);
15624 fp++;
15625 }
15626}
15627
15628static void vl_api_ip6_fib_details_t_handler_json
15629 (vl_api_ip6_fib_details_t * mp)
15630{
15631 vat_main_t *vam = &vat_main;
15632 int count = ntohl (mp->count);
15633 vat_json_node_t *node = NULL;
15634 struct in_addr ip4;
15635 struct in6_addr ip6;
15636 vl_api_fib_path_t *fp;
15637 int i;
15638
15639 if (VAT_JSON_ARRAY != vam->json_tree.type)
15640 {
15641 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15642 vat_json_init_array (&vam->json_tree);
15643 }
15644 node = vat_json_array_add (&vam->json_tree);
15645
15646 vat_json_init_object (node);
15647 vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15648 clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15649 vat_json_object_add_ip6 (node, "prefix", ip6);
15650 vat_json_object_add_uint (node, "mask_length", mp->address_length);
15651 vat_json_object_add_uint (node, "path_count", count);
15652 fp = mp->path;
15653 for (i = 0; i < count; i++)
15654 {
15655 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15656 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15657 vat_json_object_add_uint (node, "is_local", fp->is_local);
15658 vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15659 vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15660 vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15661 vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15662 if (fp->afi == IP46_TYPE_IP4)
15663 {
15664 clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15665 vat_json_object_add_ip4 (node, "next_hop", ip4);
15666 }
15667 else if (fp->afi == IP46_TYPE_IP6)
15668 {
15669 clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15670 vat_json_object_add_ip6 (node, "next_hop", ip6);
15671 }
15672 }
15673}
15674
15675static int
15676api_ip6_fib_dump (vat_main_t * vam)
15677{
15678 vl_api_ip6_fib_dump_t *mp;
15679 f64 timeout;
15680
15681 M (IP6_FIB_DUMP, ip6_fib_dump);
15682 S;
15683
15684 /* Use a control ping for synchronization */
15685 {
15686 vl_api_control_ping_t *mp;
15687 M (CONTROL_PING, control_ping);
15688 S;
15689 }
15690 W;
15691}
15692
15693int
15694api_classify_table_ids (vat_main_t * vam)
15695{
15696 vl_api_classify_table_ids_t *mp;
15697 f64 timeout;
15698
15699 /* Construct the API message */
15700 M (CLASSIFY_TABLE_IDS, classify_table_ids);
15701 mp->context = 0;
15702
15703 S;
15704 W;
15705 /* NOTREACHED */
15706 return 0;
15707}
15708
15709int
15710api_classify_table_by_interface (vat_main_t * vam)
15711{
15712 unformat_input_t *input = vam->input;
15713 vl_api_classify_table_by_interface_t *mp;
15714 f64 timeout;
15715
15716 u32 sw_if_index = ~0;
15717 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15718 {
15719 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15720 ;
15721 else if (unformat (input, "sw_if_index %d", &sw_if_index))
15722 ;
15723 else
15724 break;
15725 }
15726 if (sw_if_index == ~0)
15727 {
15728 errmsg ("missing interface name or sw_if_index");
15729 return -99;
15730 }
15731
15732 /* Construct the API message */
15733 M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15734 mp->context = 0;
15735 mp->sw_if_index = ntohl (sw_if_index);
15736
15737 S;
15738 W;
15739 /* NOTREACHED */
15740 return 0;
15741}
15742
15743int
15744api_classify_table_info (vat_main_t * vam)
15745{
15746 unformat_input_t *input = vam->input;
15747 vl_api_classify_table_info_t *mp;
15748 f64 timeout;
15749
15750 u32 table_id = ~0;
15751 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15752 {
15753 if (unformat (input, "table_id %d", &table_id))
15754 ;
15755 else
15756 break;
15757 }
15758 if (table_id == ~0)
15759 {
15760 errmsg ("missing table id");
15761 return -99;
15762 }
15763
15764 /* Construct the API message */
15765 M (CLASSIFY_TABLE_INFO, classify_table_info);
15766 mp->context = 0;
15767 mp->table_id = ntohl (table_id);
15768
15769 S;
15770 W;
15771 /* NOTREACHED */
15772 return 0;
15773}
15774
15775int
15776api_classify_session_dump (vat_main_t * vam)
15777{
15778 unformat_input_t *input = vam->input;
15779 vl_api_classify_session_dump_t *mp;
15780 f64 timeout;
15781
15782 u32 table_id = ~0;
15783 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15784 {
15785 if (unformat (input, "table_id %d", &table_id))
15786 ;
15787 else
15788 break;
15789 }
15790 if (table_id == ~0)
15791 {
15792 errmsg ("missing table id");
15793 return -99;
15794 }
15795
15796 /* Construct the API message */
15797 M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15798 mp->context = 0;
15799 mp->table_id = ntohl (table_id);
15800 S;
15801
15802 /* Use a control ping for synchronization */
15803 {
15804 vl_api_control_ping_t *mp;
15805 M (CONTROL_PING, control_ping);
15806 S;
15807 }
15808 W;
15809 /* NOTREACHED */
15810 return 0;
15811}
15812
15813static void
15814vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15815{
15816 vat_main_t *vam = &vat_main;
15817
15818 print (vam->ofp, "collector_address %U, collector_port %d, "
15819 "src_address %U, vrf_id %d, path_mtu %u, "
15820 "template_interval %u, udp_checksum %d",
15821 format_ip4_address, mp->collector_address,
15822 ntohs (mp->collector_port),
15823 format_ip4_address, mp->src_address,
15824 ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15825 ntohl (mp->template_interval), mp->udp_checksum);
15826
15827 vam->retval = 0;
15828 vam->result_ready = 1;
15829}
15830
15831static void
15832 vl_api_ipfix_exporter_details_t_handler_json
15833 (vl_api_ipfix_exporter_details_t * mp)
15834{
15835 vat_main_t *vam = &vat_main;
15836 vat_json_node_t node;
15837 struct in_addr collector_address;
15838 struct in_addr src_address;
15839
15840 vat_json_init_object (&node);
15841 clib_memcpy (&collector_address, &mp->collector_address,
15842 sizeof (collector_address));
15843 vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15844 vat_json_object_add_uint (&node, "collector_port",
15845 ntohs (mp->collector_port));
15846 clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15847 vat_json_object_add_ip4 (&node, "src_address", src_address);
15848 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15849 vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15850 vat_json_object_add_uint (&node, "template_interval",
15851 ntohl (mp->template_interval));
15852 vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15853
15854 vat_json_print (vam->ofp, &node);
15855 vat_json_free (&node);
15856 vam->retval = 0;
15857 vam->result_ready = 1;
15858}
15859
15860int
15861api_ipfix_exporter_dump (vat_main_t * vam)
15862{
15863 vl_api_ipfix_exporter_dump_t *mp;
15864 f64 timeout;
15865
15866 /* Construct the API message */
15867 M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15868 mp->context = 0;
15869
15870 S;
15871 W;
15872 /* NOTREACHED */
15873 return 0;
15874}
15875
15876static int
15877api_ipfix_classify_stream_dump (vat_main_t * vam)
15878{
15879 vl_api_ipfix_classify_stream_dump_t *mp;
15880 f64 timeout;
15881
15882 /* Construct the API message */
15883 M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15884 mp->context = 0;
15885
15886 S;
15887 W;
15888 /* NOTREACHED */
15889 return 0;
15890}
15891
15892static void
15893 vl_api_ipfix_classify_stream_details_t_handler
15894 (vl_api_ipfix_classify_stream_details_t * mp)
15895{
15896 vat_main_t *vam = &vat_main;
15897 print (vam->ofp, "domain_id %d, src_port %d",
15898 ntohl (mp->domain_id), ntohs (mp->src_port));
15899 vam->retval = 0;
15900 vam->result_ready = 1;
15901}
15902
15903static void
15904 vl_api_ipfix_classify_stream_details_t_handler_json
15905 (vl_api_ipfix_classify_stream_details_t * mp)
15906{
15907 vat_main_t *vam = &vat_main;
15908 vat_json_node_t node;
15909
15910 vat_json_init_object (&node);
15911 vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15912 vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15913
15914 vat_json_print (vam->ofp, &node);
15915 vat_json_free (&node);
15916 vam->retval = 0;
15917 vam->result_ready = 1;
15918}
15919
15920static int
15921api_ipfix_classify_table_dump (vat_main_t * vam)
15922{
15923 vl_api_ipfix_classify_table_dump_t *mp;
15924 f64 timeout;
15925
15926 if (!vam->json_output)
15927 {
15928 print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
15929 "transport_protocol");
15930 }
15931
15932 /* Construct the API message */
15933 M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15934
15935 /* send it... */
15936 S;
15937
15938 /* Use a control ping for synchronization */
15939 {
15940 vl_api_control_ping_t *mp;
15941 M (CONTROL_PING, control_ping);
15942 S;
15943 }
15944 W;
15945}
15946
15947static void
15948 vl_api_ipfix_classify_table_details_t_handler
15949 (vl_api_ipfix_classify_table_details_t * mp)
15950{
15951 vat_main_t *vam = &vat_main;
15952 print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
15953 mp->transport_protocol);
15954}
15955
15956static void
15957 vl_api_ipfix_classify_table_details_t_handler_json
15958 (vl_api_ipfix_classify_table_details_t * mp)
15959{
15960 vat_json_node_t *node = NULL;
15961 vat_main_t *vam = &vat_main;
15962
15963 if (VAT_JSON_ARRAY != vam->json_tree.type)
15964 {
15965 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15966 vat_json_init_array (&vam->json_tree);
15967 }
15968
15969 node = vat_json_array_add (&vam->json_tree);
15970 vat_json_init_object (node);
15971
15972 vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15973 vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15974 vat_json_object_add_uint (node, "transport_protocol",
15975 mp->transport_protocol);
15976}
15977
15978static int
15979api_sw_interface_span_enable_disable (vat_main_t * vam)
15980{
15981 unformat_input_t *i = vam->input;
15982 vl_api_sw_interface_span_enable_disable_t *mp;
15983 f64 timeout;
15984 u32 src_sw_if_index = ~0;
15985 u32 dst_sw_if_index = ~0;
15986 u8 state = 3;
15987
15988 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15989 {
15990 if (unformat
15991 (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
15992 ;
15993 else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15994 ;
15995 else
15996 if (unformat
15997 (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
15998 ;
15999 else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16000 ;
16001 else if (unformat (i, "disable"))
16002 state = 0;
16003 else if (unformat (i, "rx"))
16004 state = 1;
16005 else if (unformat (i, "tx"))
16006 state = 2;
16007 else if (unformat (i, "both"))
16008 state = 3;
16009 else
16010 break;
16011 }
16012
16013 M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
16014
16015 mp->sw_if_index_from = htonl (src_sw_if_index);
16016 mp->sw_if_index_to = htonl (dst_sw_if_index);
16017 mp->state = state;
16018
16019 S;
16020 W;
16021 /* NOTREACHED */
16022 return 0;
16023}
16024
16025static void
16026vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16027 * mp)
16028{
16029 vat_main_t *vam = &vat_main;
16030 u8 *sw_if_from_name = 0;
16031 u8 *sw_if_to_name = 0;
16032 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16033 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16034 char *states[] = { "none", "rx", "tx", "both" };
16035 hash_pair_t *p;
16036
16037 /* *INDENT-OFF* */
16038 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16039 ({
16040 if ((u32) p->value[0] == sw_if_index_from)
16041 {
16042 sw_if_from_name = (u8 *)(p->key);
16043 if (sw_if_to_name)
16044 break;
16045 }
16046 if ((u32) p->value[0] == sw_if_index_to)
16047 {
16048 sw_if_to_name = (u8 *)(p->key);
16049 if (sw_if_from_name)
16050 break;
16051 }
16052 }));
16053 /* *INDENT-ON* */
16054 print (vam->ofp, "%20s => %20s (%s)",
16055 sw_if_from_name, sw_if_to_name, states[mp->state]);
16056}
16057
16058static void
16059 vl_api_sw_interface_span_details_t_handler_json
16060 (vl_api_sw_interface_span_details_t * mp)
16061{
16062 vat_main_t *vam = &vat_main;
16063 vat_json_node_t *node = NULL;
16064 u8 *sw_if_from_name = 0;
16065 u8 *sw_if_to_name = 0;
16066 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16067 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16068 hash_pair_t *p;
16069
16070 /* *INDENT-OFF* */
16071 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16072 ({
16073 if ((u32) p->value[0] == sw_if_index_from)
16074 {
16075 sw_if_from_name = (u8 *)(p->key);
16076 if (sw_if_to_name)
16077 break;
16078 }
16079 if ((u32) p->value[0] == sw_if_index_to)
16080 {
16081 sw_if_to_name = (u8 *)(p->key);
16082 if (sw_if_from_name)
16083 break;
16084 }
16085 }));
16086 /* *INDENT-ON* */
16087
16088 if (VAT_JSON_ARRAY != vam->json_tree.type)
16089 {
16090 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16091 vat_json_init_array (&vam->json_tree);
16092 }
16093 node = vat_json_array_add (&vam->json_tree);
16094
16095 vat_json_init_object (node);
16096 vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16097 vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16098 vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16099 vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16100 vat_json_object_add_uint (node, "state", mp->state);
16101}
16102
16103static int
16104api_sw_interface_span_dump (vat_main_t * vam)
16105{
16106 vl_api_sw_interface_span_dump_t *mp;
16107 f64 timeout;
16108
16109 M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
16110 S;
16111
16112 /* Use a control ping for synchronization */
16113 {
16114 vl_api_control_ping_t *mp;
16115 M (CONTROL_PING, control_ping);
16116 S;
16117 }
16118 W;
16119}
16120
16121int
16122api_pg_create_interface (vat_main_t * vam)
16123{
16124 unformat_input_t *input = vam->input;
16125 vl_api_pg_create_interface_t *mp;
16126 f64 timeout;
16127
16128 u32 if_id = ~0;
16129 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16130 {
16131 if (unformat (input, "if_id %d", &if_id))
16132 ;
16133 else
16134 break;
16135 }
16136 if (if_id == ~0)
16137 {
16138 errmsg ("missing pg interface index");
16139 return -99;
16140 }
16141
16142 /* Construct the API message */
16143 M (PG_CREATE_INTERFACE, pg_create_interface);
16144 mp->context = 0;
16145 mp->interface_id = ntohl (if_id);
16146
16147 S;
16148 W;
16149 /* NOTREACHED */
16150 return 0;
16151}
16152
16153int
16154api_pg_capture (vat_main_t * vam)
16155{
16156 unformat_input_t *input = vam->input;
16157 vl_api_pg_capture_t *mp;
16158 f64 timeout;
16159
16160 u32 if_id = ~0;
16161 u8 enable = 1;
16162 u32 count = 1;
16163 u8 pcap_file_set = 0;
16164 u8 *pcap_file = 0;
16165 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16166 {
16167 if (unformat (input, "if_id %d", &if_id))
16168 ;
16169 else if (unformat (input, "pcap %s", &pcap_file))
16170 pcap_file_set = 1;
16171 else if (unformat (input, "count %d", &count))
16172 ;
16173 else if (unformat (input, "disable"))
16174 enable = 0;
16175 else
16176 break;
16177 }
16178 if (if_id == ~0)
16179 {
16180 errmsg ("missing pg interface index");
16181 return -99;
16182 }
16183 if (pcap_file_set > 0)
16184 {
16185 if (vec_len (pcap_file) > 255)
16186 {
16187 errmsg ("pcap file name is too long");
16188 return -99;
16189 }
16190 }
16191
16192 u32 name_len = vec_len (pcap_file);
16193 /* Construct the API message */
16194 M (PG_CAPTURE, pg_capture);
16195 mp->context = 0;
16196 mp->interface_id = ntohl (if_id);
16197 mp->is_enabled = enable;
16198 mp->count = ntohl (count);
16199 mp->pcap_name_length = ntohl (name_len);
16200 if (pcap_file_set != 0)
16201 {
16202 clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16203 }
16204 vec_free (pcap_file);
16205
16206 S;
16207 W;
16208 /* NOTREACHED */
16209 return 0;
16210}
16211
16212int
16213api_pg_enable_disable (vat_main_t * vam)
16214{
16215 unformat_input_t *input = vam->input;
16216 vl_api_pg_enable_disable_t *mp;
16217 f64 timeout;
16218
16219 u8 enable = 1;
16220 u8 stream_name_set = 0;
16221 u8 *stream_name = 0;
16222 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16223 {
16224 if (unformat (input, "stream %s", &stream_name))
16225 stream_name_set = 1;
16226 else if (unformat (input, "disable"))
16227 enable = 0;
16228 else
16229 break;
16230 }
16231
16232 if (stream_name_set > 0)
16233 {
16234 if (vec_len (stream_name) > 255)
16235 {
16236 errmsg ("stream name too long");
16237 return -99;
16238 }
16239 }
16240
16241 u32 name_len = vec_len (stream_name);
16242 /* Construct the API message */
16243 M (PG_ENABLE_DISABLE, pg_enable_disable);
16244 mp->context = 0;
16245 mp->is_enabled = enable;
16246 if (stream_name_set != 0)
16247 {
16248 mp->stream_name_length = ntohl (name_len);
16249 clib_memcpy (mp->stream_name, stream_name, name_len);
16250 }
16251 vec_free (stream_name);
16252
16253 S;
16254 W;
16255 /* NOTREACHED */
16256 return 0;
16257}
16258
16259int
16260api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16261{
16262 unformat_input_t *input = vam->input;
16263 vl_api_ip_source_and_port_range_check_add_del_t *mp;
16264 f64 timeout;
16265
16266 u16 *low_ports = 0;
16267 u16 *high_ports = 0;
16268 u16 this_low;
16269 u16 this_hi;
16270 ip4_address_t ip4_addr;
16271 ip6_address_t ip6_addr;
16272 u32 length;
16273 u32 tmp, tmp2;
16274 u8 prefix_set = 0;
16275 u32 vrf_id = ~0;
16276 u8 is_add = 1;
16277 u8 is_ipv6 = 0;
16278
16279 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16280 {
16281 if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16282 {
16283 prefix_set = 1;
16284 }
16285 else
16286 if (unformat
16287 (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16288 {
16289 prefix_set = 1;
16290 is_ipv6 = 1;
16291 }
16292 else if (unformat (input, "vrf %d", &vrf_id))
16293 ;
16294 else if (unformat (input, "del"))
16295 is_add = 0;
16296 else if (unformat (input, "port %d", &tmp))
16297 {
16298 if (tmp == 0 || tmp > 65535)
16299 {
16300 errmsg ("port %d out of range", tmp);
16301 return -99;
16302 }
16303 this_low = tmp;
16304 this_hi = this_low + 1;
16305 vec_add1 (low_ports, this_low);
16306 vec_add1 (high_ports, this_hi);
16307 }
16308 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16309 {
16310 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16311 {
16312 errmsg ("incorrect range parameters");
16313 return -99;
16314 }
16315 this_low = tmp;
16316 /* Note: in debug CLI +1 is added to high before
16317 passing to real fn that does "the work"
16318 (ip_source_and_port_range_check_add_del).
16319 This fn is a wrapper around the binary API fn a
16320 control plane will call, which expects this increment
16321 to have occurred. Hence letting the binary API control
16322 plane fn do the increment for consistency between VAT
16323 and other control planes.
16324 */
16325 this_hi = tmp2;
16326 vec_add1 (low_ports, this_low);
16327 vec_add1 (high_ports, this_hi);
16328 }
16329 else
16330 break;
16331 }
16332
16333 if (prefix_set == 0)
16334 {
16335 errmsg ("<address>/<mask> not specified");
16336 return -99;
16337 }
16338
16339 if (vrf_id == ~0)
16340 {
16341 errmsg ("VRF ID required, not specified");
16342 return -99;
16343 }
16344
16345 if (vrf_id == 0)
16346 {
16347 errmsg
16348 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16349 return -99;
16350 }
16351
16352 if (vec_len (low_ports) == 0)
16353 {
16354 errmsg ("At least one port or port range required");
16355 return -99;
16356 }
16357
16358 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
16359 ip_source_and_port_range_check_add_del);
16360
16361 mp->is_add = is_add;
16362
16363 if (is_ipv6)
16364 {
16365 mp->is_ipv6 = 1;
16366 clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16367 }
16368 else
16369 {
16370 mp->is_ipv6 = 0;
16371 clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16372 }
16373
16374 mp->mask_length = length;
16375 mp->number_of_ranges = vec_len (low_ports);
16376
16377 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16378 vec_free (low_ports);
16379
16380 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16381 vec_free (high_ports);
16382
16383 mp->vrf_id = ntohl (vrf_id);
16384
16385 S;
16386 W;
16387 /* NOTREACHED */
16388 return 0;
16389}
16390
16391int
16392api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16393{
16394 unformat_input_t *input = vam->input;
16395 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16396 f64 timeout;
16397 u32 sw_if_index = ~0;
16398 int vrf_set = 0;
16399 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16400 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16401 u8 is_add = 1;
16402
16403 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16404 {
16405 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16406 ;
16407 else if (unformat (input, "sw_if_index %d", &sw_if_index))
16408 ;
16409 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16410 vrf_set = 1;
16411 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16412 vrf_set = 1;
16413 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16414 vrf_set = 1;
16415 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16416 vrf_set = 1;
16417 else if (unformat (input, "del"))
16418 is_add = 0;
16419 else
16420 break;
16421 }
16422
16423 if (sw_if_index == ~0)
16424 {
16425 errmsg ("Interface required but not specified");
16426 return -99;
16427 }
16428
16429 if (vrf_set == 0)
16430 {
16431 errmsg ("VRF ID required but not specified");
16432 return -99;
16433 }
16434
16435 if (tcp_out_vrf_id == 0
16436 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16437 {
16438 errmsg
16439 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16440 return -99;
16441 }
16442
16443 /* Construct the API message */
16444 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
16445 ip_source_and_port_range_check_interface_add_del);
16446
16447 mp->sw_if_index = ntohl (sw_if_index);
16448 mp->is_add = is_add;
16449 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16450 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16451 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16452 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16453
16454 /* send it... */
16455 S;
16456
16457 /* Wait for a reply... */
16458 W;
16459}
16460
16461static int
16462api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16463{
16464 unformat_input_t *i = vam->input;
16465 vl_api_ipsec_gre_add_del_tunnel_t *mp;
16466 f64 timeout;
16467 u32 local_sa_id = 0;
16468 u32 remote_sa_id = 0;
16469 ip4_address_t src_address;
16470 ip4_address_t dst_address;
16471 u8 is_add = 1;
16472
16473 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16474 {
16475 if (unformat (i, "local_sa %d", &local_sa_id))
16476 ;
16477 else if (unformat (i, "remote_sa %d", &remote_sa_id))
16478 ;
16479 else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16480 ;
16481 else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16482 ;
16483 else if (unformat (i, "del"))
16484 is_add = 0;
16485 else
16486 {
16487 clib_warning ("parse error '%U'", format_unformat_error, i);
16488 return -99;
16489 }
16490 }
16491
16492 M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
16493
16494 mp->local_sa_id = ntohl (local_sa_id);
16495 mp->remote_sa_id = ntohl (remote_sa_id);
16496 clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16497 clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16498 mp->is_add = is_add;
16499
16500 S;
16501 W;
16502 /* NOTREACHED */
16503 return 0;
16504}
16505
16506static int
16507api_punt (vat_main_t * vam)
16508{
16509 unformat_input_t *i = vam->input;
16510 vl_api_punt_t *mp;
16511 f64 timeout;
16512 u32 ipv = ~0;
16513 u32 protocol = ~0;
16514 u32 port = ~0;
16515 int is_add = 1;
16516
16517 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16518 {
16519 if (unformat (i, "ip %d", &ipv))
16520 ;
16521 else if (unformat (i, "protocol %d", &protocol))
16522 ;
16523 else if (unformat (i, "port %d", &port))
16524 ;
16525 else if (unformat (i, "del"))
16526 is_add = 0;
16527 else
16528 {
16529 clib_warning ("parse error '%U'", format_unformat_error, i);
16530 return -99;
16531 }
16532 }
16533
16534 M (PUNT, punt);
16535
16536 mp->is_add = (u8) is_add;
16537 mp->ipv = (u8) ipv;
16538 mp->l4_protocol = (u8) protocol;
16539 mp->l4_port = htons ((u16) port);
16540
16541 S;
16542 W;
16543 /* NOTREACHED */
16544 return 0;
16545}
16546
16547static void vl_api_ipsec_gre_tunnel_details_t_handler
16548 (vl_api_ipsec_gre_tunnel_details_t * mp)
16549{
16550 vat_main_t *vam = &vat_main;
16551
16552 print (vam->ofp, "%11d%15U%15U%14d%14d",
16553 ntohl (mp->sw_if_index),
16554 format_ip4_address, &mp->src_address,
16555 format_ip4_address, &mp->dst_address,
16556 ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16557}
16558
16559static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16560 (vl_api_ipsec_gre_tunnel_details_t * mp)
16561{
16562 vat_main_t *vam = &vat_main;
16563 vat_json_node_t *node = NULL;
16564 struct in_addr ip4;
16565
16566 if (VAT_JSON_ARRAY != vam->json_tree.type)
16567 {
16568 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16569 vat_json_init_array (&vam->json_tree);
16570 }
16571 node = vat_json_array_add (&vam->json_tree);
16572
16573 vat_json_init_object (node);
16574 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16575 clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16576 vat_json_object_add_ip4 (node, "src_address", ip4);
16577 clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16578 vat_json_object_add_ip4 (node, "dst_address", ip4);
16579 vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16580 vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16581}
16582
16583static int
16584api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16585{
16586 unformat_input_t *i = vam->input;
16587 vl_api_ipsec_gre_tunnel_dump_t *mp;
16588 f64 timeout;
16589 u32 sw_if_index;
16590 u8 sw_if_index_set = 0;
16591
16592 /* Parse args required to build the message */
16593 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16594 {
16595 if (unformat (i, "sw_if_index %d", &sw_if_index))
16596 sw_if_index_set = 1;
16597 else
16598 break;
16599 }
16600
16601 if (sw_if_index_set == 0)
16602 {
16603 sw_if_index = ~0;
16604 }
16605
16606 if (!vam->json_output)
16607 {
16608 print (vam->ofp, "%11s%15s%15s%14s%14s",
16609 "sw_if_index", "src_address", "dst_address",
16610 "local_sa_id", "remote_sa_id");
16611 }
16612
16613 /* Get list of gre-tunnel interfaces */
16614 M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16615
16616 mp->sw_if_index = htonl (sw_if_index);
16617
16618 S;
16619
16620 /* Use a control ping for synchronization */
16621 {
16622 vl_api_control_ping_t *mp;
16623 M (CONTROL_PING, control_ping);
16624 S;
16625 }
16626 W;
16627}
16628
16629static int
16630api_delete_subif (vat_main_t * vam)
16631{
16632 unformat_input_t *i = vam->input;
16633 vl_api_delete_subif_t *mp;
16634 f64 timeout;
16635 u32 sw_if_index = ~0;
16636
16637 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16638 {
16639 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16640 ;
16641 if (unformat (i, "sw_if_index %d", &sw_if_index))
16642 ;
16643 else
16644 break;
16645 }
16646
16647 if (sw_if_index == ~0)
16648 {
16649 errmsg ("missing sw_if_index");
16650 return -99;
16651 }
16652
16653 /* Construct the API message */
16654 M (DELETE_SUBIF, delete_subif);
16655 mp->sw_if_index = ntohl (sw_if_index);
16656
16657 S;
16658 W;
16659}
16660
16661#define foreach_pbb_vtr_op \
16662_("disable", L2_VTR_DISABLED) \
16663_("pop", L2_VTR_POP_2) \
16664_("push", L2_VTR_PUSH_2)
16665
16666static int
16667api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16668{
16669 unformat_input_t *i = vam->input;
16670 vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16671 f64 timeout;
16672 u32 sw_if_index = ~0, vtr_op = ~0;
16673 u16 outer_tag = ~0;
16674 u8 dmac[6], smac[6];
16675 u8 dmac_set = 0, smac_set = 0;
16676 u16 vlanid = 0;
16677 u32 sid = ~0;
16678 u32 tmp;
16679
16680 /* Shut up coverity */
16681 memset (dmac, 0, sizeof (dmac));
16682 memset (smac, 0, sizeof (smac));
16683
16684 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16685 {
16686 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16687 ;
16688 else if (unformat (i, "sw_if_index %d", &sw_if_index))
16689 ;
16690 else if (unformat (i, "vtr_op %d", &vtr_op))
16691 ;
16692#define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16693 foreach_pbb_vtr_op
16694#undef _
16695 else if (unformat (i, "translate_pbb_stag"))
16696 {
16697 if (unformat (i, "%d", &tmp))
16698 {
16699 vtr_op = L2_VTR_TRANSLATE_2_1;
16700 outer_tag = tmp;
16701 }
16702 else
16703 {
16704 errmsg
16705 ("translate_pbb_stag operation requires outer tag definition");
16706 return -99;
16707 }
16708 }
16709 else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16710 dmac_set++;
16711 else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16712 smac_set++;
16713 else if (unformat (i, "sid %d", &sid))
16714 ;
16715 else if (unformat (i, "vlanid %d", &tmp))
16716 vlanid = tmp;
16717 else
16718 {
16719 clib_warning ("parse error '%U'", format_unformat_error, i);
16720 return -99;
16721 }
16722 }
16723
16724 if ((sw_if_index == ~0) || (vtr_op == ~0))
16725 {
16726 errmsg ("missing sw_if_index or vtr operation");
16727 return -99;
16728 }
16729 if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16730 && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16731 {
16732 errmsg
16733 ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
16734 return -99;
16735 }
16736
16737 M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16738 mp->sw_if_index = ntohl (sw_if_index);
16739 mp->vtr_op = ntohl (vtr_op);
16740 mp->outer_tag = ntohs (outer_tag);
16741 clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16742 clib_memcpy (mp->b_smac, smac, sizeof (smac));
16743 mp->b_vlanid = ntohs (vlanid);
16744 mp->i_sid = ntohl (sid);
16745
16746 S;
16747 W;
16748 /* NOTREACHED */
16749 return 0;
16750}
16751
16752static int
16753api_flow_classify_set_interface (vat_main_t * vam)
16754{
16755 unformat_input_t *i = vam->input;
16756 vl_api_flow_classify_set_interface_t *mp;
16757 f64 timeout;
16758 u32 sw_if_index;
16759 int sw_if_index_set;
16760 u32 ip4_table_index = ~0;
16761 u32 ip6_table_index = ~0;
16762 u8 is_add = 1;
16763
16764 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16765 {
16766 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16767 sw_if_index_set = 1;
16768 else if (unformat (i, "sw_if_index %d", &sw_if_index))
16769 sw_if_index_set = 1;
16770 else if (unformat (i, "del"))
16771 is_add = 0;
16772 else if (unformat (i, "ip4-table %d", &ip4_table_index))
16773 ;
16774 else if (unformat (i, "ip6-table %d", &ip6_table_index))
16775 ;
16776 else
16777 {
16778 clib_warning ("parse error '%U'", format_unformat_error, i);
16779 return -99;
16780 }
16781 }
16782
16783 if (sw_if_index_set == 0)
16784 {
16785 errmsg ("missing interface name or sw_if_index");
16786 return -99;
16787 }
16788
16789 M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16790
16791 mp->sw_if_index = ntohl (sw_if_index);
16792 mp->ip4_table_index = ntohl (ip4_table_index);
16793 mp->ip6_table_index = ntohl (ip6_table_index);
16794 mp->is_add = is_add;
16795
16796 S;
16797 W;
16798 /* NOTREACHED */
16799 return 0;
16800}
16801
16802static int
16803api_flow_classify_dump (vat_main_t * vam)
16804{
16805 unformat_input_t *i = vam->input;
16806 vl_api_flow_classify_dump_t *mp;
16807 f64 timeout = ~0;
16808 u8 type = FLOW_CLASSIFY_N_TABLES;
16809
16810 if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16811 ;
16812 else
16813 {
16814 errmsg ("classify table type must be specified");
16815 return -99;
16816 }
16817
16818 if (!vam->json_output)
16819 {
16820 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16821 }
16822
16823 M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16824 mp->type = type;
16825 /* send it... */
16826 S;
16827
16828 /* Use a control ping for synchronization */
16829 {
16830 vl_api_control_ping_t *mp;
16831 M (CONTROL_PING, control_ping);
16832 S;
16833 }
16834 /* Wait for a reply... */
16835 W;
16836
16837 /* NOTREACHED */
16838 return 0;
16839}
16840
16841static int
16842api_feature_enable_disable (vat_main_t * vam)
16843{
16844 unformat_input_t *i = vam->input;
16845 vl_api_feature_enable_disable_t *mp;
16846 f64 timeout;
16847 u8 *arc_name = 0;
16848 u8 *feature_name = 0;
16849 u32 sw_if_index = ~0;
16850 u8 enable = 1;
16851
16852 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16853 {
16854 if (unformat (i, "arc_name %s", &arc_name))
16855 ;
16856 else if (unformat (i, "feature_name %s", &feature_name))
16857 ;
16858 else
16859 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16860 ;
16861 else if (unformat (i, "sw_if_index %d", &sw_if_index))
16862 ;
16863 else if (unformat (i, "disable"))
16864 enable = 0;
16865 else
16866 break;
16867 }
16868
16869 if (arc_name == 0)
16870 {
16871 errmsg ("missing arc name");
16872 return -99;
16873 }
16874 if (vec_len (arc_name) > 63)
16875 {
16876 errmsg ("arc name too long");
16877 }
16878
16879 if (feature_name == 0)
16880 {
16881 errmsg ("missing feature name");
16882 return -99;
16883 }
16884 if (vec_len (feature_name) > 63)
16885 {
16886 errmsg ("feature name too long");
16887 }
16888
16889 if (sw_if_index == ~0)
16890 {
16891 errmsg ("missing interface name or sw_if_index");
16892 return -99;
16893 }
16894
16895 /* Construct the API message */
16896 M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16897 mp->sw_if_index = ntohl (sw_if_index);
16898 mp->enable = enable;
16899 clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16900 clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16901 vec_free (arc_name);
16902 vec_free (feature_name);
16903
16904 S;
16905 W;
16906}
16907
16908static int
16909api_sw_interface_tag_add_del (vat_main_t * vam)
16910{
16911 unformat_input_t *i = vam->input;
16912 vl_api_sw_interface_tag_add_del_t *mp;
16913 f64 timeout;
16914 u32 sw_if_index = ~0;
16915 u8 *tag = 0;
16916 u8 enable = 1;
16917
16918 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16919 {
16920 if (unformat (i, "tag %s", &tag))
16921 ;
16922 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16923 ;
16924 else if (unformat (i, "sw_if_index %d", &sw_if_index))
16925 ;
16926 else if (unformat (i, "del"))
16927 enable = 0;
16928 else
16929 break;
16930 }
16931
16932 if (sw_if_index == ~0)
16933 {
16934 errmsg ("missing interface name or sw_if_index");
16935 return -99;
16936 }
16937
16938 if (enable && (tag == 0))
16939 {
16940 errmsg ("no tag specified");
16941 return -99;
16942 }
16943
16944 /* Construct the API message */
16945 M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
16946 mp->sw_if_index = ntohl (sw_if_index);
16947 mp->is_add = enable;
16948 if (enable)
16949 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
16950 vec_free (tag);
16951
16952 S;
16953 W;
16954}
16955
16956static void vl_api_l2_xconnect_details_t_handler
16957 (vl_api_l2_xconnect_details_t * mp)
16958{
16959 vat_main_t *vam = &vat_main;
16960
16961 print (vam->ofp, "%15d%15d",
16962 ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
16963}
16964
16965static void vl_api_l2_xconnect_details_t_handler_json
16966 (vl_api_l2_xconnect_details_t * mp)
16967{
16968 vat_main_t *vam = &vat_main;
16969 vat_json_node_t *node = NULL;
16970
16971 if (VAT_JSON_ARRAY != vam->json_tree.type)
16972 {
16973 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16974 vat_json_init_array (&vam->json_tree);
16975 }
16976 node = vat_json_array_add (&vam->json_tree);
16977
16978 vat_json_init_object (node);
16979 vat_json_object_add_uint (node, "rx_sw_if_index",
16980 ntohl (mp->rx_sw_if_index));
16981 vat_json_object_add_uint (node, "tx_sw_if_index",
16982 ntohl (mp->tx_sw_if_index));
16983}
16984
16985static int
16986api_l2_xconnect_dump (vat_main_t * vam)
16987{
16988 vl_api_l2_xconnect_dump_t *mp;
16989 f64 timeout;
16990
16991 if (!vam->json_output)
16992 {
16993 print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
16994 }
16995
16996 M (L2_XCONNECT_DUMP, l2_xconnect_dump);
16997
16998 S;
16999
17000 /* Use a control ping for synchronization */
17001 {
17002 vl_api_control_ping_t *mp;
17003 M (CONTROL_PING, control_ping);
17004 S;
17005 }
17006 W;
17007}
17008
17009static int
17010api_sw_interface_set_mtu (vat_main_t * vam)
17011{
17012 unformat_input_t *i = vam->input;
17013 vl_api_sw_interface_set_mtu_t *mp;
17014 f64 timeout;
17015 u32 sw_if_index = ~0;
17016 u32 mtu = 0;
17017
17018 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17019 {
17020 if (unformat (i, "mtu %d", &mtu))
17021 ;
17022 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17023 ;
17024 else if (unformat (i, "sw_if_index %d", &sw_if_index))
17025 ;
17026 else
17027 break;
17028 }
17029
17030 if (sw_if_index == ~0)
17031 {
17032 errmsg ("missing interface name or sw_if_index");
17033 return -99;
17034 }
17035
17036 if (mtu == 0)
17037 {
17038 errmsg ("no mtu specified");
17039 return -99;
17040 }
17041
17042 /* Construct the API message */
17043 M (SW_INTERFACE_SET_MTU, sw_interface_set_mtu);
17044 mp->sw_if_index = ntohl (sw_if_index);
17045 mp->mtu = ntohs ((u16) mtu);
17046
17047 S;
17048 W;
17049}
17050
17051
17052static int
17053q_or_quit (vat_main_t * vam)
17054{
17055 longjmp (vam->jump_buf, 1);
17056 return 0; /* not so much */
17057}
17058
17059static int
17060q (vat_main_t * vam)
17061{
17062 return q_or_quit (vam);
17063}
17064
17065static int
17066quit (vat_main_t * vam)
17067{
17068 return q_or_quit (vam);
17069}
17070
17071static int
17072comment (vat_main_t * vam)
17073{
17074 return 0;
17075}
17076
17077static int
17078cmd_cmp (void *a1, void *a2)
17079{
17080 u8 **c1 = a1;
17081 u8 **c2 = a2;
17082
17083 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17084}
17085
17086static int
17087help (vat_main_t * vam)
17088{
17089 u8 **cmds = 0;
17090 u8 *name = 0;
17091 hash_pair_t *p;
17092 unformat_input_t *i = vam->input;
17093 int j;
17094
17095 if (unformat (i, "%s", &name))
17096 {
17097 uword *hs;
17098
17099 vec_add1 (name, 0);
17100
17101 hs = hash_get_mem (vam->help_by_name, name);
17102 if (hs)
17103 print (vam->ofp, "usage: %s %s", name, hs[0]);
17104 else
17105 print (vam->ofp, "No such msg / command '%s'", name);
17106 vec_free (name);
17107 return 0;
17108 }
17109
17110 print (vam->ofp, "Help is available for the following:");
17111
17112 /* *INDENT-OFF* */
17113 hash_foreach_pair (p, vam->function_by_name,
17114 ({
17115 vec_add1 (cmds, (u8 *)(p->key));
17116 }));
17117 /* *INDENT-ON* */
17118
17119 vec_sort_with_function (cmds, cmd_cmp);
17120
17121 for (j = 0; j < vec_len (cmds); j++)
17122 print (vam->ofp, "%s", cmds[j]);
17123
17124 vec_free (cmds);
17125 return 0;
17126}
17127
17128static int
17129set (vat_main_t * vam)
17130{
17131 u8 *name = 0, *value = 0;
17132 unformat_input_t *i = vam->input;
17133
17134 if (unformat (i, "%s", &name))
17135 {
17136 /* The input buffer is a vector, not a string. */
17137 value = vec_dup (i->buffer);
17138 vec_delete (value, i->index, 0);
17139 /* Almost certainly has a trailing newline */
17140 if (value[vec_len (value) - 1] == '\n')
17141 value[vec_len (value) - 1] = 0;
17142 /* Make sure it's a proper string, one way or the other */
17143 vec_add1 (value, 0);
17144 (void) clib_macro_set_value (&vam->macro_main,
17145 (char *) name, (char *) value);
17146 }
17147 else
17148 errmsg ("usage: set <name> <value>");
17149
17150 vec_free (name);
17151 vec_free (value);
17152 return 0;
17153}
17154
17155static int
17156unset (vat_main_t * vam)
17157{
17158 u8 *name = 0;
17159
17160 if (unformat (vam->input, "%s", &name))
17161 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17162 errmsg ("unset: %s wasn't set", name);
17163 vec_free (name);
17164 return 0;
17165}
17166
17167typedef struct
17168{
17169 u8 *name;
17170 u8 *value;
17171} macro_sort_t;
17172
17173
17174static int
17175macro_sort_cmp (void *a1, void *a2)
17176{
17177 macro_sort_t *s1 = a1;
17178 macro_sort_t *s2 = a2;
17179
17180 return strcmp ((char *) (s1->name), (char *) (s2->name));
17181}
17182
17183static int
17184dump_macro_table (vat_main_t * vam)
17185{
17186 macro_sort_t *sort_me = 0, *sm;
17187 int i;
17188 hash_pair_t *p;
17189
17190 /* *INDENT-OFF* */
17191 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17192 ({
17193 vec_add2 (sort_me, sm, 1);
17194 sm->name = (u8 *)(p->key);
17195 sm->value = (u8 *) (p->value[0]);
17196 }));
17197 /* *INDENT-ON* */
17198
17199 vec_sort_with_function (sort_me, macro_sort_cmp);
17200
17201 if (vec_len (sort_me))
17202 print (vam->ofp, "%-15s%s", "Name", "Value");
17203 else
17204 print (vam->ofp, "The macro table is empty...");
17205
17206 for (i = 0; i < vec_len (sort_me); i++)
17207 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17208 return 0;
17209}
17210
17211static int
17212dump_node_table (vat_main_t * vam)
17213{
17214 int i, j;
17215 vlib_node_t *node, *next_node;
17216
17217 if (vec_len (vam->graph_nodes) == 0)
17218 {
17219 print (vam->ofp, "Node table empty, issue get_node_graph...");
17220 return 0;
17221 }
17222
17223 for (i = 0; i < vec_len (vam->graph_nodes); i++)
17224 {
17225 node = vam->graph_nodes[i];
17226 print (vam->ofp, "[%d] %s", i, node->name);
17227 for (j = 0; j < vec_len (node->next_nodes); j++)
17228 {
17229 if (node->next_nodes[j] != ~0)
17230 {
17231 next_node = vam->graph_nodes[node->next_nodes[j]];
17232 print (vam->ofp, " [%d] %s", j, next_node->name);
17233 }
17234 }
17235 }
17236 return 0;
17237}
17238
17239static int
17240value_sort_cmp (void *a1, void *a2)
17241{
17242 name_sort_t *n1 = a1;
17243 name_sort_t *n2 = a2;
17244
17245 if (n1->value < n2->value)
17246 return -1;
17247 if (n1->value > n2->value)
17248 return 1;
17249 return 0;
17250}
17251
17252
17253static int
17254dump_msg_api_table (vat_main_t * vam)
17255{
17256 api_main_t *am = &api_main;
17257 name_sort_t *nses = 0, *ns;
17258 hash_pair_t *hp;
17259 int i;
17260
17261 /* *INDENT-OFF* */
17262 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17263 ({
17264 vec_add2 (nses, ns, 1);
17265 ns->name = (u8 *)(hp->key);
17266 ns->value = (u32) hp->value[0];
17267 }));
17268 /* *INDENT-ON* */
17269
17270 vec_sort_with_function (nses, value_sort_cmp);
17271
17272 for (i = 0; i < vec_len (nses); i++)
17273 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17274 vec_free (nses);
17275 return 0;
17276}
17277
17278static int
17279get_msg_id (vat_main_t * vam)
17280{
17281 u8 *name_and_crc;
17282 u32 message_index;
17283
17284 if (unformat (vam->input, "%s", &name_and_crc))
17285 {
17286 message_index = vl_api_get_msg_index (name_and_crc);
17287 if (message_index == ~0)
17288 {
17289 print (vam->ofp, " '%s' not found", name_and_crc);
17290 return 0;
17291 }
17292 print (vam->ofp, " '%s' has message index %d",
17293 name_and_crc, message_index);
17294 return 0;
17295 }
17296 errmsg ("name_and_crc required...");
17297 return 0;
17298}
17299
17300static int
17301search_node_table (vat_main_t * vam)
17302{
17303 unformat_input_t *line_input = vam->input;
17304 u8 *node_to_find;
17305 int j;
17306 vlib_node_t *node, *next_node;
17307 uword *p;
17308
17309 if (vam->graph_node_index_by_name == 0)
17310 {
17311 print (vam->ofp, "Node table empty, issue get_node_graph...");
17312 return 0;
17313 }
17314
17315 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17316 {
17317 if (unformat (line_input, "%s", &node_to_find))
17318 {
17319 vec_add1 (node_to_find, 0);
17320 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17321 if (p == 0)
17322 {
17323 print (vam->ofp, "%s not found...", node_to_find);
17324 goto out;
17325 }
17326 node = vam->graph_nodes[p[0]];
17327 print (vam->ofp, "[%d] %s", p[0], node->name);
17328 for (j = 0; j < vec_len (node->next_nodes); j++)
17329 {
17330 if (node->next_nodes[j] != ~0)
17331 {
17332 next_node = vam->graph_nodes[node->next_nodes[j]];
17333 print (vam->ofp, " [%d] %s", j, next_node->name);
17334 }
17335 }
17336 }
17337
17338 else
17339 {
17340 clib_warning ("parse error '%U'", format_unformat_error,
17341 line_input);
17342 return -99;
17343 }
17344
17345 out:
17346 vec_free (node_to_find);
17347
17348 }
17349
17350 return 0;
17351}
17352
17353
17354static int
17355script (vat_main_t * vam)
17356{
17357#if (VPP_API_TEST_BUILTIN==0)
17358 u8 *s = 0;
17359 char *save_current_file;
17360 unformat_input_t save_input;
17361 jmp_buf save_jump_buf;
17362 u32 save_line_number;
17363
17364 FILE *new_fp, *save_ifp;
17365
17366 if (unformat (vam->input, "%s", &s))
17367 {
17368 new_fp = fopen ((char *) s, "r");
17369 if (new_fp == 0)
17370 {
17371 errmsg ("Couldn't open script file %s", s);
17372 vec_free (s);
17373 return -99;
17374 }
17375 }
17376 else
17377 {
17378 errmsg ("Missing script name");
17379 return -99;
17380 }
17381
17382 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17383 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17384 save_ifp = vam->ifp;
17385 save_line_number = vam->input_line_number;
17386 save_current_file = (char *) vam->current_file;
17387
17388 vam->input_line_number = 0;
17389 vam->ifp = new_fp;
17390 vam->current_file = s;
17391 do_one_file (vam);
17392
17393 clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17394 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17395 vam->ifp = save_ifp;
17396 vam->input_line_number = save_line_number;
17397 vam->current_file = (u8 *) save_current_file;
17398 vec_free (s);
17399
17400 return 0;
17401#else
17402 clib_warning ("use the exec command...");
17403 return -99;
17404#endif
17405}
17406
17407static int
17408echo (vat_main_t * vam)
17409{
17410 print (vam->ofp, "%v", vam->input->buffer);
17411 return 0;
17412}
17413
17414/* List of API message constructors, CLI names map to api_xxx */
17415#define foreach_vpe_api_msg \
17416_(create_loopback,"[mac <mac-addr>]") \
17417_(sw_interface_dump,"") \
17418_(sw_interface_set_flags, \
17419 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17420_(sw_interface_add_del_address, \
17421 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17422_(sw_interface_set_table, \
17423 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
17424_(sw_interface_set_mpls_enable, \
17425 "<intfc> | sw_if_index [disable | dis]") \
17426_(sw_interface_set_vpath, \
17427 "<intfc> | sw_if_index <id> enable | disable") \
17428_(sw_interface_set_vxlan_bypass, \
17429 "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable") \
17430_(sw_interface_set_l2_xconnect, \
17431 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17432 "enable | disable") \
17433_(sw_interface_set_l2_bridge, \
17434 "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n" \
17435 "[shg <split-horizon-group>] [bvi]\n" \
17436 "enable | disable") \
17437_(sw_interface_set_dpdk_hqos_pipe, \
17438 "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
17439 "profile <profile-id>\n") \
17440_(sw_interface_set_dpdk_hqos_subport, \
17441 "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n" \
17442 "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
17443_(sw_interface_set_dpdk_hqos_tctbl, \
17444 "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n") \
17445_(bridge_domain_add_del, \
17446 "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
17447_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
17448_(l2fib_add_del, \
17449 "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17450_(l2_flags, \
17451 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
17452_(bridge_flags, \
17453 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17454_(tap_connect, \
17455 "tapname <name> mac <mac-addr> | random-mac [tag <string>]") \
17456_(tap_modify, \
17457 "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17458_(tap_delete, \
17459 "<vpp-if-name> | sw_if_index <id>") \
17460_(sw_interface_tap_dump, "") \
17461_(ip_add_del_route, \
17462 "<addr>/<mask> via <addr> [table-id <n>]\n" \
17463 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n" \
17464 "[weight <n>] [drop] [local] [classify <n>] [del]\n" \
17465 "[multipath] [count <n>]") \
17466_(mpls_route_add_del, \
17467 "<label> <eos> via <addr> [table-id <n>]\n" \
17468 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n" \
17469 "[weight <n>] [drop] [local] [classify <n>] [del]\n" \
17470 "[multipath] [count <n>]") \
17471_(mpls_ip_bind_unbind, \
17472 "<label> <addr/len>") \
17473_(mpls_tunnel_add_del, \
17474 " via <addr> [table-id <n>]\n" \
17475 "sw_if_index <id>] [l2] [del]") \
17476_(proxy_arp_add_del, \
17477 "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]") \
17478_(proxy_arp_intfc_enable_disable, \
17479 "<intfc> | sw_if_index <id> enable | disable") \
17480_(sw_interface_set_unnumbered, \
17481 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
17482_(ip_neighbor_add_del, \
17483 "(<intfc> | sw_if_index <id>) dst <ip46-address> " \
17484 "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]") \
17485_(reset_vrf, "vrf <id> [ipv6]") \
17486_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
17487_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
17488 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
17489 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
17490 "[outer_vlan_id_any][inner_vlan_id_any]") \
17491_(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]") \
17492_(reset_fib, "vrf <n> [ipv6]") \
17493_(dhcp_proxy_config, \
17494 "svr <v46-address> src <v46-address>\n" \
17495 "insert-cid <n> [del]") \
17496_(dhcp_proxy_config_2, \
17497 "svr <v46-address> src <v46-address>\n" \
17498 "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]") \
17499_(dhcp_proxy_set_vss, \
17500 "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]") \
17501_(dhcp_client_config, \
17502 "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17503_(set_ip_flow_hash, \
17504 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
17505_(sw_interface_ip6_enable_disable, \
17506 "<intfc> | sw_if_index <id> enable | disable") \
17507_(sw_interface_ip6_set_link_local_address, \
17508 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>") \
17509_(sw_interface_ip6nd_ra_prefix, \
17510 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n" \
17511 "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n" \
17512 "[nolink] [isno]") \
17513_(sw_interface_ip6nd_ra_config, \
17514 "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n" \
17515 "[life <n>] [count <n>] [interval <n>] [suppress]\n" \
17516 "[managed] [other] [ll] [send] [cease] [isno] [def]") \
17517_(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]") \
17518_(l2_patch_add_del, \
17519 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17520 "enable | disable") \
17521_(sr_tunnel_add_del, \
17522 "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n" \
17523 "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n" \
17524 "[policy <policy_name>]") \
17525_(sr_policy_add_del, \
17526 "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]") \
17527_(sr_multicast_map_add_del, \
17528 "address [ip6 multicast address] sr-policy [policy name] [del]") \
17529_(classify_add_del_table, \
17530 "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
17531 " [del] [del-chain] mask <mask-value>\n" \
17532 " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n" \
17533 " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]") \
17534_(classify_add_del_session, \
17535 "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n" \
17536 " table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n" \
17537 " [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n" \
17538 " [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]") \
17539_(classify_set_interface_ip_table, \
17540 "<intfc> | sw_if_index <nn> table <nn>") \
17541_(classify_set_interface_l2_tables, \
17542 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
17543 " [other-table <nn>]") \
17544_(get_node_index, "node <node-name") \
17545_(add_node_next, "node <node-name> next <next-node-name>") \
17546_(l2tpv3_create_tunnel, \
17547 "client_address <ip6-addr> our_address <ip6-addr>\n" \
17548 "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
17549 "[remote_cookie <nn>]\n[l2-sublayer-preset]\n") \
17550_(l2tpv3_set_tunnel_cookies, \
17551 "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n" \
17552 "[new_remote_cookie <nn>]\n") \
17553_(l2tpv3_interface_enable_disable, \
17554 "<intfc> | sw_if_index <nn> enable | disable") \
17555_(l2tpv3_set_lookup_key, \
17556 "lookup_v6_src | lookup_v6_dst | lookup_session_id") \
17557_(sw_if_l2tpv3_tunnel_dump, "") \
17558_(vxlan_add_del_tunnel, \
17559 "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n" \
17560 "{ <intfc> | mcast_sw_if_index <nn> } }\n" \
17561 "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]") \
17562_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
17563_(gre_add_del_tunnel, \
17564 "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n") \
17565_(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
17566_(l2_fib_clear_table, "") \
17567_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
17568_(l2_interface_vlan_tag_rewrite, \
17569 "<intfc> | sw_if_index <nn> \n" \
17570 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
17571 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
17572_(create_vhost_user_if, \
17573 "socket <filename> [server] [renumber <dev_instance>] " \
17574 "[mac <mac_address>]") \
17575_(modify_vhost_user_if, \
17576 "<intfc> | sw_if_index <nn> socket <filename>\n" \
17577 "[server] [renumber <dev_instance>]") \
17578_(delete_vhost_user_if, "<intfc> | sw_if_index <nn>") \
17579_(sw_interface_vhost_user_dump, "") \
17580_(show_version, "") \
17581_(vxlan_gpe_add_del_tunnel, \
17582 "local <addr> remote <addr> vni <nn>\n" \
17583 "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]" \
17584 "[next-ethernet] [next-nsh]\n") \
17585_(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
17586_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
17587_(interface_name_renumber, \
17588 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
17589_(input_acl_set_interface, \
17590 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
17591 " [l2-table <nn>] [del]") \
17592_(want_ip4_arp_events, "address <ip4-address> [del]") \
17593_(want_ip6_nd_events, "address <ip6-address> [del]") \
17594_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
17595_(ip_dump, "ipv4 | ipv6") \
17596_(ipsec_spd_add_del, "spd_id <n> [del]") \
17597_(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n" \
17598 " spid_id <n> ") \
17599_(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n" \
17600 " crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n" \
17601 " integ_alg <alg> integ_key <hex>") \
17602_(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n" \
17603 " (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n" \
17604 " laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
17605 " [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
17606_(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>") \
17607_(ikev2_profile_add_del, "name <profile_name> [del]") \
17608_(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n" \
17609 "(auth_data 0x<data> | auth_data <data>)") \
17610_(ikev2_profile_set_id, "name <profile_name> id_type <type>\n" \
17611 "(id_data 0x<data> | id_data <data>) (local|remote)") \
17612_(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n" \
17613 "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
17614 "(local|remote)") \
17615_(ikev2_set_local_key, "file <absolute_file_path>") \
17616_(delete_loopback,"sw_if_index <nn>") \
17617_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
17618_(map_add_domain, \
17619 "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> " \
17620 "ip6-src <ip6addr> " \
17621 "ea-bits-len <n> psid-offset <n> psid-len <n>") \
17622_(map_del_domain, "index <n>") \
17623_(map_add_del_rule, \
17624 "index <n> psid <n> dst <ip6addr> [del]") \
17625_(map_domain_dump, "") \
17626_(map_rule_dump, "index <map-domain>") \
17627_(want_interface_events, "enable|disable") \
17628_(want_stats,"enable|disable") \
17629_(get_first_msg_id, "client <name>") \
17630_(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
17631_(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n" \
17632 "fib-id <nn> [ip4][ip6][default]") \
17633_(get_node_graph, " ") \
17634_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
17635_(ioam_enable, "[trace] [pow] [ppc <encap|decap>]") \
17636_(ioam_disable, "") \
17637_(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
17638 " sw_if_index <sw_if_index> p <priority> " \
17639 "w <weight>] [del]") \
17640_(lisp_add_del_locator, "locator-set <locator_name> " \
17641 "iface <intf> | sw_if_index <sw_if_index> " \
17642 "p <priority> w <weight> [del]") \
17643_(lisp_add_del_local_eid,"vni <vni> eid " \
17644 "<ipv4|ipv6>/<prefix> | <L2 address> " \
17645 "locator-set <locator_name> [del]" \
17646 "[key-id sha1|sha256 secret-key <secret-key>]") \
17647_(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
17648 "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]") \
17649_(lisp_add_del_map_resolver, "<ip4|6-addr> [del]") \
17650_(lisp_add_del_map_server, "<ip4|6-addr> [del]") \
17651_(lisp_gpe_enable_disable, "enable|disable") \
17652_(lisp_enable_disable, "enable|disable") \
17653_(lisp_map_register_enable_disable, "enable|disable") \
17654_(lisp_rloc_probe_enable_disable, "enable|disable") \
17655_(lisp_gpe_add_del_iface, "up|down") \
17656_(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> " \
17657 "[seid <seid>] " \
17658 "rloc <locator> p <prio> " \
17659 "w <weight> [rloc <loc> ... ] " \
17660 "action <action> [del-all]") \
17661_(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid " \
17662 "<local-eid>") \
17663_(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del") \
17664_(lisp_map_request_mode, "src-dst|dst-only") \
17665_(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]") \
17666_(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>") \
17667_(lisp_locator_set_dump, "[local | remote]") \
17668_(lisp_locator_dump, "ls_index <index> | ls_name <name>") \
17669_(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] " \
17670 "[local] | [remote]") \
17671_(lisp_eid_table_vni_dump, "") \
17672_(lisp_eid_table_map_dump, "l2|l3") \
17673_(lisp_gpe_tunnel_dump, "") \
17674_(lisp_map_resolver_dump, "") \
17675_(lisp_map_server_dump, "") \
17676_(lisp_adjacencies_get, "vni <vni>") \
17677_(show_lisp_rloc_probe_state, "") \
17678_(show_lisp_map_register_state, "") \
17679_(show_lisp_status, "") \
17680_(lisp_get_map_request_itr_rlocs, "") \
17681_(show_lisp_pitr, "") \
17682_(show_lisp_map_request_mode, "") \
17683_(af_packet_create, "name <host interface name> [hw_addr <mac>]") \
17684_(af_packet_delete, "name <host interface name>") \
17685_(policer_add_del, "name <policer name> <params> [del]") \
17686_(policer_dump, "[name <policer name>]") \
17687_(policer_classify_set_interface, \
17688 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
17689 " [l2-table <nn>] [del]") \
17690_(policer_classify_dump, "type [ip4|ip6|l2]") \
17691_(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] " \
17692 "[master|slave]") \
17693_(netmap_delete, "name <interface name>") \
17694_(mpls_tunnel_dump, "tunnel_index <tunnel-id>") \
17695_(mpls_fib_dump, "") \
17696_(classify_table_ids, "") \
17697_(classify_table_by_interface, "sw_if_index <sw_if_index>") \
17698_(classify_table_info, "table_id <nn>") \
17699_(classify_session_dump, "table_id <nn>") \
17700_(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] " \
17701 "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] " \
17702 "[template_interval <nn>] [udp_checksum]") \
17703_(ipfix_exporter_dump, "") \
17704_(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17705_(ipfix_classify_stream_dump, "") \
17706_(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
17707_(ipfix_classify_table_dump, "") \
17708_(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
17709_(sw_interface_span_dump, "") \
17710_(get_next_index, "node-name <node-name> next-node-name <node-name>") \
17711_(pg_create_interface, "if_id <nn>") \
17712_(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]") \
17713_(pg_enable_disable, "[stream <id>] disable") \
17714_(ip_source_and_port_range_check_add_del, \
17715 "<ip-addr>/<mask> range <nn>-<nn> vrf <id>") \
17716_(ip_source_and_port_range_check_interface_add_del, \
17717 "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]" \
17718 "[udp-in-vrf <id>] [udp-out-vrf <id>]") \
17719_(ipsec_gre_add_del_tunnel, \
17720 "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]") \
17721_(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]") \
17722_(delete_subif,"<intfc> | sw_if_index <nn>") \
17723_(l2_interface_pbb_tag_rewrite, \
17724 "<intfc> | sw_if_index <nn> \n" \
17725 "[disable | push | pop | translate_pbb_stag <outer_tag>] \n" \
17726 "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]") \
17727_(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]") \
17728_(flow_classify_set_interface, \
17729 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17730_(flow_classify_dump, "type [ip4|ip6]") \
17731_(ip_fib_dump, "") \
17732_(ip6_fib_dump, "") \
17733_(feature_enable_disable, "arc_name <arc_name> " \
17734 "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]") \
17735_(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>" \
17736"[disable]") \
17737_(l2_xconnect_dump, "") \
17738_(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>") \
17739_(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>") \
17740_(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
17741
17742/* List of command functions, CLI names map directly to functions */
17743#define foreach_cli_function \
17744_(comment, "usage: comment <ignore-rest-of-line>") \
17745_(dump_interface_table, "usage: dump_interface_table") \
17746_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
17747_(dump_ipv4_table, "usage: dump_ipv4_table") \
17748_(dump_ipv6_table, "usage: dump_ipv6_table") \
17749_(dump_stats_table, "usage: dump_stats_table") \
17750_(dump_macro_table, "usage: dump_macro_table ") \
17751_(dump_node_table, "usage: dump_node_table") \
17752_(dump_msg_api_table, "usage: dump_msg_api_table") \
17753_(get_msg_id, "usage: get_msg_id name_and_crc") \
17754_(echo, "usage: echo <message>") \
17755_(exec, "usage: exec <vpe-debug-CLI-command>") \
17756_(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>") \
17757_(help, "usage: help") \
17758_(q, "usage: quit") \
17759_(quit, "usage: quit") \
17760_(search_node_table, "usage: search_node_table <name>...") \
17761_(set, "usage: set <variable-name> <value>") \
17762_(script, "usage: script <file-name>") \
17763_(unset, "usage: unset <variable-name>")
17764
17765#define _(N,n) \
17766 static void vl_api_##n##_t_handler_uni \
17767 (vl_api_##n##_t * mp) \
17768 { \
17769 vat_main_t * vam = &vat_main; \
17770 if (vam->json_output) { \
17771 vl_api_##n##_t_handler_json(mp); \
17772 } else { \
17773 vl_api_##n##_t_handler(mp); \
17774 } \
17775 }
17776foreach_vpe_api_reply_msg;
17777#undef _
17778
17779void
17780vat_api_hookup (vat_main_t * vam)
17781{
17782#define _(N,n) \
17783 vl_msg_api_set_handlers(VL_API_##N, #n, \
17784 vl_api_##n##_t_handler_uni, \
17785 vl_noop_handler, \
17786 vl_api_##n##_t_endian, \
17787 vl_api_##n##_t_print, \
17788 sizeof(vl_api_##n##_t), 1);
17789 foreach_vpe_api_reply_msg;
17790#undef _
17791
17792#if (VPP_API_TEST_BUILTIN==0)
17793 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17794#endif
17795
17796 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17797
17798 vam->function_by_name = hash_create_string (0, sizeof (uword));
17799
17800 vam->help_by_name = hash_create_string (0, sizeof (uword));
17801
17802 /* API messages we can send */
17803#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17804 foreach_vpe_api_msg;
17805#undef _
17806
17807 /* Help strings */
17808#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17809 foreach_vpe_api_msg;
17810#undef _
17811
17812 /* CLI functions */
17813#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17814 foreach_cli_function;
17815#undef _
17816
17817 /* Help strings */
17818#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17819 foreach_cli_function;
17820#undef _
17821}
17822
17823/*
17824 * fd.io coding-style-patch-verification: ON
17825 *
17826 * Local Variables:
17827 * eval: (c-set-style "gnu")
17828 * End:
17829 */