dpdk: Add support for Mellanox ConnectX-4 devices
[vpp.git] / src / vat / api_format.c
1 /*
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
73 static uword
74 api_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
91 void 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. */
95 uword
96 unformat_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
115 uword
116 unformat_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. */
137 uword
138 unformat_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. */
156 uword
157 unformat_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
247 uword
248 unformat_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
261 uword
262 unformat_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
275 u8 *
276 format_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
292 uword
293 unformat_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
306 u8 *
307 format_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
323 uword
324 unformat_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
337 uword
338 unformat_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
352 static uword
353 unformat_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
366 static uword
367 unformat_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
382 static uword
383 unformat_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
402 static uword
403 unformat_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
416 static uword
417 unformat_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
433 static uword
434 unformat_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
452 static uword
453 unformat_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)
470 u8 *
471 format_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
477 u8 *
478 format_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. */
528 u8 *
529 format_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
553 u8 *
554 format_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
563 static void
564 increment_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
572 static void
573 increment_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
587 static void
588 increment_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
598 static 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
610 static 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
626 static 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
638 static 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
655 static 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
667 static 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
684 static 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
696 static 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
713 static 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
724 static 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  */
744 static 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
783 static 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
832 static 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
843 static 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
849 static void
850 vl_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
860 static void
861 vl_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
890 static void
891 vl_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
901 static void
902 vl_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
918 static 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
945 static 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
967 static 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
985 static 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
1002 static 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
1020 static 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
1037 static 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
1055 static 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
1072 static 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
1089 static 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
1110 static void
1111 vl_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
1119 static void
1120 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1121 {
1122   /* JSON output not supported */
1123 }
1124
1125 static void
1126 vl_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
1134 static void
1135 vl_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  */
1144 static 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
1161 static 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  */
1189 static 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
1214 static 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
1235 static 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
1251 static 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
1275 static void
1276 vl_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
1291 static 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
1309 static 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
1325 static 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
1343 static 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
1361 static 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
1379 static void
1380 vl_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
1396 static 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
1413 static void
1414 vl_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
1429 static 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
1445 static 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
1461 static 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
1479 static 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
1496 static 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
1514 static 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
1530 static 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
1547 static 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
1564 static 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
1581 static 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
1598 static 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
1615 static 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
1632 static 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
1649 static 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
1682 static 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
1711 static void
1712 vl_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
1730 static void
1731 vl_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
1744 static 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
1780 static 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
1808 static 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
1829 static void
1830 vl_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
1837 static void
1838 vl_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
1848 static 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
1854 static void
1855 set_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
1868 static void
1869 set_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
1882 static void vl_api_vnet_interface_counters_t_handler
1883   (vl_api_vnet_interface_counters_t * mp)
1884 {
1885   /* not supported */
1886 }
1887
1888 static 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
1930 static u32
1931 ip4_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
1946 static u32
1947 ip6_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
1962 static void vl_api_vnet_ip4_fib_counters_t_handler
1963   (vl_api_vnet_ip4_fib_counters_t * mp)
1964 {
1965   /* not supported */
1966 }
1967
1968 static 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
2007 static void vl_api_vnet_ip6_fib_counters_t_handler
2008   (vl_api_vnet_ip6_fib_counters_t * mp)
2009 {
2010   /* not supported */
2011 }
2012
2013 static 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
2052 static 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
2073 static 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
2091 static 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
2153 static 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
2185 static void
2186 vl_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
2208 static void
2209 vl_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
2247 static void
2248 vl_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
2261 static 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
2286 static u8 *
2287 format_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
2305 static u8 *
2306 format_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
2323 static void
2324 vl_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
2352 static void
2353 vl_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
2395 static 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
2408 static 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
2427 static 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
2438 static 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
2455 static u8 *
2456 format_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
2474 static void
2475 vl_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
2504 static 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
2552 static 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
2565 static 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
2586 static 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");
2597 end:
2598   vam->retval = retval;
2599   vam->result_ready = 1;
2600 }
2601
2602 static 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
2622 static 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
2644 end:
2645   vam->retval = retval;
2646   vam->result_ready = 1;
2647 }
2648
2649 static 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
2688 end:
2689   vam->retval = retval;
2690   vam->result_ready = 1;
2691 }
2692
2693 static void
2694 vl_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
2704 static 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
2733 static void
2734 vl_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
2744 static 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
2773 static 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
2791 static 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
2820 static 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
2836 static 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
2860 static u8 *
2861 format_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
2875 static 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
2893 static 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
2916 static void
2917 vl_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
2933 static void
2934 vl_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
2961 static u8 *
2962 format_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
2981 static u8 *
2982 format_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
2995 static u8 *
2996 format_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
3011 static u8 *
3012 format_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
3027 static u8 *
3028 format_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
3045 static void
3046 vl_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
3101 static 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
3184 static void
3185 vl_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
3202 static 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
3225 static 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
3251 static 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
3271 static 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
3293 static 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. */
3312 u8 *
3313 format_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
3338 static void
3339 vl_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
3360 static 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
3392 static void
3393 vl_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
3405 static 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
3429 static 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
3438 static 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
3458 static 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
3467 static 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
3485 static 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
3502 static 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
3519 static 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
3528 static 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     }
3687 foreach_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     }
3702 foreach_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,                                \
3780 classify_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)                                          \
3930 do {                                                    \
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)                                               \
3939 do {                                                            \
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                                       \
3953 do {                                            \
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)                                \
3967 do {                                            \
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
3980 typedef 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
3991 static const char *
3992 str_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
4010 static int
4011 dump_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
4051 static int
4052 name_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
4060 static int
4061 dump_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
4093 static int
4094 dump_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
4127 static int
4128 dump_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
4140 static int
4141 dump_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
4153 static char *
4154 counter_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
4194 static int
4195 dump_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
4307 int
4308 exec (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  */
4378 static int
4379 exec_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
4413 static int
4414 api_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
4441 static int
4442 api_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
4471 static int
4472 api_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
4502 static int
4503 api_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 */
4537 int
4538 api_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
4643 static int
4644 api_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
4692 static int
4693 api_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
4727 static int
4728 api_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
4800 static int
4801 api_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
4881 static int
4882 api_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
4948 static int
4949 api_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
5025 static int
5026 api_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
5069 static int
5070 api_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
5114 static 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
5126 static 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
5143 static int
5144 api_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
5179 static int
5180 api_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
5223 static int
5224 api_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
5273 static int
5274 api_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
5346 static int
5347 api_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
5409 static int
5410 api_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
5442 static int
5443 api_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
5508 static int
5509 api_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
5655 static int
5656 api_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
5710 static int
5711 api_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
5762 static int
5763 api_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
5837 static int
5838 api_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
5905 static int
5906 api_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
5971 static int
5972 api_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
6009 static int
6010 api_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
6306 static int
6307 api_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
6527 static int
6528 api_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
6610 static int
6611 api_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
6656 static int
6657 api_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
6700 static int
6701 api_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
6787 static int
6788 api_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
6833 static int
6834 api_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
6928 static int
6929 api_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
6968 static int
6969 api_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
7027 static int
7028 api_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
7102 static int
7103 api_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
7156 static int
7157 api_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
7196 static int
7197 api_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
7291 static int
7292 api_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
7390 static int
7391 api_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
7454 static int
7455 api_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
7515 static int
7516 api_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
7579 static int
7580 api_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
7623 static int
7624 api_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
7679 static int
7680 api_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
7768 static int
7769 api_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
7865 static int
7866 api_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
7905 static int
7906 api_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
7976 static int
7977 api_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
8016 static int
8017 api_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
8028 static int
8029 api_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
8161 static int
8162 api_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
8245 static int
8246 api_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
8317 uword
8318 unformat_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
8358 uword
8359 unformat_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
8399 typedef struct
8400 {
8401   u16 src_port, dst_port;
8402 } tcpudp_header_t;
8403
8404 uword
8405 unformat_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
8440 uword
8441 unformat_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
8509 uword
8510 unformat_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
8580 uword
8581 unformat_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
8597 uword
8598 unformat_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
8707 uword
8708 unformat_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
8804 uword
8805 unformat_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
8824 out:
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
8834 uword
8835 unformat_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
8854 out:
8855   *miss_next_indexp = next_index;
8856   return 1;
8857 }
8858
8859 #define foreach_acl_next                        \
8860 _(deny, DENY)
8861
8862 uword
8863 unformat_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
8887 out:
8888   *miss_next_indexp = next_index;
8889   return 1;
8890 }
8891
8892 uword
8893 unformat_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
8907 static int
8908 api_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
9014 uword
9015 unformat_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
9045 uword
9046 unformat_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
9141 uword
9142 unformat_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
9230 uword
9231 unformat_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
9247 uword
9248 unformat_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
9263 uword
9264 unformat_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
9380 uword
9381 unformat_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
9450 static int
9451 api_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
9544 static int
9545 api_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
9589 static int
9590 api_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
9644 static int
9645 api_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
9710 static int
9711 api_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
9742 static int
9743 api_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
9804 static int
9805 api_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
9840 static int
9841 api_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
9890 static int
9891 api_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
9941 static int
9942 api_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
10010 static int
10011 api_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
10053 static int
10054 api_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
10094 static int
10095 api_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
10130 static 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
10155 static 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
10193 static int
10194 api_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
10213 static 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
10222 static 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
10240 static int
10241 api_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
10260 static 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
10275 static int
10276 api_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
10432 static 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
10450 static 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
10492 static int
10493 api_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
10538 static int
10539 api_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
10596 static 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
10608 static 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
10632 static int
10633 api_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
10678 static int
10679 api_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
10693 static int
10694 api_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
10748 static int
10749 api_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
10805 static int
10806 api_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
10875 static int
10876 api_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
10943 static int
10944 api_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
10979 static 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
10992 static 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
11019 static int
11020 api_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
11040 static int
11041 api_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
11055 static int
11056 api_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
11171 static 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
11185 static 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
11223 static int
11224 api_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
11269 u8 *
11270 format_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
11278 static 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
11290 static 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
11312 static int
11313 api_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
11354 static int
11355 api_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
11398 static int
11399 api_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
11433 static int
11434 api_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
11468 static int
11469 api_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
11522 static int
11523 api_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
11583 static int
11584 api_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
11639 static int
11640 api_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
11677 static int
11678 api_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
11731 static int
11732 api_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
11889 static int
11890 api_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
12052 static int
12053 api_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
12099 static int
12100 api_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
12147 static int
12148 api_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
12218 static int
12219 api_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
12298 static int
12299 api_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
12369 static int
12370 api_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  */
12414 static int
12415 api_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
12494 static int
12495 api_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
12533 static int
12534 api_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
12577 static int
12578 api_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
12598 static int
12599 api_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
12637 static 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
12654 static 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
12671 static int
12672 api_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
12709 static int
12710 api_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
12750 static int
12751 api_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
12799 static int
12800 api_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 */
12815 typedef 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
12822 static uword
12823 unformat_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
12854 static int
12855 lisp_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
12869 static void
12870 lisp_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 */
12877 typedef 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
12885 static int
12886 api_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
12972 static int
12973 api_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
13087 uword
13088 unformat_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
13112 static int
13113 api_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 */
13216 typedef 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
13225 static int
13226 api_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
13355 static int
13356 api_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
13423 static int
13424 api_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
13491 static int
13492 api_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
13538 static int
13539 api_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
13582 static int
13583 api_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
13626 static int
13627 api_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
13672 static int
13673 api_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
13689 static int
13690 api_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
13706 static int
13707 api_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
13723 static int
13724 api_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  */
13765 static int
13766 api_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
13811 static int
13812 api_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  */
13836 static int
13837 api_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
13889 uword
13890 unformat_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  */
13924 static int
13925 api_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  */
14051 static int
14052 api_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
14172 static int
14173 api_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  */
14246 static int
14247 api_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
14310 static int
14311 api_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
14389 static int
14390 api_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
14440 static int
14441 api_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
14499 static int
14500 api_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
14528 static int
14529 api_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
14629 static int
14630 api_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
14661 static int
14662 api_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
14707 static int
14708 api_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
14735 static int
14736 api_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
14763 static int
14764 api_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
14784 static int
14785 api_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
14805 static int
14806 api_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
14852 static int
14853 api_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
14891 static int
14892 api_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
14991 static int
14992 api_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
15031 static int
15032 api_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
15085 static int
15086 api_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
15124 static int
15125 api_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
15181 static int
15182 api_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
15220 static 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
15238 static 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
15269 static int
15270 api_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
15304 static void
15305 vl_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
15336 static 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
15382 static int
15383 api_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
15403 static void
15404 vl_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
15436 static 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
15483 static int
15484 api_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
15501 static 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
15513 static 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
15550 static int
15551 api_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
15595 static void
15596 vl_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
15628 static 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
15675 static int
15676 api_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
15693 int
15694 api_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
15709 int
15710 api_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
15743 int
15744 api_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
15775 int
15776 api_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
15813 static void
15814 vl_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
15831 static 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
15860 int
15861 api_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
15876 static int
15877 api_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
15892 static 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
15903 static 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
15920 static int
15921 api_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
15947 static 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
15956 static 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
15978 static int
15979 api_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
16025 static void
16026 vl_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
16058 static 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
16103 static int
16104 api_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
16121 int
16122 api_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
16153 int
16154 api_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
16212 int
16213 api_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
16259 int
16260 api_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
16391 int
16392 api_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
16461 static int
16462 api_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
16506 static int
16507 api_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
16547 static 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
16559 static 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
16583 static int
16584 api_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
16629 static int
16630 api_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
16666 static int
16667 api_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
16752 static int
16753 api_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
16802 static int
16803 api_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
16841 static int
16842 api_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
16908 static int
16909 api_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
16956 static 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
16965 static 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
16985 static int
16986 api_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
17009 static int
17010 api_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
17052 static int
17053 q_or_quit (vat_main_t * vam)
17054 {
17055   longjmp (vam->jump_buf, 1);
17056   return 0;                     /* not so much */
17057 }
17058
17059 static int
17060 q (vat_main_t * vam)
17061 {
17062   return q_or_quit (vam);
17063 }
17064
17065 static int
17066 quit (vat_main_t * vam)
17067 {
17068   return q_or_quit (vam);
17069 }
17070
17071 static int
17072 comment (vat_main_t * vam)
17073 {
17074   return 0;
17075 }
17076
17077 static int
17078 cmd_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
17086 static int
17087 help (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
17128 static int
17129 set (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
17155 static int
17156 unset (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
17167 typedef struct
17168 {
17169   u8 *name;
17170   u8 *value;
17171 } macro_sort_t;
17172
17173
17174 static int
17175 macro_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
17183 static int
17184 dump_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
17211 static int
17212 dump_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
17239 static int
17240 value_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
17253 static int
17254 dump_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
17278 static int
17279 get_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
17300 static int
17301 search_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
17354 static int
17355 script (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
17407 static int
17408 echo (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     }
17776 foreach_vpe_api_reply_msg;
17777 #undef _
17778
17779 void
17780 vat_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  */