Provision linux stack ip4 and ip6 addresses for tap interfaces
[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 void
2456   vl_api_show_lisp_map_register_state_reply_t_handler
2457   (vl_api_show_lisp_map_register_state_reply_t * mp)
2458 {
2459   vat_main_t *vam = &vat_main;
2460   int retval = clib_net_to_host_u32 (mp->retval);
2461
2462   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2463
2464   vam->retval = retval;
2465   vam->result_ready = 1;
2466 }
2467
2468 static void
2469   vl_api_show_lisp_map_register_state_reply_t_handler_json
2470   (vl_api_show_lisp_map_register_state_reply_t * mp)
2471 {
2472   vat_main_t *vam = &vat_main;
2473   vat_json_node_t _node, *node = &_node;
2474   int retval = clib_net_to_host_u32 (mp->retval);
2475
2476   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2477
2478   vat_json_init_object (node);
2479   vat_json_object_add_string_copy (node, "state", s);
2480
2481   vat_json_print (vam->ofp, node);
2482   vat_json_free (node);
2483
2484   vam->retval = retval;
2485   vam->result_ready = 1;
2486   vec_free (s);
2487 }
2488
2489 static void
2490   vl_api_show_lisp_rloc_probe_state_reply_t_handler
2491   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2492 {
2493   vat_main_t *vam = &vat_main;
2494   int retval = clib_net_to_host_u32 (mp->retval);
2495
2496   if (retval)
2497     goto end;
2498
2499   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2500 end:
2501   vam->retval = retval;
2502   vam->result_ready = 1;
2503 }
2504
2505 static void
2506   vl_api_show_lisp_rloc_probe_state_reply_t_handler_json
2507   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2508 {
2509   vat_main_t *vam = &vat_main;
2510   vat_json_node_t _node, *node = &_node;
2511   int retval = clib_net_to_host_u32 (mp->retval);
2512
2513   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2514   vat_json_init_object (node);
2515   vat_json_object_add_string_copy (node, "state", s);
2516
2517   vat_json_print (vam->ofp, node);
2518   vat_json_free (node);
2519
2520   vam->retval = retval;
2521   vam->result_ready = 1;
2522   vec_free (s);
2523 }
2524
2525 static void
2526   vl_api_lisp_adjacencies_get_reply_t_handler
2527   (vl_api_lisp_adjacencies_get_reply_t * mp)
2528 {
2529   vat_main_t *vam = &vat_main;
2530   u32 i, n;
2531   int retval = clib_net_to_host_u32 (mp->retval);
2532   vl_api_lisp_adjacency_t *a;
2533
2534   if (retval)
2535     goto end;
2536
2537   n = clib_net_to_host_u32 (mp->count);
2538
2539   for (i = 0; i < n; i++)
2540     {
2541       a = &mp->adjacencies[i];
2542       print (vam->ofp, "%U %40U",
2543              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2544              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2545     }
2546
2547 end:
2548   vam->retval = retval;
2549   vam->result_ready = 1;
2550 }
2551
2552 static void
2553   vl_api_lisp_adjacencies_get_reply_t_handler_json
2554   (vl_api_lisp_adjacencies_get_reply_t * mp)
2555 {
2556   u8 *s = 0;
2557   vat_main_t *vam = &vat_main;
2558   vat_json_node_t *e = 0, root;
2559   u32 i, n;
2560   int retval = clib_net_to_host_u32 (mp->retval);
2561   vl_api_lisp_adjacency_t *a;
2562
2563   if (retval)
2564     goto end;
2565
2566   n = clib_net_to_host_u32 (mp->count);
2567   vat_json_init_array (&root);
2568
2569   for (i = 0; i < n; i++)
2570     {
2571       e = vat_json_array_add (&root);
2572       a = &mp->adjacencies[i];
2573
2574       vat_json_init_object (e);
2575       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2576                   a->leid_prefix_len);
2577       vec_add1 (s, 0);
2578       vat_json_object_add_string_copy (e, "leid", s);
2579       vec_free (s);
2580
2581       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2582                   a->reid_prefix_len);
2583       vec_add1 (s, 0);
2584       vat_json_object_add_string_copy (e, "reid", s);
2585       vec_free (s);
2586     }
2587
2588   vat_json_print (vam->ofp, &root);
2589   vat_json_free (&root);
2590
2591 end:
2592   vam->retval = retval;
2593   vam->result_ready = 1;
2594 }
2595
2596 static void
2597 vl_api_lisp_map_server_details_t_handler (vl_api_lisp_map_server_details_t
2598                                           * mp)
2599 {
2600   vat_main_t *vam = &vat_main;
2601
2602   print (vam->ofp, "%=20U",
2603          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2604          mp->ip_address);
2605 }
2606
2607 static void
2608   vl_api_lisp_map_server_details_t_handler_json
2609   (vl_api_lisp_map_server_details_t * mp)
2610 {
2611   vat_main_t *vam = &vat_main;
2612   vat_json_node_t *node = NULL;
2613   struct in6_addr ip6;
2614   struct in_addr ip4;
2615
2616   if (VAT_JSON_ARRAY != vam->json_tree.type)
2617     {
2618       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2619       vat_json_init_array (&vam->json_tree);
2620     }
2621   node = vat_json_array_add (&vam->json_tree);
2622
2623   vat_json_init_object (node);
2624   if (mp->is_ipv6)
2625     {
2626       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2627       vat_json_object_add_ip6 (node, "map-server", ip6);
2628     }
2629   else
2630     {
2631       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2632       vat_json_object_add_ip4 (node, "map-server", ip4);
2633     }
2634 }
2635
2636 static void
2637 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2638                                             * mp)
2639 {
2640   vat_main_t *vam = &vat_main;
2641
2642   print (vam->ofp, "%=20U",
2643          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2644          mp->ip_address);
2645 }
2646
2647 static void
2648   vl_api_lisp_map_resolver_details_t_handler_json
2649   (vl_api_lisp_map_resolver_details_t * mp)
2650 {
2651   vat_main_t *vam = &vat_main;
2652   vat_json_node_t *node = NULL;
2653   struct in6_addr ip6;
2654   struct in_addr ip4;
2655
2656   if (VAT_JSON_ARRAY != vam->json_tree.type)
2657     {
2658       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2659       vat_json_init_array (&vam->json_tree);
2660     }
2661   node = vat_json_array_add (&vam->json_tree);
2662
2663   vat_json_init_object (node);
2664   if (mp->is_ipv6)
2665     {
2666       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2667       vat_json_object_add_ip6 (node, "map resolver", ip6);
2668     }
2669   else
2670     {
2671       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2672       vat_json_object_add_ip4 (node, "map resolver", ip4);
2673     }
2674 }
2675
2676 static void
2677   vl_api_show_lisp_status_reply_t_handler
2678   (vl_api_show_lisp_status_reply_t * mp)
2679 {
2680   vat_main_t *vam = &vat_main;
2681   i32 retval = ntohl (mp->retval);
2682
2683   if (0 <= retval)
2684     {
2685       print (vam->ofp, "feature: %s\ngpe: %s",
2686              mp->feature_status ? "enabled" : "disabled",
2687              mp->gpe_status ? "enabled" : "disabled");
2688     }
2689
2690   vam->retval = retval;
2691   vam->result_ready = 1;
2692 }
2693
2694 static void
2695   vl_api_show_lisp_status_reply_t_handler_json
2696   (vl_api_show_lisp_status_reply_t * mp)
2697 {
2698   vat_main_t *vam = &vat_main;
2699   vat_json_node_t node;
2700   u8 *gpe_status = NULL;
2701   u8 *feature_status = NULL;
2702
2703   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2704   feature_status = format (0, "%s",
2705                            mp->feature_status ? "enabled" : "disabled");
2706   vec_add1 (gpe_status, 0);
2707   vec_add1 (feature_status, 0);
2708
2709   vat_json_init_object (&node);
2710   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2711   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2712
2713   vec_free (gpe_status);
2714   vec_free (feature_status);
2715
2716   vat_json_print (vam->ofp, &node);
2717   vat_json_free (&node);
2718
2719   vam->retval = ntohl (mp->retval);
2720   vam->result_ready = 1;
2721 }
2722
2723 static void
2724   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2725   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2726 {
2727   vat_main_t *vam = &vat_main;
2728   i32 retval = ntohl (mp->retval);
2729
2730   if (retval >= 0)
2731     {
2732       print (vam->ofp, "%=20s", mp->locator_set_name);
2733     }
2734
2735   vam->retval = retval;
2736   vam->result_ready = 1;
2737 }
2738
2739 static void
2740   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2741   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2742 {
2743   vat_main_t *vam = &vat_main;
2744   vat_json_node_t *node = NULL;
2745
2746   if (VAT_JSON_ARRAY != vam->json_tree.type)
2747     {
2748       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2749       vat_json_init_array (&vam->json_tree);
2750     }
2751   node = vat_json_array_add (&vam->json_tree);
2752
2753   vat_json_init_object (node);
2754   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2755
2756   vat_json_print (vam->ofp, node);
2757   vat_json_free (node);
2758
2759   vam->retval = ntohl (mp->retval);
2760   vam->result_ready = 1;
2761 }
2762
2763 static u8 *
2764 format_lisp_map_request_mode (u8 * s, va_list * args)
2765 {
2766   u32 mode = va_arg (*args, u32);
2767
2768   switch (mode)
2769     {
2770     case 0:
2771       return format (0, "dst-only");
2772     case 1:
2773       return format (0, "src-dst");
2774     }
2775   return 0;
2776 }
2777
2778 static void
2779   vl_api_show_lisp_map_request_mode_reply_t_handler
2780   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2781 {
2782   vat_main_t *vam = &vat_main;
2783   i32 retval = ntohl (mp->retval);
2784
2785   if (0 <= retval)
2786     {
2787       u32 mode = mp->mode;
2788       print (vam->ofp, "map_request_mode: %U",
2789              format_lisp_map_request_mode, mode);
2790     }
2791
2792   vam->retval = retval;
2793   vam->result_ready = 1;
2794 }
2795
2796 static void
2797   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2798   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2799 {
2800   vat_main_t *vam = &vat_main;
2801   vat_json_node_t node;
2802   u8 *s = 0;
2803   u32 mode;
2804
2805   mode = mp->mode;
2806   s = format (0, "%U", format_lisp_map_request_mode, mode);
2807   vec_add1 (s, 0);
2808
2809   vat_json_init_object (&node);
2810   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2811   vat_json_print (vam->ofp, &node);
2812   vat_json_free (&node);
2813
2814   vec_free (s);
2815   vam->retval = ntohl (mp->retval);
2816   vam->result_ready = 1;
2817 }
2818
2819 static void
2820 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2821 {
2822   vat_main_t *vam = &vat_main;
2823   i32 retval = ntohl (mp->retval);
2824
2825   if (0 <= retval)
2826     {
2827       print (vam->ofp, "%-20s%-16s",
2828              mp->status ? "enabled" : "disabled",
2829              mp->status ? (char *) mp->locator_set_name : "");
2830     }
2831
2832   vam->retval = retval;
2833   vam->result_ready = 1;
2834 }
2835
2836 static void
2837 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2838                                             mp)
2839 {
2840   vat_main_t *vam = &vat_main;
2841   vat_json_node_t node;
2842   u8 *status = 0;
2843
2844   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2845   vec_add1 (status, 0);
2846
2847   vat_json_init_object (&node);
2848   vat_json_object_add_string_copy (&node, "status", status);
2849   if (mp->status)
2850     {
2851       vat_json_object_add_string_copy (&node, "locator_set",
2852                                        mp->locator_set_name);
2853     }
2854
2855   vec_free (status);
2856
2857   vat_json_print (vam->ofp, &node);
2858   vat_json_free (&node);
2859
2860   vam->retval = ntohl (mp->retval);
2861   vam->result_ready = 1;
2862 }
2863
2864 static u8 *
2865 format_policer_type (u8 * s, va_list * va)
2866 {
2867   u32 i = va_arg (*va, u32);
2868
2869   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2870     s = format (s, "1r2c");
2871   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2872     s = format (s, "1r3c");
2873   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2874     s = format (s, "2r3c-2698");
2875   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2876     s = format (s, "2r3c-4115");
2877   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2878     s = format (s, "2r3c-mef5cf1");
2879   else
2880     s = format (s, "ILLEGAL");
2881   return s;
2882 }
2883
2884 static u8 *
2885 format_policer_rate_type (u8 * s, va_list * va)
2886 {
2887   u32 i = va_arg (*va, u32);
2888
2889   if (i == SSE2_QOS_RATE_KBPS)
2890     s = format (s, "kbps");
2891   else if (i == SSE2_QOS_RATE_PPS)
2892     s = format (s, "pps");
2893   else
2894     s = format (s, "ILLEGAL");
2895   return s;
2896 }
2897
2898 static u8 *
2899 format_policer_round_type (u8 * s, va_list * va)
2900 {
2901   u32 i = va_arg (*va, u32);
2902
2903   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2904     s = format (s, "closest");
2905   else if (i == SSE2_QOS_ROUND_TO_UP)
2906     s = format (s, "up");
2907   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2908     s = format (s, "down");
2909   else
2910     s = format (s, "ILLEGAL");
2911   return s;
2912 }
2913
2914 static u8 *
2915 format_policer_action_type (u8 * s, va_list * va)
2916 {
2917   u32 i = va_arg (*va, u32);
2918
2919   if (i == SSE2_QOS_ACTION_DROP)
2920     s = format (s, "drop");
2921   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2922     s = format (s, "transmit");
2923   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2924     s = format (s, "mark-and-transmit");
2925   else
2926     s = format (s, "ILLEGAL");
2927   return s;
2928 }
2929
2930 static u8 *
2931 format_dscp (u8 * s, va_list * va)
2932 {
2933   u32 i = va_arg (*va, u32);
2934   char *t = 0;
2935
2936   switch (i)
2937     {
2938 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2939       foreach_vnet_dscp
2940 #undef _
2941     default:
2942       return format (s, "ILLEGAL");
2943     }
2944   s = format (s, "%s", t);
2945   return s;
2946 }
2947
2948 static void
2949 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2950 {
2951   vat_main_t *vam = &vat_main;
2952   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2953
2954   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2955     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2956   else
2957     conform_dscp_str = format (0, "");
2958
2959   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2960     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2961   else
2962     exceed_dscp_str = format (0, "");
2963
2964   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2965     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2966   else
2967     violate_dscp_str = format (0, "");
2968
2969   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2970          "rate type %U, round type %U, %s rate, %s color-aware, "
2971          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2972          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2973          "conform action %U%s, exceed action %U%s, violate action %U%s",
2974          mp->name,
2975          format_policer_type, mp->type,
2976          ntohl (mp->cir),
2977          ntohl (mp->eir),
2978          clib_net_to_host_u64 (mp->cb),
2979          clib_net_to_host_u64 (mp->eb),
2980          format_policer_rate_type, mp->rate_type,
2981          format_policer_round_type, mp->round_type,
2982          mp->single_rate ? "single" : "dual",
2983          mp->color_aware ? "is" : "not",
2984          ntohl (mp->cir_tokens_per_period),
2985          ntohl (mp->pir_tokens_per_period),
2986          ntohl (mp->scale),
2987          ntohl (mp->current_limit),
2988          ntohl (mp->current_bucket),
2989          ntohl (mp->extended_limit),
2990          ntohl (mp->extended_bucket),
2991          clib_net_to_host_u64 (mp->last_update_time),
2992          format_policer_action_type, mp->conform_action_type,
2993          conform_dscp_str,
2994          format_policer_action_type, mp->exceed_action_type,
2995          exceed_dscp_str,
2996          format_policer_action_type, mp->violate_action_type,
2997          violate_dscp_str);
2998
2999   vec_free (conform_dscp_str);
3000   vec_free (exceed_dscp_str);
3001   vec_free (violate_dscp_str);
3002 }
3003
3004 static void vl_api_policer_details_t_handler_json
3005   (vl_api_policer_details_t * mp)
3006 {
3007   vat_main_t *vam = &vat_main;
3008   vat_json_node_t *node;
3009   u8 *rate_type_str, *round_type_str, *type_str;
3010   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3011
3012   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3013   round_type_str =
3014     format (0, "%U", format_policer_round_type, mp->round_type);
3015   type_str = format (0, "%U", format_policer_type, mp->type);
3016   conform_action_str = format (0, "%U", format_policer_action_type,
3017                                mp->conform_action_type);
3018   exceed_action_str = format (0, "%U", format_policer_action_type,
3019                               mp->exceed_action_type);
3020   violate_action_str = format (0, "%U", format_policer_action_type,
3021                                mp->violate_action_type);
3022
3023   if (VAT_JSON_ARRAY != vam->json_tree.type)
3024     {
3025       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3026       vat_json_init_array (&vam->json_tree);
3027     }
3028   node = vat_json_array_add (&vam->json_tree);
3029
3030   vat_json_init_object (node);
3031   vat_json_object_add_string_copy (node, "name", mp->name);
3032   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3033   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3034   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3035   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3036   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3037   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3038   vat_json_object_add_string_copy (node, "type", type_str);
3039   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3040   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3041   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3042   vat_json_object_add_uint (node, "cir_tokens_per_period",
3043                             ntohl (mp->cir_tokens_per_period));
3044   vat_json_object_add_uint (node, "eir_tokens_per_period",
3045                             ntohl (mp->pir_tokens_per_period));
3046   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3047   vat_json_object_add_uint (node, "current_bucket",
3048                             ntohl (mp->current_bucket));
3049   vat_json_object_add_uint (node, "extended_limit",
3050                             ntohl (mp->extended_limit));
3051   vat_json_object_add_uint (node, "extended_bucket",
3052                             ntohl (mp->extended_bucket));
3053   vat_json_object_add_uint (node, "last_update_time",
3054                             ntohl (mp->last_update_time));
3055   vat_json_object_add_string_copy (node, "conform_action",
3056                                    conform_action_str);
3057   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3058     {
3059       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3060       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3061       vec_free (dscp_str);
3062     }
3063   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3064   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3065     {
3066       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3067       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3068       vec_free (dscp_str);
3069     }
3070   vat_json_object_add_string_copy (node, "violate_action",
3071                                    violate_action_str);
3072   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3073     {
3074       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3075       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3076       vec_free (dscp_str);
3077     }
3078
3079   vec_free (rate_type_str);
3080   vec_free (round_type_str);
3081   vec_free (type_str);
3082   vec_free (conform_action_str);
3083   vec_free (exceed_action_str);
3084   vec_free (violate_action_str);
3085 }
3086
3087 static void
3088 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3089                                            mp)
3090 {
3091   vat_main_t *vam = &vat_main;
3092   int i, count = ntohl (mp->count);
3093
3094   if (count > 0)
3095     print (vam->ofp, "classify table ids (%d) : ", count);
3096   for (i = 0; i < count; i++)
3097     {
3098       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3099       print (vam->ofp, (i < count - 1) ? "," : "");
3100     }
3101   vam->retval = ntohl (mp->retval);
3102   vam->result_ready = 1;
3103 }
3104
3105 static void
3106   vl_api_classify_table_ids_reply_t_handler_json
3107   (vl_api_classify_table_ids_reply_t * mp)
3108 {
3109   vat_main_t *vam = &vat_main;
3110   int i, count = ntohl (mp->count);
3111
3112   if (count > 0)
3113     {
3114       vat_json_node_t node;
3115
3116       vat_json_init_object (&node);
3117       for (i = 0; i < count; i++)
3118         {
3119           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3120         }
3121       vat_json_print (vam->ofp, &node);
3122       vat_json_free (&node);
3123     }
3124   vam->retval = ntohl (mp->retval);
3125   vam->result_ready = 1;
3126 }
3127
3128 static void
3129   vl_api_classify_table_by_interface_reply_t_handler
3130   (vl_api_classify_table_by_interface_reply_t * mp)
3131 {
3132   vat_main_t *vam = &vat_main;
3133   u32 table_id;
3134
3135   table_id = ntohl (mp->l2_table_id);
3136   if (table_id != ~0)
3137     print (vam->ofp, "l2 table id : %d", table_id);
3138   else
3139     print (vam->ofp, "l2 table id : No input ACL tables configured");
3140   table_id = ntohl (mp->ip4_table_id);
3141   if (table_id != ~0)
3142     print (vam->ofp, "ip4 table id : %d", table_id);
3143   else
3144     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3145   table_id = ntohl (mp->ip6_table_id);
3146   if (table_id != ~0)
3147     print (vam->ofp, "ip6 table id : %d", table_id);
3148   else
3149     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3150   vam->retval = ntohl (mp->retval);
3151   vam->result_ready = 1;
3152 }
3153
3154 static void
3155   vl_api_classify_table_by_interface_reply_t_handler_json
3156   (vl_api_classify_table_by_interface_reply_t * mp)
3157 {
3158   vat_main_t *vam = &vat_main;
3159   vat_json_node_t node;
3160
3161   vat_json_init_object (&node);
3162
3163   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3164   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3165   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3166
3167   vat_json_print (vam->ofp, &node);
3168   vat_json_free (&node);
3169
3170   vam->retval = ntohl (mp->retval);
3171   vam->result_ready = 1;
3172 }
3173
3174 static void vl_api_policer_add_del_reply_t_handler
3175   (vl_api_policer_add_del_reply_t * mp)
3176 {
3177   vat_main_t *vam = &vat_main;
3178   i32 retval = ntohl (mp->retval);
3179   if (vam->async_mode)
3180     {
3181       vam->async_errors += (retval < 0);
3182     }
3183   else
3184     {
3185       vam->retval = retval;
3186       vam->result_ready = 1;
3187       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3188         /*
3189          * Note: this is just barely thread-safe, depends on
3190          * the main thread spinning waiting for an answer...
3191          */
3192         errmsg ("policer index %d", ntohl (mp->policer_index));
3193     }
3194 }
3195
3196 static void vl_api_policer_add_del_reply_t_handler_json
3197   (vl_api_policer_add_del_reply_t * mp)
3198 {
3199   vat_main_t *vam = &vat_main;
3200   vat_json_node_t node;
3201
3202   vat_json_init_object (&node);
3203   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3204   vat_json_object_add_uint (&node, "policer_index",
3205                             ntohl (mp->policer_index));
3206
3207   vat_json_print (vam->ofp, &node);
3208   vat_json_free (&node);
3209
3210   vam->retval = ntohl (mp->retval);
3211   vam->result_ready = 1;
3212 }
3213
3214 /* Format hex dump. */
3215 u8 *
3216 format_hex_bytes (u8 * s, va_list * va)
3217 {
3218   u8 *bytes = va_arg (*va, u8 *);
3219   int n_bytes = va_arg (*va, int);
3220   uword i;
3221
3222   /* Print short or long form depending on byte count. */
3223   uword short_form = n_bytes <= 32;
3224   uword indent = format_get_indent (s);
3225
3226   if (n_bytes == 0)
3227     return s;
3228
3229   for (i = 0; i < n_bytes; i++)
3230     {
3231       if (!short_form && (i % 32) == 0)
3232         s = format (s, "%08x: ", i);
3233       s = format (s, "%02x", bytes[i]);
3234       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3235         s = format (s, "\n%U", format_white_space, indent);
3236     }
3237
3238   return s;
3239 }
3240
3241 static void
3242 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3243                                             * mp)
3244 {
3245   vat_main_t *vam = &vat_main;
3246   i32 retval = ntohl (mp->retval);
3247   if (retval == 0)
3248     {
3249       print (vam->ofp, "classify table info :");
3250       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3251              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3252              ntohl (mp->miss_next_index));
3253       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3254              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3255              ntohl (mp->match_n_vectors));
3256       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3257              ntohl (mp->mask_length));
3258     }
3259   vam->retval = retval;
3260   vam->result_ready = 1;
3261 }
3262
3263 static void
3264   vl_api_classify_table_info_reply_t_handler_json
3265   (vl_api_classify_table_info_reply_t * mp)
3266 {
3267   vat_main_t *vam = &vat_main;
3268   vat_json_node_t node;
3269
3270   i32 retval = ntohl (mp->retval);
3271   if (retval == 0)
3272     {
3273       vat_json_init_object (&node);
3274
3275       vat_json_object_add_int (&node, "sessions",
3276                                ntohl (mp->active_sessions));
3277       vat_json_object_add_int (&node, "nexttbl",
3278                                ntohl (mp->next_table_index));
3279       vat_json_object_add_int (&node, "nextnode",
3280                                ntohl (mp->miss_next_index));
3281       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3282       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3283       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3284       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3285                       ntohl (mp->mask_length), 0);
3286       vat_json_object_add_string_copy (&node, "mask", s);
3287
3288       vat_json_print (vam->ofp, &node);
3289       vat_json_free (&node);
3290     }
3291   vam->retval = ntohl (mp->retval);
3292   vam->result_ready = 1;
3293 }
3294
3295 static void
3296 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3297                                            mp)
3298 {
3299   vat_main_t *vam = &vat_main;
3300
3301   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3302          ntohl (mp->hit_next_index), ntohl (mp->advance),
3303          ntohl (mp->opaque_index));
3304   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3305          ntohl (mp->match_length));
3306 }
3307
3308 static void
3309   vl_api_classify_session_details_t_handler_json
3310   (vl_api_classify_session_details_t * mp)
3311 {
3312   vat_main_t *vam = &vat_main;
3313   vat_json_node_t *node = NULL;
3314
3315   if (VAT_JSON_ARRAY != vam->json_tree.type)
3316     {
3317       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3318       vat_json_init_array (&vam->json_tree);
3319     }
3320   node = vat_json_array_add (&vam->json_tree);
3321
3322   vat_json_init_object (node);
3323   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3324   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3325   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3326   u8 *s =
3327     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3328             0);
3329   vat_json_object_add_string_copy (node, "match", s);
3330 }
3331
3332 static void vl_api_pg_create_interface_reply_t_handler
3333   (vl_api_pg_create_interface_reply_t * mp)
3334 {
3335   vat_main_t *vam = &vat_main;
3336
3337   vam->retval = ntohl (mp->retval);
3338   vam->result_ready = 1;
3339 }
3340
3341 static void vl_api_pg_create_interface_reply_t_handler_json
3342   (vl_api_pg_create_interface_reply_t * mp)
3343 {
3344   vat_main_t *vam = &vat_main;
3345   vat_json_node_t node;
3346
3347   i32 retval = ntohl (mp->retval);
3348   if (retval == 0)
3349     {
3350       vat_json_init_object (&node);
3351
3352       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3353
3354       vat_json_print (vam->ofp, &node);
3355       vat_json_free (&node);
3356     }
3357   vam->retval = ntohl (mp->retval);
3358   vam->result_ready = 1;
3359 }
3360
3361 static void vl_api_policer_classify_details_t_handler
3362   (vl_api_policer_classify_details_t * mp)
3363 {
3364   vat_main_t *vam = &vat_main;
3365
3366   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3367          ntohl (mp->table_index));
3368 }
3369
3370 static void vl_api_policer_classify_details_t_handler_json
3371   (vl_api_policer_classify_details_t * mp)
3372 {
3373   vat_main_t *vam = &vat_main;
3374   vat_json_node_t *node;
3375
3376   if (VAT_JSON_ARRAY != vam->json_tree.type)
3377     {
3378       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3379       vat_json_init_array (&vam->json_tree);
3380     }
3381   node = vat_json_array_add (&vam->json_tree);
3382
3383   vat_json_init_object (node);
3384   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3385   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3386 }
3387
3388 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3389   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3390 {
3391   vat_main_t *vam = &vat_main;
3392   i32 retval = ntohl (mp->retval);
3393   if (vam->async_mode)
3394     {
3395       vam->async_errors += (retval < 0);
3396     }
3397   else
3398     {
3399       vam->retval = retval;
3400       vam->sw_if_index = ntohl (mp->sw_if_index);
3401       vam->result_ready = 1;
3402     }
3403 }
3404
3405 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3406   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3407 {
3408   vat_main_t *vam = &vat_main;
3409   vat_json_node_t node;
3410
3411   vat_json_init_object (&node);
3412   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3413   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3414
3415   vat_json_print (vam->ofp, &node);
3416   vat_json_free (&node);
3417
3418   vam->retval = ntohl (mp->retval);
3419   vam->result_ready = 1;
3420 }
3421
3422 static void vl_api_flow_classify_details_t_handler
3423   (vl_api_flow_classify_details_t * mp)
3424 {
3425   vat_main_t *vam = &vat_main;
3426
3427   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3428          ntohl (mp->table_index));
3429 }
3430
3431 static void vl_api_flow_classify_details_t_handler_json
3432   (vl_api_flow_classify_details_t * mp)
3433 {
3434   vat_main_t *vam = &vat_main;
3435   vat_json_node_t *node;
3436
3437   if (VAT_JSON_ARRAY != vam->json_tree.type)
3438     {
3439       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3440       vat_json_init_array (&vam->json_tree);
3441     }
3442   node = vat_json_array_add (&vam->json_tree);
3443
3444   vat_json_init_object (node);
3445   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3446   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3447 }
3448
3449
3450
3451 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3452 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3453 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3454 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3455 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3456 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3457
3458 /*
3459  * Generate boilerplate reply handlers, which
3460  * dig the return value out of the xxx_reply_t API message,
3461  * stick it into vam->retval, and set vam->result_ready
3462  *
3463  * Could also do this by pointing N message decode slots at
3464  * a single function, but that could break in subtle ways.
3465  */
3466
3467 #define foreach_standard_reply_retval_handler           \
3468 _(sw_interface_set_flags_reply)                         \
3469 _(sw_interface_add_del_address_reply)                   \
3470 _(sw_interface_set_table_reply)                         \
3471 _(sw_interface_set_mpls_enable_reply)                   \
3472 _(sw_interface_set_vpath_reply)                         \
3473 _(sw_interface_set_vxlan_bypass_reply)                  \
3474 _(sw_interface_set_l2_bridge_reply)                     \
3475 _(bridge_domain_add_del_reply)                          \
3476 _(sw_interface_set_l2_xconnect_reply)                   \
3477 _(l2fib_add_del_reply)                                  \
3478 _(ip_add_del_route_reply)                               \
3479 _(mpls_route_add_del_reply)                             \
3480 _(mpls_ip_bind_unbind_reply)                            \
3481 _(proxy_arp_add_del_reply)                              \
3482 _(proxy_arp_intfc_enable_disable_reply)                 \
3483 _(sw_interface_set_unnumbered_reply)                    \
3484 _(ip_neighbor_add_del_reply)                            \
3485 _(reset_vrf_reply)                                      \
3486 _(oam_add_del_reply)                                    \
3487 _(reset_fib_reply)                                      \
3488 _(dhcp_proxy_config_reply)                              \
3489 _(dhcp_proxy_config_2_reply)                            \
3490 _(dhcp_proxy_set_vss_reply)                             \
3491 _(dhcp_client_config_reply)                             \
3492 _(set_ip_flow_hash_reply)                               \
3493 _(sw_interface_ip6_enable_disable_reply)                \
3494 _(sw_interface_ip6_set_link_local_address_reply)        \
3495 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3496 _(sw_interface_ip6nd_ra_config_reply)                   \
3497 _(set_arp_neighbor_limit_reply)                         \
3498 _(l2_patch_add_del_reply)                               \
3499 _(sr_tunnel_add_del_reply)                              \
3500 _(sr_policy_add_del_reply)                              \
3501 _(sr_multicast_map_add_del_reply)                       \
3502 _(classify_add_del_session_reply)                       \
3503 _(classify_set_interface_ip_table_reply)                \
3504 _(classify_set_interface_l2_tables_reply)               \
3505 _(l2tpv3_set_tunnel_cookies_reply)                      \
3506 _(l2tpv3_interface_enable_disable_reply)                \
3507 _(l2tpv3_set_lookup_key_reply)                          \
3508 _(l2_fib_clear_table_reply)                             \
3509 _(l2_interface_efp_filter_reply)                        \
3510 _(l2_interface_vlan_tag_rewrite_reply)                  \
3511 _(modify_vhost_user_if_reply)                           \
3512 _(delete_vhost_user_if_reply)                           \
3513 _(want_ip4_arp_events_reply)                            \
3514 _(want_ip6_nd_events_reply)                             \
3515 _(input_acl_set_interface_reply)                        \
3516 _(ipsec_spd_add_del_reply)                              \
3517 _(ipsec_interface_add_del_spd_reply)                    \
3518 _(ipsec_spd_add_del_entry_reply)                        \
3519 _(ipsec_sad_add_del_entry_reply)                        \
3520 _(ipsec_sa_set_key_reply)                               \
3521 _(ikev2_profile_add_del_reply)                          \
3522 _(ikev2_profile_set_auth_reply)                         \
3523 _(ikev2_profile_set_id_reply)                           \
3524 _(ikev2_profile_set_ts_reply)                           \
3525 _(ikev2_set_local_key_reply)                            \
3526 _(delete_loopback_reply)                                \
3527 _(bd_ip_mac_add_del_reply)                              \
3528 _(map_del_domain_reply)                                 \
3529 _(map_add_del_rule_reply)                               \
3530 _(want_interface_events_reply)                          \
3531 _(want_stats_reply)                                     \
3532 _(cop_interface_enable_disable_reply)                   \
3533 _(cop_whitelist_enable_disable_reply)                   \
3534 _(sw_interface_clear_stats_reply)                       \
3535 _(ioam_enable_reply)                              \
3536 _(ioam_disable_reply)                              \
3537 _(lisp_add_del_locator_reply)                           \
3538 _(lisp_add_del_local_eid_reply)                         \
3539 _(lisp_add_del_remote_mapping_reply)                    \
3540 _(lisp_add_del_adjacency_reply)                         \
3541 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3542 _(lisp_add_del_map_resolver_reply)                      \
3543 _(lisp_add_del_map_server_reply)                        \
3544 _(lisp_gpe_enable_disable_reply)                        \
3545 _(lisp_gpe_add_del_iface_reply)                         \
3546 _(lisp_enable_disable_reply)                            \
3547 _(lisp_rloc_probe_enable_disable_reply)                 \
3548 _(lisp_map_register_enable_disable_reply)               \
3549 _(lisp_pitr_set_locator_set_reply)                      \
3550 _(lisp_map_request_mode_reply)                          \
3551 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3552 _(lisp_eid_table_add_del_map_reply)                     \
3553 _(vxlan_gpe_add_del_tunnel_reply)                       \
3554 _(af_packet_delete_reply)                               \
3555 _(policer_classify_set_interface_reply)                 \
3556 _(netmap_create_reply)                                  \
3557 _(netmap_delete_reply)                                  \
3558 _(set_ipfix_exporter_reply)                             \
3559 _(set_ipfix_classify_stream_reply)                      \
3560 _(ipfix_classify_table_add_del_reply)                   \
3561 _(flow_classify_set_interface_reply)                    \
3562 _(sw_interface_span_enable_disable_reply)               \
3563 _(pg_capture_reply)                                     \
3564 _(pg_enable_disable_reply)                              \
3565 _(ip_source_and_port_range_check_add_del_reply)         \
3566 _(ip_source_and_port_range_check_interface_add_del_reply)\
3567 _(delete_subif_reply)                                   \
3568 _(l2_interface_pbb_tag_rewrite_reply)                   \
3569 _(punt_reply)                                           \
3570 _(feature_enable_disable_reply)                         \
3571 _(sw_interface_tag_add_del_reply)                       \
3572 _(sw_interface_set_mtu_reply)
3573
3574 #if DPDK > 0
3575 #define foreach_standard_dpdk_reply_retval_handler      \
3576 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3577 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3578 _(sw_interface_set_dpdk_hqos_tctbl_reply)
3579 #endif
3580
3581 #define _(n)                                    \
3582     static void vl_api_##n##_t_handler          \
3583     (vl_api_##n##_t * mp)                       \
3584     {                                           \
3585         vat_main_t * vam = &vat_main;           \
3586         i32 retval = ntohl(mp->retval);         \
3587         if (vam->async_mode) {                  \
3588             vam->async_errors += (retval < 0);  \
3589         } else {                                \
3590             vam->retval = retval;               \
3591             vam->result_ready = 1;              \
3592         }                                       \
3593     }
3594 foreach_standard_reply_retval_handler;
3595 #undef _
3596
3597 #define _(n)                                    \
3598     static void vl_api_##n##_t_handler_json     \
3599     (vl_api_##n##_t * mp)                       \
3600     {                                           \
3601         vat_main_t * vam = &vat_main;           \
3602         vat_json_node_t node;                   \
3603         vat_json_init_object(&node);            \
3604         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3605         vat_json_print(vam->ofp, &node);        \
3606         vam->retval = ntohl(mp->retval);        \
3607         vam->result_ready = 1;                  \
3608     }
3609 foreach_standard_reply_retval_handler;
3610 #undef _
3611
3612 #if DPDK > 0
3613 #define _(n)                                    \
3614     static void vl_api_##n##_t_handler          \
3615     (vl_api_##n##_t * mp)                       \
3616     {                                           \
3617         vat_main_t * vam = &vat_main;           \
3618         i32 retval = ntohl(mp->retval);         \
3619         if (vam->async_mode) {                  \
3620             vam->async_errors += (retval < 0);  \
3621         } else {                                \
3622             vam->retval = retval;               \
3623             vam->result_ready = 1;              \
3624         }                                       \
3625     }
3626 foreach_standard_dpdk_reply_retval_handler;
3627 #undef _
3628
3629 #define _(n)                                    \
3630     static void vl_api_##n##_t_handler_json     \
3631     (vl_api_##n##_t * mp)                       \
3632     {                                           \
3633         vat_main_t * vam = &vat_main;           \
3634         vat_json_node_t node;                   \
3635         vat_json_init_object(&node);            \
3636         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3637         vat_json_print(vam->ofp, &node);        \
3638         vam->retval = ntohl(mp->retval);        \
3639         vam->result_ready = 1;                  \
3640     }
3641 foreach_standard_dpdk_reply_retval_handler;
3642 #undef _
3643 #endif
3644
3645 /*
3646  * Table of message reply handlers, must include boilerplate handlers
3647  * we just generated
3648  */
3649
3650 #define foreach_vpe_api_reply_msg                                       \
3651 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3652 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3653 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3654 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3655 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3656 _(CLI_REPLY, cli_reply)                                                 \
3657 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3658 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3659   sw_interface_add_del_address_reply)                                   \
3660 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3661 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3662 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3663 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3664 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3665   sw_interface_set_l2_xconnect_reply)                                   \
3666 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3667   sw_interface_set_l2_bridge_reply)                                     \
3668 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3669 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3670 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3671 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3672 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3673 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3674 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3675 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3676 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3677 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3678 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3679 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3680 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3681 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3682 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3683   proxy_arp_intfc_enable_disable_reply)                                 \
3684 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
3685 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3686   sw_interface_set_unnumbered_reply)                                    \
3687 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3688 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3689 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3690 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3691 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3692 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3693 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3694 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3695 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3696 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3697 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3698 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3699   sw_interface_ip6_enable_disable_reply)                                \
3700 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3701   sw_interface_ip6_set_link_local_address_reply)                        \
3702 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3703   sw_interface_ip6nd_ra_prefix_reply)                                   \
3704 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3705   sw_interface_ip6nd_ra_config_reply)                                   \
3706 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3707 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3708 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3709 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3710 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3711 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3712 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3713 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3714 classify_set_interface_ip_table_reply)                                  \
3715 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3716   classify_set_interface_l2_tables_reply)                               \
3717 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3718 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3719 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3720 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3721 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3722   l2tpv3_interface_enable_disable_reply)                                \
3723 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3724 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3725 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3726 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3727 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3728 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3729 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3730 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3731 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3732 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3733 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3734 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3735 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3736 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3737 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3738 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3739 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3740 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3741 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3742 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3743 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3744 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3745 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3746 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3747 _(IP_DETAILS, ip_details)                                               \
3748 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3749 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3750 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3751 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3752 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3753 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3754 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3755 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3756 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3757 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3758 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3759 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3760 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3761 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3762 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3763 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3764 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3765 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3766 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3767 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3768 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3769 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3770 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3771 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3772 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3773 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3774 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3775 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3776 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3777 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3778 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3779 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3780 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3781 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3782 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3783 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3784 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3785 _(LISP_ADD_DEL_MAP_SERVER_REPLY, lisp_add_del_map_server_reply)         \
3786 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3787 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3788 _(LISP_MAP_REGISTER_ENABLE_DISABLE_REPLY,                               \
3789   lisp_map_register_enable_disable_reply)                               \
3790 _(LISP_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                 \
3791   lisp_rloc_probe_enable_disable_reply)                                 \
3792 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3793 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3794 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3795 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3796 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3797 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3798 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3799 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3800 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3801 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3802 _(LISP_MAP_SERVER_DETAILS, lisp_map_server_details)                     \
3803 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3804 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3805 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3806   lisp_add_del_map_request_itr_rlocs_reply)                             \
3807 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3808   lisp_get_map_request_itr_rlocs_reply)                                 \
3809 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3810 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3811 _(SHOW_LISP_RLOC_PROBE_STATE_REPLY, show_lisp_rloc_probe_state_reply)   \
3812 _(SHOW_LISP_MAP_REGISTER_STATE_REPLY,                                   \
3813   show_lisp_map_register_state_reply)                                   \
3814 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3815 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3816 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3817 _(POLICER_DETAILS, policer_details)                                     \
3818 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3819 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3820 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3821 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3822 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
3823 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3824 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3825 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3826 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3827 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3828 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3829 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3830 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3831 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3832 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3833 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3834 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3835 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3836 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3837 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3838 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3839 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3840 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3841 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3842 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3843  ip_source_and_port_range_check_add_del_reply)                          \
3844 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3845  ip_source_and_port_range_check_interface_add_del_reply)                \
3846 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3847 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3848 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3849 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3850 _(PUNT_REPLY, punt_reply)                                               \
3851 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3852 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
3853 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
3854 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
3855 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
3856 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
3857 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
3858 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
3859
3860 #if DPDK > 0
3861 #define foreach_vpe_dpdk_api_reply_msg                                  \
3862 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3863   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3864 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3865   sw_interface_set_dpdk_hqos_subport_reply)                             \
3866 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3867   sw_interface_set_dpdk_hqos_tctbl_reply)
3868 #endif
3869
3870 /* M: construct, but don't yet send a message */
3871
3872 #define M(T,t)                                          \
3873 do {                                                    \
3874     vam->result_ready = 0;                              \
3875     mp = vl_msg_api_alloc_as_if_client(sizeof(*mp));    \
3876     memset (mp, 0, sizeof (*mp));                       \
3877     mp->_vl_msg_id = ntohs (VL_API_##T);                \
3878     mp->client_index = vam->my_client_index;            \
3879 } while(0);
3880
3881 #define M2(T,t,n)                                               \
3882 do {                                                            \
3883     vam->result_ready = 0;                                      \
3884     mp = vl_msg_api_alloc_as_if_client(sizeof(*mp)+(n));        \
3885     memset (mp, 0, sizeof (*mp));                               \
3886     mp->_vl_msg_id = ntohs (VL_API_##T);                        \
3887     mp->client_index = vam->my_client_index;                    \
3888 } while(0);
3889
3890
3891 /* S: send a message */
3892 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3893
3894 /* W: wait for results, with timeout */
3895 #define W                                       \
3896 do {                                            \
3897     timeout = vat_time_now (vam) + 1.0;         \
3898                                                 \
3899     while (vat_time_now (vam) < timeout) {      \
3900         if (vam->result_ready == 1) {           \
3901             return (vam->retval);               \
3902         }                                       \
3903         vat_suspend (vam->vlib_main, 1e-3);     \
3904     }                                           \
3905     return -99;                                 \
3906 } while(0);
3907
3908 /* W2: wait for results, with timeout */
3909 #define W2(body)                                \
3910 do {                                            \
3911     timeout = vat_time_now (vam) + 1.0;         \
3912                                                 \
3913     while (vat_time_now (vam) < timeout) {      \
3914         if (vam->result_ready == 1) {           \
3915           (body);                               \
3916           return (vam->retval);                 \
3917         }                                       \
3918         vat_suspend (vam->vlib_main, 1e-3);     \
3919     }                                           \
3920     return -99;                                 \
3921 } while(0);
3922
3923 typedef struct
3924 {
3925   u8 *name;
3926   u32 value;
3927 } name_sort_t;
3928
3929
3930 #define STR_VTR_OP_CASE(op)     \
3931     case L2_VTR_ ## op:         \
3932         return "" # op;
3933
3934 static const char *
3935 str_vtr_op (u32 vtr_op)
3936 {
3937   switch (vtr_op)
3938     {
3939       STR_VTR_OP_CASE (DISABLED);
3940       STR_VTR_OP_CASE (PUSH_1);
3941       STR_VTR_OP_CASE (PUSH_2);
3942       STR_VTR_OP_CASE (POP_1);
3943       STR_VTR_OP_CASE (POP_2);
3944       STR_VTR_OP_CASE (TRANSLATE_1_1);
3945       STR_VTR_OP_CASE (TRANSLATE_1_2);
3946       STR_VTR_OP_CASE (TRANSLATE_2_1);
3947       STR_VTR_OP_CASE (TRANSLATE_2_2);
3948     }
3949
3950   return "UNKNOWN";
3951 }
3952
3953 static int
3954 dump_sub_interface_table (vat_main_t * vam)
3955 {
3956   const sw_interface_subif_t *sub = NULL;
3957
3958   if (vam->json_output)
3959     {
3960       clib_warning
3961         ("JSON output supported only for VPE API calls and dump_stats_table");
3962       return -99;
3963     }
3964
3965   print (vam->ofp,
3966          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
3967          "Interface", "sw_if_index",
3968          "sub id", "dot1ad", "tags", "outer id",
3969          "inner id", "exact", "default", "outer any", "inner any");
3970
3971   vec_foreach (sub, vam->sw_if_subif_table)
3972   {
3973     print (vam->ofp,
3974            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
3975            sub->interface_name,
3976            sub->sw_if_index,
3977            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3978            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3979            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3980            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3981     if (sub->vtr_op != L2_VTR_DISABLED)
3982       {
3983         print (vam->ofp,
3984                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3985                "tag1: %d tag2: %d ]",
3986                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3987                sub->vtr_tag1, sub->vtr_tag2);
3988       }
3989   }
3990
3991   return 0;
3992 }
3993
3994 static int
3995 name_sort_cmp (void *a1, void *a2)
3996 {
3997   name_sort_t *n1 = a1;
3998   name_sort_t *n2 = a2;
3999
4000   return strcmp ((char *) n1->name, (char *) n2->name);
4001 }
4002
4003 static int
4004 dump_interface_table (vat_main_t * vam)
4005 {
4006   hash_pair_t *p;
4007   name_sort_t *nses = 0, *ns;
4008
4009   if (vam->json_output)
4010     {
4011       clib_warning
4012         ("JSON output supported only for VPE API calls and dump_stats_table");
4013       return -99;
4014     }
4015
4016   /* *INDENT-OFF* */
4017   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4018   ({
4019     vec_add2 (nses, ns, 1);
4020     ns->name = (u8 *)(p->key);
4021     ns->value = (u32) p->value[0];
4022   }));
4023   /* *INDENT-ON* */
4024
4025   vec_sort_with_function (nses, name_sort_cmp);
4026
4027   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4028   vec_foreach (ns, nses)
4029   {
4030     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4031   }
4032   vec_free (nses);
4033   return 0;
4034 }
4035
4036 static int
4037 dump_ip_table (vat_main_t * vam, int is_ipv6)
4038 {
4039   const ip_details_t *det = NULL;
4040   const ip_address_details_t *address = NULL;
4041   u32 i = ~0;
4042
4043   print (vam->ofp, "%-12s", "sw_if_index");
4044
4045   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4046   {
4047     i++;
4048     if (!det->present)
4049       {
4050         continue;
4051       }
4052     print (vam->ofp, "%-12d", i);
4053     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4054     if (!det->addr)
4055       {
4056         continue;
4057       }
4058     vec_foreach (address, det->addr)
4059     {
4060       print (vam->ofp,
4061              "            %-30U%-13d",
4062              is_ipv6 ? format_ip6_address : format_ip4_address,
4063              address->ip, address->prefix_length);
4064     }
4065   }
4066
4067   return 0;
4068 }
4069
4070 static int
4071 dump_ipv4_table (vat_main_t * vam)
4072 {
4073   if (vam->json_output)
4074     {
4075       clib_warning
4076         ("JSON output supported only for VPE API calls and dump_stats_table");
4077       return -99;
4078     }
4079
4080   return dump_ip_table (vam, 0);
4081 }
4082
4083 static int
4084 dump_ipv6_table (vat_main_t * vam)
4085 {
4086   if (vam->json_output)
4087     {
4088       clib_warning
4089         ("JSON output supported only for VPE API calls and dump_stats_table");
4090       return -99;
4091     }
4092
4093   return dump_ip_table (vam, 1);
4094 }
4095
4096 static char *
4097 counter_type_to_str (u8 counter_type, u8 is_combined)
4098 {
4099   if (!is_combined)
4100     {
4101       switch (counter_type)
4102         {
4103         case VNET_INTERFACE_COUNTER_DROP:
4104           return "drop";
4105         case VNET_INTERFACE_COUNTER_PUNT:
4106           return "punt";
4107         case VNET_INTERFACE_COUNTER_IP4:
4108           return "ip4";
4109         case VNET_INTERFACE_COUNTER_IP6:
4110           return "ip6";
4111         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4112           return "rx-no-buf";
4113         case VNET_INTERFACE_COUNTER_RX_MISS:
4114           return "rx-miss";
4115         case VNET_INTERFACE_COUNTER_RX_ERROR:
4116           return "rx-error";
4117         case VNET_INTERFACE_COUNTER_TX_ERROR:
4118           return "tx-error";
4119         default:
4120           return "INVALID-COUNTER-TYPE";
4121         }
4122     }
4123   else
4124     {
4125       switch (counter_type)
4126         {
4127         case VNET_INTERFACE_COUNTER_RX:
4128           return "rx";
4129         case VNET_INTERFACE_COUNTER_TX:
4130           return "tx";
4131         default:
4132           return "INVALID-COUNTER-TYPE";
4133         }
4134     }
4135 }
4136
4137 static int
4138 dump_stats_table (vat_main_t * vam)
4139 {
4140   vat_json_node_t node;
4141   vat_json_node_t *msg_array;
4142   vat_json_node_t *msg;
4143   vat_json_node_t *counter_array;
4144   vat_json_node_t *counter;
4145   interface_counter_t c;
4146   u64 packets;
4147   ip4_fib_counter_t *c4;
4148   ip6_fib_counter_t *c6;
4149   int i, j;
4150
4151   if (!vam->json_output)
4152     {
4153       clib_warning ("dump_stats_table supported only in JSON format");
4154       return -99;
4155     }
4156
4157   vat_json_init_object (&node);
4158
4159   /* interface counters */
4160   msg_array = vat_json_object_add (&node, "interface_counters");
4161   vat_json_init_array (msg_array);
4162   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4163     {
4164       msg = vat_json_array_add (msg_array);
4165       vat_json_init_object (msg);
4166       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4167                                        (u8 *) counter_type_to_str (i, 0));
4168       vat_json_object_add_int (msg, "is_combined", 0);
4169       counter_array = vat_json_object_add (msg, "data");
4170       vat_json_init_array (counter_array);
4171       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4172         {
4173           packets = vam->simple_interface_counters[i][j];
4174           vat_json_array_add_uint (counter_array, packets);
4175         }
4176     }
4177   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4178     {
4179       msg = vat_json_array_add (msg_array);
4180       vat_json_init_object (msg);
4181       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4182                                        (u8 *) counter_type_to_str (i, 1));
4183       vat_json_object_add_int (msg, "is_combined", 1);
4184       counter_array = vat_json_object_add (msg, "data");
4185       vat_json_init_array (counter_array);
4186       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4187         {
4188           c = vam->combined_interface_counters[i][j];
4189           counter = vat_json_array_add (counter_array);
4190           vat_json_init_object (counter);
4191           vat_json_object_add_uint (counter, "packets", c.packets);
4192           vat_json_object_add_uint (counter, "bytes", c.bytes);
4193         }
4194     }
4195
4196   /* ip4 fib counters */
4197   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4198   vat_json_init_array (msg_array);
4199   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4200     {
4201       msg = vat_json_array_add (msg_array);
4202       vat_json_init_object (msg);
4203       vat_json_object_add_uint (msg, "vrf_id",
4204                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4205       counter_array = vat_json_object_add (msg, "c");
4206       vat_json_init_array (counter_array);
4207       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4208         {
4209           counter = vat_json_array_add (counter_array);
4210           vat_json_init_object (counter);
4211           c4 = &vam->ip4_fib_counters[i][j];
4212           vat_json_object_add_ip4 (counter, "address", c4->address);
4213           vat_json_object_add_uint (counter, "address_length",
4214                                     c4->address_length);
4215           vat_json_object_add_uint (counter, "packets", c4->packets);
4216           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4217         }
4218     }
4219
4220   /* ip6 fib counters */
4221   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4222   vat_json_init_array (msg_array);
4223   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4224     {
4225       msg = vat_json_array_add (msg_array);
4226       vat_json_init_object (msg);
4227       vat_json_object_add_uint (msg, "vrf_id",
4228                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4229       counter_array = vat_json_object_add (msg, "c");
4230       vat_json_init_array (counter_array);
4231       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4232         {
4233           counter = vat_json_array_add (counter_array);
4234           vat_json_init_object (counter);
4235           c6 = &vam->ip6_fib_counters[i][j];
4236           vat_json_object_add_ip6 (counter, "address", c6->address);
4237           vat_json_object_add_uint (counter, "address_length",
4238                                     c6->address_length);
4239           vat_json_object_add_uint (counter, "packets", c6->packets);
4240           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4241         }
4242     }
4243
4244   vat_json_print (vam->ofp, &node);
4245   vat_json_free (&node);
4246
4247   return 0;
4248 }
4249
4250 int
4251 exec (vat_main_t * vam)
4252 {
4253   api_main_t *am = &api_main;
4254   vl_api_cli_request_t *mp;
4255   f64 timeout;
4256   void *oldheap;
4257   u8 *cmd = 0;
4258   unformat_input_t *i = vam->input;
4259
4260   if (vec_len (i->buffer) == 0)
4261     return -1;
4262
4263   if (vam->exec_mode == 0 && unformat (i, "mode"))
4264     {
4265       vam->exec_mode = 1;
4266       return 0;
4267     }
4268   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4269     {
4270       vam->exec_mode = 0;
4271       return 0;
4272     }
4273
4274
4275   M (CLI_REQUEST, cli_request);
4276
4277   /*
4278    * Copy cmd into shared memory.
4279    * In order for the CLI command to work, it
4280    * must be a vector ending in \n, not a C-string ending
4281    * in \n\0.
4282    */
4283   pthread_mutex_lock (&am->vlib_rp->mutex);
4284   oldheap = svm_push_data_heap (am->vlib_rp);
4285
4286   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4287   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4288
4289   svm_pop_heap (oldheap);
4290   pthread_mutex_unlock (&am->vlib_rp->mutex);
4291
4292   mp->cmd_in_shmem = (u64) cmd;
4293   S;
4294   timeout = vat_time_now (vam) + 10.0;
4295
4296   while (vat_time_now (vam) < timeout)
4297     {
4298       if (vam->result_ready == 1)
4299         {
4300           u8 *free_me;
4301           if (vam->shmem_result != NULL)
4302             print (vam->ofp, "%s", vam->shmem_result);
4303           pthread_mutex_lock (&am->vlib_rp->mutex);
4304           oldheap = svm_push_data_heap (am->vlib_rp);
4305
4306           free_me = (u8 *) vam->shmem_result;
4307           vec_free (free_me);
4308
4309           svm_pop_heap (oldheap);
4310           pthread_mutex_unlock (&am->vlib_rp->mutex);
4311           return 0;
4312         }
4313     }
4314   return -99;
4315 }
4316
4317 /*
4318  * Future replacement of exec() that passes CLI buffers directly in
4319  * the API messages instead of an additional shared memory area.
4320  */
4321 static int
4322 exec_inband (vat_main_t * vam)
4323 {
4324   vl_api_cli_inband_t *mp;
4325   f64 timeout;
4326   unformat_input_t *i = vam->input;
4327
4328   if (vec_len (i->buffer) == 0)
4329     return -1;
4330
4331   if (vam->exec_mode == 0 && unformat (i, "mode"))
4332     {
4333       vam->exec_mode = 1;
4334       return 0;
4335     }
4336   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4337     {
4338       vam->exec_mode = 0;
4339       return 0;
4340     }
4341
4342   /*
4343    * In order for the CLI command to work, it
4344    * must be a vector ending in \n, not a C-string ending
4345    * in \n\0.
4346    */
4347   u32 len = vec_len (vam->input->buffer);
4348   M2 (CLI_INBAND, cli_inband, len);
4349   clib_memcpy (mp->cmd, vam->input->buffer, len);
4350   mp->length = htonl (len);
4351
4352   S;
4353   W2 (print (vam->ofp, "%s", vam->cmd_reply));
4354 }
4355
4356 static int
4357 api_create_loopback (vat_main_t * vam)
4358 {
4359   unformat_input_t *i = vam->input;
4360   vl_api_create_loopback_t *mp;
4361   f64 timeout;
4362   u8 mac_address[6];
4363   u8 mac_set = 0;
4364
4365   memset (mac_address, 0, sizeof (mac_address));
4366
4367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4368     {
4369       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4370         mac_set = 1;
4371       else
4372         break;
4373     }
4374
4375   /* Construct the API message */
4376   M (CREATE_LOOPBACK, create_loopback);
4377   if (mac_set)
4378     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4379
4380   S;
4381   W;
4382 }
4383
4384 static int
4385 api_delete_loopback (vat_main_t * vam)
4386 {
4387   unformat_input_t *i = vam->input;
4388   vl_api_delete_loopback_t *mp;
4389   f64 timeout;
4390   u32 sw_if_index = ~0;
4391
4392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4393     {
4394       if (unformat (i, "sw_if_index %d", &sw_if_index))
4395         ;
4396       else
4397         break;
4398     }
4399
4400   if (sw_if_index == ~0)
4401     {
4402       errmsg ("missing sw_if_index");
4403       return -99;
4404     }
4405
4406   /* Construct the API message */
4407   M (DELETE_LOOPBACK, delete_loopback);
4408   mp->sw_if_index = ntohl (sw_if_index);
4409
4410   S;
4411   W;
4412 }
4413
4414 static int
4415 api_want_stats (vat_main_t * vam)
4416 {
4417   unformat_input_t *i = vam->input;
4418   vl_api_want_stats_t *mp;
4419   f64 timeout;
4420   int enable = -1;
4421
4422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4423     {
4424       if (unformat (i, "enable"))
4425         enable = 1;
4426       else if (unformat (i, "disable"))
4427         enable = 0;
4428       else
4429         break;
4430     }
4431
4432   if (enable == -1)
4433     {
4434       errmsg ("missing enable|disable");
4435       return -99;
4436     }
4437
4438   M (WANT_STATS, want_stats);
4439   mp->enable_disable = enable;
4440
4441   S;
4442   W;
4443 }
4444
4445 static int
4446 api_want_interface_events (vat_main_t * vam)
4447 {
4448   unformat_input_t *i = vam->input;
4449   vl_api_want_interface_events_t *mp;
4450   f64 timeout;
4451   int enable = -1;
4452
4453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4454     {
4455       if (unformat (i, "enable"))
4456         enable = 1;
4457       else if (unformat (i, "disable"))
4458         enable = 0;
4459       else
4460         break;
4461     }
4462
4463   if (enable == -1)
4464     {
4465       errmsg ("missing enable|disable");
4466       return -99;
4467     }
4468
4469   M (WANT_INTERFACE_EVENTS, want_interface_events);
4470   mp->enable_disable = enable;
4471
4472   vam->interface_event_display = enable;
4473
4474   S;
4475   W;
4476 }
4477
4478
4479 /* Note: non-static, called once to set up the initial intfc table */
4480 int
4481 api_sw_interface_dump (vat_main_t * vam)
4482 {
4483   vl_api_sw_interface_dump_t *mp;
4484   f64 timeout;
4485   hash_pair_t *p;
4486   name_sort_t *nses = 0, *ns;
4487   sw_interface_subif_t *sub = NULL;
4488
4489   /* Toss the old name table */
4490   /* *INDENT-OFF* */
4491   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4492   ({
4493     vec_add2 (nses, ns, 1);
4494     ns->name = (u8 *)(p->key);
4495     ns->value = (u32) p->value[0];
4496   }));
4497   /* *INDENT-ON* */
4498
4499   hash_free (vam->sw_if_index_by_interface_name);
4500
4501   vec_foreach (ns, nses) vec_free (ns->name);
4502
4503   vec_free (nses);
4504
4505   vec_foreach (sub, vam->sw_if_subif_table)
4506   {
4507     vec_free (sub->interface_name);
4508   }
4509   vec_free (vam->sw_if_subif_table);
4510
4511   /* recreate the interface name hash table */
4512   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4513
4514   /* Get list of ethernets */
4515   M (SW_INTERFACE_DUMP, sw_interface_dump);
4516   mp->name_filter_valid = 1;
4517   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4518   S;
4519
4520   /* and local / loopback interfaces */
4521   M (SW_INTERFACE_DUMP, sw_interface_dump);
4522   mp->name_filter_valid = 1;
4523   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4524   S;
4525
4526   /* and packet-generator interfaces */
4527   M (SW_INTERFACE_DUMP, sw_interface_dump);
4528   mp->name_filter_valid = 1;
4529   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4530   S;
4531
4532   /* and vxlan-gpe tunnel interfaces */
4533   M (SW_INTERFACE_DUMP, sw_interface_dump);
4534   mp->name_filter_valid = 1;
4535   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4536            sizeof (mp->name_filter) - 1);
4537   S;
4538
4539   /* and vxlan tunnel interfaces */
4540   M (SW_INTERFACE_DUMP, sw_interface_dump);
4541   mp->name_filter_valid = 1;
4542   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4543   S;
4544
4545   /* and host (af_packet) interfaces */
4546   M (SW_INTERFACE_DUMP, sw_interface_dump);
4547   mp->name_filter_valid = 1;
4548   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4549   S;
4550
4551   /* and l2tpv3 tunnel interfaces */
4552   M (SW_INTERFACE_DUMP, sw_interface_dump);
4553   mp->name_filter_valid = 1;
4554   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4555            sizeof (mp->name_filter) - 1);
4556   S;
4557
4558   /* and GRE tunnel interfaces */
4559   M (SW_INTERFACE_DUMP, sw_interface_dump);
4560   mp->name_filter_valid = 1;
4561   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4562   S;
4563
4564   /* and LISP-GPE interfaces */
4565   M (SW_INTERFACE_DUMP, sw_interface_dump);
4566   mp->name_filter_valid = 1;
4567   strncpy ((char *) mp->name_filter, "lisp_gpe",
4568            sizeof (mp->name_filter) - 1);
4569   S;
4570
4571   /* and IPSEC tunnel interfaces */
4572   M (SW_INTERFACE_DUMP, sw_interface_dump);
4573   mp->name_filter_valid = 1;
4574   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4575   S;
4576
4577   /* Use a control ping for synchronization */
4578   {
4579     vl_api_control_ping_t *mp;
4580     M (CONTROL_PING, control_ping);
4581     S;
4582   }
4583   W;
4584 }
4585
4586 static int
4587 api_sw_interface_set_flags (vat_main_t * vam)
4588 {
4589   unformat_input_t *i = vam->input;
4590   vl_api_sw_interface_set_flags_t *mp;
4591   f64 timeout;
4592   u32 sw_if_index;
4593   u8 sw_if_index_set = 0;
4594   u8 admin_up = 0, link_up = 0;
4595
4596   /* Parse args required to build the message */
4597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4598     {
4599       if (unformat (i, "admin-up"))
4600         admin_up = 1;
4601       else if (unformat (i, "admin-down"))
4602         admin_up = 0;
4603       else if (unformat (i, "link-up"))
4604         link_up = 1;
4605       else if (unformat (i, "link-down"))
4606         link_up = 0;
4607       else
4608         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4609         sw_if_index_set = 1;
4610       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4611         sw_if_index_set = 1;
4612       else
4613         break;
4614     }
4615
4616   if (sw_if_index_set == 0)
4617     {
4618       errmsg ("missing interface name or sw_if_index");
4619       return -99;
4620     }
4621
4622   /* Construct the API message */
4623   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4624   mp->sw_if_index = ntohl (sw_if_index);
4625   mp->admin_up_down = admin_up;
4626   mp->link_up_down = link_up;
4627
4628   /* send it... */
4629   S;
4630
4631   /* Wait for a reply, return the good/bad news... */
4632   W;
4633 }
4634
4635 static int
4636 api_sw_interface_clear_stats (vat_main_t * vam)
4637 {
4638   unformat_input_t *i = vam->input;
4639   vl_api_sw_interface_clear_stats_t *mp;
4640   f64 timeout;
4641   u32 sw_if_index;
4642   u8 sw_if_index_set = 0;
4643
4644   /* Parse args required to build the message */
4645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4646     {
4647       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4648         sw_if_index_set = 1;
4649       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4650         sw_if_index_set = 1;
4651       else
4652         break;
4653     }
4654
4655   /* Construct the API message */
4656   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4657
4658   if (sw_if_index_set == 1)
4659     mp->sw_if_index = ntohl (sw_if_index);
4660   else
4661     mp->sw_if_index = ~0;
4662
4663   /* send it... */
4664   S;
4665
4666   /* Wait for a reply, return the good/bad news... */
4667   W;
4668 }
4669
4670 #if DPDK >0
4671 static int
4672 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4673 {
4674   unformat_input_t *i = vam->input;
4675   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4676   f64 timeout;
4677   u32 sw_if_index;
4678   u8 sw_if_index_set = 0;
4679   u32 subport;
4680   u8 subport_set = 0;
4681   u32 pipe;
4682   u8 pipe_set = 0;
4683   u32 profile;
4684   u8 profile_set = 0;
4685
4686   /* Parse args required to build the message */
4687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4688     {
4689       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4690         sw_if_index_set = 1;
4691       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4692         sw_if_index_set = 1;
4693       else if (unformat (i, "subport %u", &subport))
4694         subport_set = 1;
4695       else
4696         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4697         sw_if_index_set = 1;
4698       else if (unformat (i, "pipe %u", &pipe))
4699         pipe_set = 1;
4700       else if (unformat (i, "profile %u", &profile))
4701         profile_set = 1;
4702       else
4703         break;
4704     }
4705
4706   if (sw_if_index_set == 0)
4707     {
4708       errmsg ("missing interface name or sw_if_index");
4709       return -99;
4710     }
4711
4712   if (subport_set == 0)
4713     {
4714       errmsg ("missing subport ");
4715       return -99;
4716     }
4717
4718   if (pipe_set == 0)
4719     {
4720       errmsg ("missing pipe");
4721       return -99;
4722     }
4723
4724   if (profile_set == 0)
4725     {
4726       errmsg ("missing profile");
4727       return -99;
4728     }
4729
4730   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4731
4732   mp->sw_if_index = ntohl (sw_if_index);
4733   mp->subport = ntohl (subport);
4734   mp->pipe = ntohl (pipe);
4735   mp->profile = ntohl (profile);
4736
4737
4738   S;
4739   W;
4740   /* NOTREACHED */
4741   return 0;
4742 }
4743
4744 static int
4745 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4746 {
4747   unformat_input_t *i = vam->input;
4748   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4749   f64 timeout;
4750   u32 sw_if_index;
4751   u8 sw_if_index_set = 0;
4752   u32 subport;
4753   u8 subport_set = 0;
4754   u32 tb_rate = 1250000000;     /* 10GbE */
4755   u32 tb_size = 1000000;
4756   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4757   u32 tc_period = 10;
4758
4759   /* Parse args required to build the message */
4760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4761     {
4762       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4763         sw_if_index_set = 1;
4764       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4765         sw_if_index_set = 1;
4766       else if (unformat (i, "subport %u", &subport))
4767         subport_set = 1;
4768       else
4769         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4770         sw_if_index_set = 1;
4771       else if (unformat (i, "rate %u", &tb_rate))
4772         {
4773           u32 tc_id;
4774
4775           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4776                tc_id++)
4777             tc_rate[tc_id] = tb_rate;
4778         }
4779       else if (unformat (i, "bktsize %u", &tb_size))
4780         ;
4781       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4782         ;
4783       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4784         ;
4785       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4786         ;
4787       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4788         ;
4789       else if (unformat (i, "period %u", &tc_period))
4790         ;
4791       else
4792         break;
4793     }
4794
4795   if (sw_if_index_set == 0)
4796     {
4797       errmsg ("missing interface name or sw_if_index");
4798       return -99;
4799     }
4800
4801   if (subport_set == 0)
4802     {
4803       errmsg ("missing subport ");
4804       return -99;
4805     }
4806
4807   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4808
4809   mp->sw_if_index = ntohl (sw_if_index);
4810   mp->subport = ntohl (subport);
4811   mp->tb_rate = ntohl (tb_rate);
4812   mp->tb_size = ntohl (tb_size);
4813   mp->tc_rate[0] = ntohl (tc_rate[0]);
4814   mp->tc_rate[1] = ntohl (tc_rate[1]);
4815   mp->tc_rate[2] = ntohl (tc_rate[2]);
4816   mp->tc_rate[3] = ntohl (tc_rate[3]);
4817   mp->tc_period = ntohl (tc_period);
4818
4819   S;
4820   W;
4821   /* NOTREACHED */
4822   return 0;
4823 }
4824
4825 static int
4826 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4827 {
4828   unformat_input_t *i = vam->input;
4829   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4830   f64 timeout;
4831   u32 sw_if_index;
4832   u8 sw_if_index_set = 0;
4833   u8 entry_set = 0;
4834   u8 tc_set = 0;
4835   u8 queue_set = 0;
4836   u32 entry, tc, queue;
4837
4838   /* Parse args required to build the message */
4839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4840     {
4841       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4842         sw_if_index_set = 1;
4843       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4844         sw_if_index_set = 1;
4845       else if (unformat (i, "entry %d", &entry))
4846         entry_set = 1;
4847       else if (unformat (i, "tc %d", &tc))
4848         tc_set = 1;
4849       else if (unformat (i, "queue %d", &queue))
4850         queue_set = 1;
4851       else
4852         break;
4853     }
4854
4855   if (sw_if_index_set == 0)
4856     {
4857       errmsg ("missing interface name or sw_if_index");
4858       return -99;
4859     }
4860
4861   if (entry_set == 0)
4862     {
4863       errmsg ("missing entry ");
4864       return -99;
4865     }
4866
4867   if (tc_set == 0)
4868     {
4869       errmsg ("missing traffic class ");
4870       return -99;
4871     }
4872
4873   if (queue_set == 0)
4874     {
4875       errmsg ("missing queue ");
4876       return -99;
4877     }
4878
4879   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4880
4881   mp->sw_if_index = ntohl (sw_if_index);
4882   mp->entry = ntohl (entry);
4883   mp->tc = ntohl (tc);
4884   mp->queue = ntohl (queue);
4885
4886   S;
4887   W;
4888   /* NOTREACHED */
4889   return 0;
4890 }
4891 #endif
4892
4893 static int
4894 api_sw_interface_add_del_address (vat_main_t * vam)
4895 {
4896   unformat_input_t *i = vam->input;
4897   vl_api_sw_interface_add_del_address_t *mp;
4898   f64 timeout;
4899   u32 sw_if_index;
4900   u8 sw_if_index_set = 0;
4901   u8 is_add = 1, del_all = 0;
4902   u32 address_length = 0;
4903   u8 v4_address_set = 0;
4904   u8 v6_address_set = 0;
4905   ip4_address_t v4address;
4906   ip6_address_t v6address;
4907
4908   /* Parse args required to build the message */
4909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4910     {
4911       if (unformat (i, "del-all"))
4912         del_all = 1;
4913       else if (unformat (i, "del"))
4914         is_add = 0;
4915       else
4916         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4917         sw_if_index_set = 1;
4918       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4919         sw_if_index_set = 1;
4920       else if (unformat (i, "%U/%d",
4921                          unformat_ip4_address, &v4address, &address_length))
4922         v4_address_set = 1;
4923       else if (unformat (i, "%U/%d",
4924                          unformat_ip6_address, &v6address, &address_length))
4925         v6_address_set = 1;
4926       else
4927         break;
4928     }
4929
4930   if (sw_if_index_set == 0)
4931     {
4932       errmsg ("missing interface name or sw_if_index");
4933       return -99;
4934     }
4935   if (v4_address_set && v6_address_set)
4936     {
4937       errmsg ("both v4 and v6 addresses set");
4938       return -99;
4939     }
4940   if (!v4_address_set && !v6_address_set && !del_all)
4941     {
4942       errmsg ("no addresses set");
4943       return -99;
4944     }
4945
4946   /* Construct the API message */
4947   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4948
4949   mp->sw_if_index = ntohl (sw_if_index);
4950   mp->is_add = is_add;
4951   mp->del_all = del_all;
4952   if (v6_address_set)
4953     {
4954       mp->is_ipv6 = 1;
4955       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4956     }
4957   else
4958     {
4959       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4960     }
4961   mp->address_length = address_length;
4962
4963   /* send it... */
4964   S;
4965
4966   /* Wait for a reply, return good/bad news  */
4967   W;
4968 }
4969
4970 static int
4971 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4972 {
4973   unformat_input_t *i = vam->input;
4974   vl_api_sw_interface_set_mpls_enable_t *mp;
4975   f64 timeout;
4976   u32 sw_if_index;
4977   u8 sw_if_index_set = 0;
4978   u8 enable = 1;
4979
4980   /* Parse args required to build the message */
4981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4982     {
4983       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4984         sw_if_index_set = 1;
4985       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4986         sw_if_index_set = 1;
4987       else if (unformat (i, "disable"))
4988         enable = 0;
4989       else if (unformat (i, "dis"))
4990         enable = 0;
4991       else
4992         break;
4993     }
4994
4995   if (sw_if_index_set == 0)
4996     {
4997       errmsg ("missing interface name or sw_if_index");
4998       return -99;
4999     }
5000
5001   /* Construct the API message */
5002   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
5003
5004   mp->sw_if_index = ntohl (sw_if_index);
5005   mp->enable = enable;
5006
5007   /* send it... */
5008   S;
5009
5010   /* Wait for a reply... */
5011   W;
5012 }
5013
5014 static int
5015 api_sw_interface_set_table (vat_main_t * vam)
5016 {
5017   unformat_input_t *i = vam->input;
5018   vl_api_sw_interface_set_table_t *mp;
5019   f64 timeout;
5020   u32 sw_if_index, vrf_id = 0;
5021   u8 sw_if_index_set = 0;
5022   u8 is_ipv6 = 0;
5023
5024   /* Parse args required to build the message */
5025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5026     {
5027       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5028         sw_if_index_set = 1;
5029       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5030         sw_if_index_set = 1;
5031       else if (unformat (i, "vrf %d", &vrf_id))
5032         ;
5033       else if (unformat (i, "ipv6"))
5034         is_ipv6 = 1;
5035       else
5036         break;
5037     }
5038
5039   if (sw_if_index_set == 0)
5040     {
5041       errmsg ("missing interface name or sw_if_index");
5042       return -99;
5043     }
5044
5045   /* Construct the API message */
5046   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
5047
5048   mp->sw_if_index = ntohl (sw_if_index);
5049   mp->is_ipv6 = is_ipv6;
5050   mp->vrf_id = ntohl (vrf_id);
5051
5052   /* send it... */
5053   S;
5054
5055   /* Wait for a reply... */
5056   W;
5057 }
5058
5059 static void vl_api_sw_interface_get_table_reply_t_handler
5060   (vl_api_sw_interface_get_table_reply_t * mp)
5061 {
5062   vat_main_t *vam = &vat_main;
5063
5064   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5065
5066   vam->retval = ntohl (mp->retval);
5067   vam->result_ready = 1;
5068
5069 }
5070
5071 static void vl_api_sw_interface_get_table_reply_t_handler_json
5072   (vl_api_sw_interface_get_table_reply_t * mp)
5073 {
5074   vat_main_t *vam = &vat_main;
5075   vat_json_node_t node;
5076
5077   vat_json_init_object (&node);
5078   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5079   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5080
5081   vat_json_print (vam->ofp, &node);
5082   vat_json_free (&node);
5083
5084   vam->retval = ntohl (mp->retval);
5085   vam->result_ready = 1;
5086 }
5087
5088 static int
5089 api_sw_interface_get_table (vat_main_t * vam)
5090 {
5091   unformat_input_t *i = vam->input;
5092   vl_api_sw_interface_get_table_t *mp;
5093   u32 sw_if_index;
5094   u8 sw_if_index_set = 0;
5095   u8 is_ipv6 = 0;
5096   f64 timeout;
5097
5098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5099     {
5100       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5101         sw_if_index_set = 1;
5102       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5103         sw_if_index_set = 1;
5104       else if (unformat (i, "ipv6"))
5105         is_ipv6 = 1;
5106       else
5107         break;
5108     }
5109
5110   if (sw_if_index_set == 0)
5111     {
5112       errmsg ("missing interface name or sw_if_index");
5113       return -99;
5114     }
5115
5116   M (SW_INTERFACE_GET_TABLE, sw_interface_get_table);
5117   mp->sw_if_index = htonl (sw_if_index);
5118   mp->is_ipv6 = is_ipv6;
5119
5120   S;
5121   W;
5122 }
5123
5124 static int
5125 api_sw_interface_set_vpath (vat_main_t * vam)
5126 {
5127   unformat_input_t *i = vam->input;
5128   vl_api_sw_interface_set_vpath_t *mp;
5129   f64 timeout;
5130   u32 sw_if_index = 0;
5131   u8 sw_if_index_set = 0;
5132   u8 is_enable = 0;
5133
5134   /* Parse args required to build the message */
5135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5136     {
5137       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5138         sw_if_index_set = 1;
5139       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5140         sw_if_index_set = 1;
5141       else if (unformat (i, "enable"))
5142         is_enable = 1;
5143       else if (unformat (i, "disable"))
5144         is_enable = 0;
5145       else
5146         break;
5147     }
5148
5149   if (sw_if_index_set == 0)
5150     {
5151       errmsg ("missing interface name or sw_if_index");
5152       return -99;
5153     }
5154
5155   /* Construct the API message */
5156   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5157
5158   mp->sw_if_index = ntohl (sw_if_index);
5159   mp->enable = is_enable;
5160
5161   /* send it... */
5162   S;
5163
5164   /* Wait for a reply... */
5165   W;
5166 }
5167
5168 static int
5169 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5170 {
5171   unformat_input_t *i = vam->input;
5172   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5173   f64 timeout;
5174   u32 sw_if_index = 0;
5175   u8 sw_if_index_set = 0;
5176   u8 is_enable = 0;
5177   u8 is_ipv6 = 0;
5178
5179   /* Parse args required to build the message */
5180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5181     {
5182       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5183         sw_if_index_set = 1;
5184       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5185         sw_if_index_set = 1;
5186       else if (unformat (i, "enable"))
5187         is_enable = 1;
5188       else if (unformat (i, "disable"))
5189         is_enable = 0;
5190       else if (unformat (i, "ip4"))
5191         is_ipv6 = 0;
5192       else if (unformat (i, "ip6"))
5193         is_ipv6 = 1;
5194       else
5195         break;
5196     }
5197
5198   if (sw_if_index_set == 0)
5199     {
5200       errmsg ("missing interface name or sw_if_index");
5201       return -99;
5202     }
5203
5204   /* Construct the API message */
5205   M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5206
5207   mp->sw_if_index = ntohl (sw_if_index);
5208   mp->enable = is_enable;
5209   mp->is_ipv6 = is_ipv6;
5210
5211   /* send it... */
5212   S;
5213
5214   /* Wait for a reply... */
5215   W;
5216 }
5217
5218 static int
5219 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5220 {
5221   unformat_input_t *i = vam->input;
5222   vl_api_sw_interface_set_l2_xconnect_t *mp;
5223   f64 timeout;
5224   u32 rx_sw_if_index;
5225   u8 rx_sw_if_index_set = 0;
5226   u32 tx_sw_if_index;
5227   u8 tx_sw_if_index_set = 0;
5228   u8 enable = 1;
5229
5230   /* Parse args required to build the message */
5231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5232     {
5233       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5234         rx_sw_if_index_set = 1;
5235       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5236         tx_sw_if_index_set = 1;
5237       else if (unformat (i, "rx"))
5238         {
5239           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5240             {
5241               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5242                             &rx_sw_if_index))
5243                 rx_sw_if_index_set = 1;
5244             }
5245           else
5246             break;
5247         }
5248       else if (unformat (i, "tx"))
5249         {
5250           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5251             {
5252               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5253                             &tx_sw_if_index))
5254                 tx_sw_if_index_set = 1;
5255             }
5256           else
5257             break;
5258         }
5259       else if (unformat (i, "enable"))
5260         enable = 1;
5261       else if (unformat (i, "disable"))
5262         enable = 0;
5263       else
5264         break;
5265     }
5266
5267   if (rx_sw_if_index_set == 0)
5268     {
5269       errmsg ("missing rx interface name or rx_sw_if_index");
5270       return -99;
5271     }
5272
5273   if (enable && (tx_sw_if_index_set == 0))
5274     {
5275       errmsg ("missing tx interface name or tx_sw_if_index");
5276       return -99;
5277     }
5278
5279   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5280
5281   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5282   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5283   mp->enable = enable;
5284
5285   S;
5286   W;
5287   /* NOTREACHED */
5288   return 0;
5289 }
5290
5291 static int
5292 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5293 {
5294   unformat_input_t *i = vam->input;
5295   vl_api_sw_interface_set_l2_bridge_t *mp;
5296   f64 timeout;
5297   u32 rx_sw_if_index;
5298   u8 rx_sw_if_index_set = 0;
5299   u32 bd_id;
5300   u8 bd_id_set = 0;
5301   u8 bvi = 0;
5302   u32 shg = 0;
5303   u8 enable = 1;
5304
5305   /* Parse args required to build the message */
5306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5307     {
5308       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5309         rx_sw_if_index_set = 1;
5310       else if (unformat (i, "bd_id %d", &bd_id))
5311         bd_id_set = 1;
5312       else
5313         if (unformat
5314             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5315         rx_sw_if_index_set = 1;
5316       else if (unformat (i, "shg %d", &shg))
5317         ;
5318       else if (unformat (i, "bvi"))
5319         bvi = 1;
5320       else if (unformat (i, "enable"))
5321         enable = 1;
5322       else if (unformat (i, "disable"))
5323         enable = 0;
5324       else
5325         break;
5326     }
5327
5328   if (rx_sw_if_index_set == 0)
5329     {
5330       errmsg ("missing rx interface name or sw_if_index");
5331       return -99;
5332     }
5333
5334   if (enable && (bd_id_set == 0))
5335     {
5336       errmsg ("missing bridge domain");
5337       return -99;
5338     }
5339
5340   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5341
5342   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5343   mp->bd_id = ntohl (bd_id);
5344   mp->shg = (u8) shg;
5345   mp->bvi = bvi;
5346   mp->enable = enable;
5347
5348   S;
5349   W;
5350   /* NOTREACHED */
5351   return 0;
5352 }
5353
5354 static int
5355 api_bridge_domain_dump (vat_main_t * vam)
5356 {
5357   unformat_input_t *i = vam->input;
5358   vl_api_bridge_domain_dump_t *mp;
5359   f64 timeout;
5360   u32 bd_id = ~0;
5361
5362   /* Parse args required to build the message */
5363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5364     {
5365       if (unformat (i, "bd_id %d", &bd_id))
5366         ;
5367       else
5368         break;
5369     }
5370
5371   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5372   mp->bd_id = ntohl (bd_id);
5373   S;
5374
5375   /* Use a control ping for synchronization */
5376   {
5377     vl_api_control_ping_t *mp;
5378     M (CONTROL_PING, control_ping);
5379     S;
5380   }
5381
5382   W;
5383   /* NOTREACHED */
5384   return 0;
5385 }
5386
5387 static int
5388 api_bridge_domain_add_del (vat_main_t * vam)
5389 {
5390   unformat_input_t *i = vam->input;
5391   vl_api_bridge_domain_add_del_t *mp;
5392   f64 timeout;
5393   u32 bd_id = ~0;
5394   u8 is_add = 1;
5395   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5396   u32 mac_age = 0;
5397
5398   /* Parse args required to build the message */
5399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5400     {
5401       if (unformat (i, "bd_id %d", &bd_id))
5402         ;
5403       else if (unformat (i, "flood %d", &flood))
5404         ;
5405       else if (unformat (i, "uu-flood %d", &uu_flood))
5406         ;
5407       else if (unformat (i, "forward %d", &forward))
5408         ;
5409       else if (unformat (i, "learn %d", &learn))
5410         ;
5411       else if (unformat (i, "arp-term %d", &arp_term))
5412         ;
5413       else if (unformat (i, "mac-age %d", &mac_age))
5414         ;
5415       else if (unformat (i, "del"))
5416         {
5417           is_add = 0;
5418           flood = uu_flood = forward = learn = 0;
5419         }
5420       else
5421         break;
5422     }
5423
5424   if (bd_id == ~0)
5425     {
5426       errmsg ("missing bridge domain");
5427       return -99;
5428     }
5429
5430   if (mac_age > 255)
5431     {
5432       errmsg ("mac age must be less than 256 ");
5433       return -99;
5434     }
5435
5436   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5437
5438   mp->bd_id = ntohl (bd_id);
5439   mp->flood = flood;
5440   mp->uu_flood = uu_flood;
5441   mp->forward = forward;
5442   mp->learn = learn;
5443   mp->arp_term = arp_term;
5444   mp->is_add = is_add;
5445   mp->mac_age = (u8) mac_age;
5446
5447   S;
5448   W;
5449   /* NOTREACHED */
5450   return 0;
5451 }
5452
5453 static int
5454 api_l2fib_add_del (vat_main_t * vam)
5455 {
5456   unformat_input_t *i = vam->input;
5457   vl_api_l2fib_add_del_t *mp;
5458   f64 timeout;
5459   u64 mac = 0;
5460   u8 mac_set = 0;
5461   u32 bd_id;
5462   u8 bd_id_set = 0;
5463   u32 sw_if_index = ~0;
5464   u8 sw_if_index_set = 0;
5465   u8 is_add = 1;
5466   u8 static_mac = 0;
5467   u8 filter_mac = 0;
5468   u8 bvi_mac = 0;
5469   int count = 1;
5470   f64 before = 0;
5471   int j;
5472
5473   /* Parse args required to build the message */
5474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5475     {
5476       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5477         mac_set = 1;
5478       else if (unformat (i, "bd_id %d", &bd_id))
5479         bd_id_set = 1;
5480       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5481         sw_if_index_set = 1;
5482       else if (unformat (i, "sw_if"))
5483         {
5484           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5485             {
5486               if (unformat
5487                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5488                 sw_if_index_set = 1;
5489             }
5490           else
5491             break;
5492         }
5493       else if (unformat (i, "static"))
5494         static_mac = 1;
5495       else if (unformat (i, "filter"))
5496         {
5497           filter_mac = 1;
5498           static_mac = 1;
5499         }
5500       else if (unformat (i, "bvi"))
5501         {
5502           bvi_mac = 1;
5503           static_mac = 1;
5504         }
5505       else if (unformat (i, "del"))
5506         is_add = 0;
5507       else if (unformat (i, "count %d", &count))
5508         ;
5509       else
5510         break;
5511     }
5512
5513   if (mac_set == 0)
5514     {
5515       errmsg ("missing mac address");
5516       return -99;
5517     }
5518
5519   if (bd_id_set == 0)
5520     {
5521       errmsg ("missing bridge domain");
5522       return -99;
5523     }
5524
5525   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5526     {
5527       errmsg ("missing interface name or sw_if_index");
5528       return -99;
5529     }
5530
5531   if (count > 1)
5532     {
5533       /* Turn on async mode */
5534       vam->async_mode = 1;
5535       vam->async_errors = 0;
5536       before = vat_time_now (vam);
5537     }
5538
5539   for (j = 0; j < count; j++)
5540     {
5541       M (L2FIB_ADD_DEL, l2fib_add_del);
5542
5543       mp->mac = mac;
5544       mp->bd_id = ntohl (bd_id);
5545       mp->is_add = is_add;
5546
5547       if (is_add)
5548         {
5549           mp->sw_if_index = ntohl (sw_if_index);
5550           mp->static_mac = static_mac;
5551           mp->filter_mac = filter_mac;
5552           mp->bvi_mac = bvi_mac;
5553         }
5554       increment_mac_address (&mac);
5555       /* send it... */
5556       S;
5557     }
5558
5559   if (count > 1)
5560     {
5561       vl_api_control_ping_t *mp;
5562       f64 after;
5563
5564       /* Shut off async mode */
5565       vam->async_mode = 0;
5566
5567       M (CONTROL_PING, control_ping);
5568       S;
5569
5570       timeout = vat_time_now (vam) + 1.0;
5571       while (vat_time_now (vam) < timeout)
5572         if (vam->result_ready == 1)
5573           goto out;
5574       vam->retval = -99;
5575
5576     out:
5577       if (vam->retval == -99)
5578         errmsg ("timeout");
5579
5580       if (vam->async_errors > 0)
5581         {
5582           errmsg ("%d asynchronous errors", vam->async_errors);
5583           vam->retval = -98;
5584         }
5585       vam->async_errors = 0;
5586       after = vat_time_now (vam);
5587
5588       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5589              count, after - before, count / (after - before));
5590     }
5591   else
5592     {
5593       /* Wait for a reply... */
5594       W;
5595     }
5596   /* Return the good/bad news */
5597   return (vam->retval);
5598 }
5599
5600 static int
5601 api_l2_flags (vat_main_t * vam)
5602 {
5603   unformat_input_t *i = vam->input;
5604   vl_api_l2_flags_t *mp;
5605   f64 timeout;
5606   u32 sw_if_index;
5607   u32 feature_bitmap = 0;
5608   u8 sw_if_index_set = 0;
5609
5610   /* Parse args required to build the message */
5611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5612     {
5613       if (unformat (i, "sw_if_index %d", &sw_if_index))
5614         sw_if_index_set = 1;
5615       else if (unformat (i, "sw_if"))
5616         {
5617           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5618             {
5619               if (unformat
5620                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5621                 sw_if_index_set = 1;
5622             }
5623           else
5624             break;
5625         }
5626       else if (unformat (i, "learn"))
5627         feature_bitmap |= L2INPUT_FEAT_LEARN;
5628       else if (unformat (i, "forward"))
5629         feature_bitmap |= L2INPUT_FEAT_FWD;
5630       else if (unformat (i, "flood"))
5631         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5632       else if (unformat (i, "uu-flood"))
5633         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5634       else
5635         break;
5636     }
5637
5638   if (sw_if_index_set == 0)
5639     {
5640       errmsg ("missing interface name or sw_if_index");
5641       return -99;
5642     }
5643
5644   M (L2_FLAGS, l2_flags);
5645
5646   mp->sw_if_index = ntohl (sw_if_index);
5647   mp->feature_bitmap = ntohl (feature_bitmap);
5648
5649   S;
5650   W;
5651   /* NOTREACHED */
5652   return 0;
5653 }
5654
5655 static int
5656 api_bridge_flags (vat_main_t * vam)
5657 {
5658   unformat_input_t *i = vam->input;
5659   vl_api_bridge_flags_t *mp;
5660   f64 timeout;
5661   u32 bd_id;
5662   u8 bd_id_set = 0;
5663   u8 is_set = 1;
5664   u32 flags = 0;
5665
5666   /* Parse args required to build the message */
5667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5668     {
5669       if (unformat (i, "bd_id %d", &bd_id))
5670         bd_id_set = 1;
5671       else if (unformat (i, "learn"))
5672         flags |= L2_LEARN;
5673       else if (unformat (i, "forward"))
5674         flags |= L2_FWD;
5675       else if (unformat (i, "flood"))
5676         flags |= L2_FLOOD;
5677       else if (unformat (i, "uu-flood"))
5678         flags |= L2_UU_FLOOD;
5679       else if (unformat (i, "arp-term"))
5680         flags |= L2_ARP_TERM;
5681       else if (unformat (i, "off"))
5682         is_set = 0;
5683       else if (unformat (i, "disable"))
5684         is_set = 0;
5685       else
5686         break;
5687     }
5688
5689   if (bd_id_set == 0)
5690     {
5691       errmsg ("missing bridge domain");
5692       return -99;
5693     }
5694
5695   M (BRIDGE_FLAGS, bridge_flags);
5696
5697   mp->bd_id = ntohl (bd_id);
5698   mp->feature_bitmap = ntohl (flags);
5699   mp->is_set = is_set;
5700
5701   S;
5702   W;
5703   /* NOTREACHED */
5704   return 0;
5705 }
5706
5707 static int
5708 api_bd_ip_mac_add_del (vat_main_t * vam)
5709 {
5710   unformat_input_t *i = vam->input;
5711   vl_api_bd_ip_mac_add_del_t *mp;
5712   f64 timeout;
5713   u32 bd_id;
5714   u8 is_ipv6 = 0;
5715   u8 is_add = 1;
5716   u8 bd_id_set = 0;
5717   u8 ip_set = 0;
5718   u8 mac_set = 0;
5719   ip4_address_t v4addr;
5720   ip6_address_t v6addr;
5721   u8 macaddr[6];
5722
5723
5724   /* Parse args required to build the message */
5725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5726     {
5727       if (unformat (i, "bd_id %d", &bd_id))
5728         {
5729           bd_id_set++;
5730         }
5731       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5732         {
5733           ip_set++;
5734         }
5735       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5736         {
5737           ip_set++;
5738           is_ipv6++;
5739         }
5740       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5741         {
5742           mac_set++;
5743         }
5744       else if (unformat (i, "del"))
5745         is_add = 0;
5746       else
5747         break;
5748     }
5749
5750   if (bd_id_set == 0)
5751     {
5752       errmsg ("missing bridge domain");
5753       return -99;
5754     }
5755   else if (ip_set == 0)
5756     {
5757       errmsg ("missing IP address");
5758       return -99;
5759     }
5760   else if (mac_set == 0)
5761     {
5762       errmsg ("missing MAC address");
5763       return -99;
5764     }
5765
5766   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5767
5768   mp->bd_id = ntohl (bd_id);
5769   mp->is_ipv6 = is_ipv6;
5770   mp->is_add = is_add;
5771   if (is_ipv6)
5772     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5773   else
5774     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5775   clib_memcpy (mp->mac_address, macaddr, 6);
5776   S;
5777   W;
5778   /* NOTREACHED */
5779   return 0;
5780 }
5781
5782 static int
5783 api_tap_connect (vat_main_t * vam)
5784 {
5785   unformat_input_t *i = vam->input;
5786   vl_api_tap_connect_t *mp;
5787   f64 timeout;
5788   u8 mac_address[6];
5789   u8 random_mac = 1;
5790   u8 name_set = 0;
5791   u8 *tap_name;
5792   u8 *tag = 0;
5793   ip4_address_t ip4_address;
5794   u32 ip4_mask_width;
5795   int ip4_address_set = 0;
5796   ip6_address_t ip6_address;
5797   u32 ip6_mask_width;
5798   int ip6_address_set = 0;
5799
5800   memset (mac_address, 0, sizeof (mac_address));
5801
5802   /* Parse args required to build the message */
5803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5804     {
5805       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5806         {
5807           random_mac = 0;
5808         }
5809       else if (unformat (i, "random-mac"))
5810         random_mac = 1;
5811       else if (unformat (i, "tapname %s", &tap_name))
5812         name_set = 1;
5813       else if (unformat (i, "tag %s", &tag))
5814         ;
5815       else if (unformat (i, "address %U/%d",
5816                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
5817         ip4_address_set = 1;
5818       else if (unformat (i, "address %U/%d",
5819                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
5820         ip6_address_set = 1;
5821       else
5822         break;
5823     }
5824
5825   if (name_set == 0)
5826     {
5827       errmsg ("missing tap name");
5828       return -99;
5829     }
5830   if (vec_len (tap_name) > 63)
5831     {
5832       errmsg ("tap name too long");
5833       return -99;
5834     }
5835   vec_add1 (tap_name, 0);
5836
5837   if (vec_len (tag) > 63)
5838     {
5839       errmsg ("tag too long");
5840       return -99;
5841     }
5842
5843   /* Construct the API message */
5844   M (TAP_CONNECT, tap_connect);
5845
5846   mp->use_random_mac = random_mac;
5847   clib_memcpy (mp->mac_address, mac_address, 6);
5848   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5849   if (tag)
5850     clib_memcpy (mp->tag, tag, vec_len (tag));
5851
5852   if (ip4_address_set)
5853     {
5854       mp->ip4_address_set = 1;
5855       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
5856       mp->ip4_mask_width = ip4_mask_width;
5857     }
5858   if (ip6_address_set)
5859     {
5860       mp->ip6_address_set = 1;
5861       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
5862       mp->ip6_mask_width = ip6_mask_width;
5863     }
5864
5865   vec_free (tap_name);
5866   vec_free (tag);
5867
5868   /* send it... */
5869   S;
5870
5871   /* Wait for a reply... */
5872   W;
5873 }
5874
5875 static int
5876 api_tap_modify (vat_main_t * vam)
5877 {
5878   unformat_input_t *i = vam->input;
5879   vl_api_tap_modify_t *mp;
5880   f64 timeout;
5881   u8 mac_address[6];
5882   u8 random_mac = 1;
5883   u8 name_set = 0;
5884   u8 *tap_name;
5885   u32 sw_if_index = ~0;
5886   u8 sw_if_index_set = 0;
5887
5888   memset (mac_address, 0, sizeof (mac_address));
5889
5890   /* Parse args required to build the message */
5891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5892     {
5893       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5894         sw_if_index_set = 1;
5895       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5896         sw_if_index_set = 1;
5897       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5898         {
5899           random_mac = 0;
5900         }
5901       else if (unformat (i, "random-mac"))
5902         random_mac = 1;
5903       else if (unformat (i, "tapname %s", &tap_name))
5904         name_set = 1;
5905       else
5906         break;
5907     }
5908
5909   if (sw_if_index_set == 0)
5910     {
5911       errmsg ("missing vpp interface name");
5912       return -99;
5913     }
5914   if (name_set == 0)
5915     {
5916       errmsg ("missing tap name");
5917       return -99;
5918     }
5919   if (vec_len (tap_name) > 63)
5920     {
5921       errmsg ("tap name too long");
5922     }
5923   vec_add1 (tap_name, 0);
5924
5925   /* Construct the API message */
5926   M (TAP_MODIFY, tap_modify);
5927
5928   mp->use_random_mac = random_mac;
5929   mp->sw_if_index = ntohl (sw_if_index);
5930   clib_memcpy (mp->mac_address, mac_address, 6);
5931   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5932   vec_free (tap_name);
5933
5934   /* send it... */
5935   S;
5936
5937   /* Wait for a reply... */
5938   W;
5939 }
5940
5941 static int
5942 api_tap_delete (vat_main_t * vam)
5943 {
5944   unformat_input_t *i = vam->input;
5945   vl_api_tap_delete_t *mp;
5946   f64 timeout;
5947   u32 sw_if_index = ~0;
5948   u8 sw_if_index_set = 0;
5949
5950   /* Parse args required to build the message */
5951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5952     {
5953       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5954         sw_if_index_set = 1;
5955       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5956         sw_if_index_set = 1;
5957       else
5958         break;
5959     }
5960
5961   if (sw_if_index_set == 0)
5962     {
5963       errmsg ("missing vpp interface name");
5964       return -99;
5965     }
5966
5967   /* Construct the API message */
5968   M (TAP_DELETE, tap_delete);
5969
5970   mp->sw_if_index = ntohl (sw_if_index);
5971
5972   /* send it... */
5973   S;
5974
5975   /* Wait for a reply... */
5976   W;
5977 }
5978
5979 static int
5980 api_ip_add_del_route (vat_main_t * vam)
5981 {
5982   unformat_input_t *i = vam->input;
5983   vl_api_ip_add_del_route_t *mp;
5984   f64 timeout;
5985   u32 sw_if_index = ~0, vrf_id = 0;
5986   u8 is_ipv6 = 0;
5987   u8 is_local = 0, is_drop = 0;
5988   u8 is_unreach = 0, is_prohibit = 0;
5989   u8 create_vrf_if_needed = 0;
5990   u8 is_add = 1;
5991   u32 next_hop_weight = 1;
5992   u8 not_last = 0;
5993   u8 is_multipath = 0;
5994   u8 address_set = 0;
5995   u8 address_length_set = 0;
5996   u32 next_hop_table_id = 0;
5997   u32 resolve_attempts = 0;
5998   u32 dst_address_length = 0;
5999   u8 next_hop_set = 0;
6000   ip4_address_t v4_dst_address, v4_next_hop_address;
6001   ip6_address_t v6_dst_address, v6_next_hop_address;
6002   int count = 1;
6003   int j;
6004   f64 before = 0;
6005   u32 random_add_del = 0;
6006   u32 *random_vector = 0;
6007   uword *random_hash;
6008   u32 random_seed = 0xdeaddabe;
6009   u32 classify_table_index = ~0;
6010   u8 is_classify = 0;
6011   u8 resolve_host = 0, resolve_attached = 0;
6012   mpls_label_t *next_hop_out_label_stack = NULL;
6013   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6014   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6015
6016   /* Parse args required to build the message */
6017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6018     {
6019       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6020         ;
6021       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6022         ;
6023       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6024         {
6025           address_set = 1;
6026           is_ipv6 = 0;
6027         }
6028       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6029         {
6030           address_set = 1;
6031           is_ipv6 = 1;
6032         }
6033       else if (unformat (i, "/%d", &dst_address_length))
6034         {
6035           address_length_set = 1;
6036         }
6037
6038       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6039                                          &v4_next_hop_address))
6040         {
6041           next_hop_set = 1;
6042         }
6043       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6044                                          &v6_next_hop_address))
6045         {
6046           next_hop_set = 1;
6047         }
6048       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6049         ;
6050       else if (unformat (i, "weight %d", &next_hop_weight))
6051         ;
6052       else if (unformat (i, "drop"))
6053         {
6054           is_drop = 1;
6055         }
6056       else if (unformat (i, "null-send-unreach"))
6057         {
6058           is_unreach = 1;
6059         }
6060       else if (unformat (i, "null-send-prohibit"))
6061         {
6062           is_prohibit = 1;
6063         }
6064       else if (unformat (i, "local"))
6065         {
6066           is_local = 1;
6067         }
6068       else if (unformat (i, "classify %d", &classify_table_index))
6069         {
6070           is_classify = 1;
6071         }
6072       else if (unformat (i, "del"))
6073         is_add = 0;
6074       else if (unformat (i, "add"))
6075         is_add = 1;
6076       else if (unformat (i, "not-last"))
6077         not_last = 1;
6078       else if (unformat (i, "resolve-via-host"))
6079         resolve_host = 1;
6080       else if (unformat (i, "resolve-via-attached"))
6081         resolve_attached = 1;
6082       else if (unformat (i, "multipath"))
6083         is_multipath = 1;
6084       else if (unformat (i, "vrf %d", &vrf_id))
6085         ;
6086       else if (unformat (i, "create-vrf"))
6087         create_vrf_if_needed = 1;
6088       else if (unformat (i, "count %d", &count))
6089         ;
6090       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6091         ;
6092       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6093         ;
6094       else if (unformat (i, "out-label %d", &next_hop_out_label))
6095         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6096       else if (unformat (i, "via-label %d", &next_hop_via_label))
6097         ;
6098       else if (unformat (i, "random"))
6099         random_add_del = 1;
6100       else if (unformat (i, "seed %d", &random_seed))
6101         ;
6102       else
6103         {
6104           clib_warning ("parse error '%U'", format_unformat_error, i);
6105           return -99;
6106         }
6107     }
6108
6109   if (!next_hop_set && !is_drop && !is_local &&
6110       !is_classify && !is_unreach && !is_prohibit &&
6111       MPLS_LABEL_INVALID == next_hop_via_label)
6112     {
6113       errmsg
6114         ("next hop / local / drop / unreach / prohibit / classify not set");
6115       return -99;
6116     }
6117
6118   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6119     {
6120       errmsg ("next hop and next-hop via label set");
6121       return -99;
6122     }
6123   if (address_set == 0)
6124     {
6125       errmsg ("missing addresses");
6126       return -99;
6127     }
6128
6129   if (address_length_set == 0)
6130     {
6131       errmsg ("missing address length");
6132       return -99;
6133     }
6134
6135   /* Generate a pile of unique, random routes */
6136   if (random_add_del)
6137     {
6138       u32 this_random_address;
6139       random_hash = hash_create (count, sizeof (uword));
6140
6141       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6142       for (j = 0; j <= count; j++)
6143         {
6144           do
6145             {
6146               this_random_address = random_u32 (&random_seed);
6147               this_random_address =
6148                 clib_host_to_net_u32 (this_random_address);
6149             }
6150           while (hash_get (random_hash, this_random_address));
6151           vec_add1 (random_vector, this_random_address);
6152           hash_set (random_hash, this_random_address, 1);
6153         }
6154       hash_free (random_hash);
6155       v4_dst_address.as_u32 = random_vector[0];
6156     }
6157
6158   if (count > 1)
6159     {
6160       /* Turn on async mode */
6161       vam->async_mode = 1;
6162       vam->async_errors = 0;
6163       before = vat_time_now (vam);
6164     }
6165
6166   for (j = 0; j < count; j++)
6167     {
6168       /* Construct the API message */
6169       M2 (IP_ADD_DEL_ROUTE, ip_add_del_route,
6170           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6171
6172       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6173       mp->table_id = ntohl (vrf_id);
6174       mp->create_vrf_if_needed = create_vrf_if_needed;
6175
6176       mp->is_add = is_add;
6177       mp->is_drop = is_drop;
6178       mp->is_unreach = is_unreach;
6179       mp->is_prohibit = is_prohibit;
6180       mp->is_ipv6 = is_ipv6;
6181       mp->is_local = is_local;
6182       mp->is_classify = is_classify;
6183       mp->is_multipath = is_multipath;
6184       mp->is_resolve_host = resolve_host;
6185       mp->is_resolve_attached = resolve_attached;
6186       mp->not_last = not_last;
6187       mp->next_hop_weight = next_hop_weight;
6188       mp->dst_address_length = dst_address_length;
6189       mp->next_hop_table_id = ntohl (next_hop_table_id);
6190       mp->classify_table_index = ntohl (classify_table_index);
6191       mp->next_hop_via_label = ntohl (next_hop_via_label);
6192       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6193       if (0 != mp->next_hop_n_out_labels)
6194         {
6195           memcpy (mp->next_hop_out_label_stack,
6196                   next_hop_out_label_stack,
6197                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6198           vec_free (next_hop_out_label_stack);
6199         }
6200
6201       if (is_ipv6)
6202         {
6203           clib_memcpy (mp->dst_address, &v6_dst_address,
6204                        sizeof (v6_dst_address));
6205           if (next_hop_set)
6206             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6207                          sizeof (v6_next_hop_address));
6208           increment_v6_address (&v6_dst_address);
6209         }
6210       else
6211         {
6212           clib_memcpy (mp->dst_address, &v4_dst_address,
6213                        sizeof (v4_dst_address));
6214           if (next_hop_set)
6215             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6216                          sizeof (v4_next_hop_address));
6217           if (random_add_del)
6218             v4_dst_address.as_u32 = random_vector[j + 1];
6219           else
6220             increment_v4_address (&v4_dst_address);
6221         }
6222       /* send it... */
6223       S;
6224       /* If we receive SIGTERM, stop now... */
6225       if (vam->do_exit)
6226         break;
6227     }
6228
6229   /* When testing multiple add/del ops, use a control-ping to sync */
6230   if (count > 1)
6231     {
6232       vl_api_control_ping_t *mp;
6233       f64 after;
6234
6235       /* Shut off async mode */
6236       vam->async_mode = 0;
6237
6238       M (CONTROL_PING, control_ping);
6239       S;
6240
6241       timeout = vat_time_now (vam) + 1.0;
6242       while (vat_time_now (vam) < timeout)
6243         if (vam->result_ready == 1)
6244           goto out;
6245       vam->retval = -99;
6246
6247     out:
6248       if (vam->retval == -99)
6249         errmsg ("timeout");
6250
6251       if (vam->async_errors > 0)
6252         {
6253           errmsg ("%d asynchronous errors", vam->async_errors);
6254           vam->retval = -98;
6255         }
6256       vam->async_errors = 0;
6257       after = vat_time_now (vam);
6258
6259       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6260       if (j > 0)
6261         count = j;
6262
6263       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6264              count, after - before, count / (after - before));
6265     }
6266   else
6267     {
6268       /* Wait for a reply... */
6269       W;
6270     }
6271
6272   /* Return the good/bad news */
6273   return (vam->retval);
6274 }
6275
6276 static int
6277 api_mpls_route_add_del (vat_main_t * vam)
6278 {
6279   unformat_input_t *i = vam->input;
6280   vl_api_mpls_route_add_del_t *mp;
6281   f64 timeout;
6282   u32 sw_if_index = ~0, table_id = 0;
6283   u8 create_table_if_needed = 0;
6284   u8 is_add = 1;
6285   u32 next_hop_weight = 1;
6286   u8 is_multipath = 0;
6287   u32 next_hop_table_id = 0;
6288   u8 next_hop_set = 0;
6289   ip4_address_t v4_next_hop_address = {
6290     .as_u32 = 0,
6291   };
6292   ip6_address_t v6_next_hop_address = { {0} };
6293   int count = 1;
6294   int j;
6295   f64 before = 0;
6296   u32 classify_table_index = ~0;
6297   u8 is_classify = 0;
6298   u8 resolve_host = 0, resolve_attached = 0;
6299   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6300   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6301   mpls_label_t *next_hop_out_label_stack = NULL;
6302   mpls_label_t local_label = MPLS_LABEL_INVALID;
6303   u8 is_eos = 0;
6304   u8 next_hop_proto_is_ip4 = 1;
6305
6306   /* Parse args required to build the message */
6307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6308     {
6309       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6310         ;
6311       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6312         ;
6313       else if (unformat (i, "%d", &local_label))
6314         ;
6315       else if (unformat (i, "eos"))
6316         is_eos = 1;
6317       else if (unformat (i, "non-eos"))
6318         is_eos = 0;
6319       else if (unformat (i, "via %U", unformat_ip4_address,
6320                          &v4_next_hop_address))
6321         {
6322           next_hop_set = 1;
6323           next_hop_proto_is_ip4 = 1;
6324         }
6325       else if (unformat (i, "via %U", unformat_ip6_address,
6326                          &v6_next_hop_address))
6327         {
6328           next_hop_set = 1;
6329           next_hop_proto_is_ip4 = 0;
6330         }
6331       else if (unformat (i, "weight %d", &next_hop_weight))
6332         ;
6333       else if (unformat (i, "create-table"))
6334         create_table_if_needed = 1;
6335       else if (unformat (i, "classify %d", &classify_table_index))
6336         {
6337           is_classify = 1;
6338         }
6339       else if (unformat (i, "del"))
6340         is_add = 0;
6341       else if (unformat (i, "add"))
6342         is_add = 1;
6343       else if (unformat (i, "resolve-via-host"))
6344         resolve_host = 1;
6345       else if (unformat (i, "resolve-via-attached"))
6346         resolve_attached = 1;
6347       else if (unformat (i, "multipath"))
6348         is_multipath = 1;
6349       else if (unformat (i, "count %d", &count))
6350         ;
6351       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6352         {
6353           next_hop_set = 1;
6354           next_hop_proto_is_ip4 = 1;
6355         }
6356       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6357         {
6358           next_hop_set = 1;
6359           next_hop_proto_is_ip4 = 0;
6360         }
6361       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6362         ;
6363       else if (unformat (i, "via-label %d", &next_hop_via_label))
6364         ;
6365       else if (unformat (i, "out-label %d", &next_hop_out_label))
6366         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6367       else
6368         {
6369           clib_warning ("parse error '%U'", format_unformat_error, i);
6370           return -99;
6371         }
6372     }
6373
6374   if (!next_hop_set && !is_classify)
6375     {
6376       errmsg ("next hop / classify not set");
6377       return -99;
6378     }
6379
6380   if (MPLS_LABEL_INVALID == local_label)
6381     {
6382       errmsg ("missing label");
6383       return -99;
6384     }
6385
6386   if (count > 1)
6387     {
6388       /* Turn on async mode */
6389       vam->async_mode = 1;
6390       vam->async_errors = 0;
6391       before = vat_time_now (vam);
6392     }
6393
6394   for (j = 0; j < count; j++)
6395     {
6396       /* Construct the API message */
6397       M2 (MPLS_ROUTE_ADD_DEL, mpls_route_add_del,
6398           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6399
6400       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6401       mp->mr_table_id = ntohl (table_id);
6402       mp->mr_create_table_if_needed = create_table_if_needed;
6403
6404       mp->mr_is_add = is_add;
6405       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6406       mp->mr_is_classify = is_classify;
6407       mp->mr_is_multipath = is_multipath;
6408       mp->mr_is_resolve_host = resolve_host;
6409       mp->mr_is_resolve_attached = resolve_attached;
6410       mp->mr_next_hop_weight = next_hop_weight;
6411       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6412       mp->mr_classify_table_index = ntohl (classify_table_index);
6413       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6414       mp->mr_label = ntohl (local_label);
6415       mp->mr_eos = is_eos;
6416
6417       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6418       if (0 != mp->mr_next_hop_n_out_labels)
6419         {
6420           memcpy (mp->mr_next_hop_out_label_stack,
6421                   next_hop_out_label_stack,
6422                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6423           vec_free (next_hop_out_label_stack);
6424         }
6425
6426       if (next_hop_set)
6427         {
6428           if (next_hop_proto_is_ip4)
6429             {
6430               clib_memcpy (mp->mr_next_hop,
6431                            &v4_next_hop_address,
6432                            sizeof (v4_next_hop_address));
6433             }
6434           else
6435             {
6436               clib_memcpy (mp->mr_next_hop,
6437                            &v6_next_hop_address,
6438                            sizeof (v6_next_hop_address));
6439             }
6440         }
6441       local_label++;
6442
6443       /* send it... */
6444       S;
6445       /* If we receive SIGTERM, stop now... */
6446       if (vam->do_exit)
6447         break;
6448     }
6449
6450   /* When testing multiple add/del ops, use a control-ping to sync */
6451   if (count > 1)
6452     {
6453       vl_api_control_ping_t *mp;
6454       f64 after;
6455
6456       /* Shut off async mode */
6457       vam->async_mode = 0;
6458
6459       M (CONTROL_PING, control_ping);
6460       S;
6461
6462       timeout = vat_time_now (vam) + 1.0;
6463       while (vat_time_now (vam) < timeout)
6464         if (vam->result_ready == 1)
6465           goto out;
6466       vam->retval = -99;
6467
6468     out:
6469       if (vam->retval == -99)
6470         errmsg ("timeout");
6471
6472       if (vam->async_errors > 0)
6473         {
6474           errmsg ("%d asynchronous errors", vam->async_errors);
6475           vam->retval = -98;
6476         }
6477       vam->async_errors = 0;
6478       after = vat_time_now (vam);
6479
6480       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6481       if (j > 0)
6482         count = j;
6483
6484       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6485              count, after - before, count / (after - before));
6486     }
6487   else
6488     {
6489       /* Wait for a reply... */
6490       W;
6491     }
6492
6493   /* Return the good/bad news */
6494   return (vam->retval);
6495 }
6496
6497 static int
6498 api_mpls_ip_bind_unbind (vat_main_t * vam)
6499 {
6500   unformat_input_t *i = vam->input;
6501   vl_api_mpls_ip_bind_unbind_t *mp;
6502   f64 timeout;
6503   u32 ip_table_id = 0;
6504   u8 create_table_if_needed = 0;
6505   u8 is_bind = 1;
6506   u8 is_ip4 = 1;
6507   ip4_address_t v4_address;
6508   ip6_address_t v6_address;
6509   u32 address_length;
6510   u8 address_set = 0;
6511   mpls_label_t local_label = MPLS_LABEL_INVALID;
6512
6513   /* Parse args required to build the message */
6514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6515     {
6516       if (unformat (i, "%U/%d", unformat_ip4_address,
6517                     &v4_address, &address_length))
6518         {
6519           is_ip4 = 1;
6520           address_set = 1;
6521         }
6522       else if (unformat (i, "%U/%d", unformat_ip6_address,
6523                          &v6_address, &address_length))
6524         {
6525           is_ip4 = 0;
6526           address_set = 1;
6527         }
6528       else if (unformat (i, "%d", &local_label))
6529         ;
6530       else if (unformat (i, "create-table"))
6531         create_table_if_needed = 1;
6532       else if (unformat (i, "table-id %d", &ip_table_id))
6533         ;
6534       else if (unformat (i, "unbind"))
6535         is_bind = 0;
6536       else if (unformat (i, "bind"))
6537         is_bind = 1;
6538       else
6539         {
6540           clib_warning ("parse error '%U'", format_unformat_error, i);
6541           return -99;
6542         }
6543     }
6544
6545   if (!address_set)
6546     {
6547       errmsg ("IP addres not set");
6548       return -99;
6549     }
6550
6551   if (MPLS_LABEL_INVALID == local_label)
6552     {
6553       errmsg ("missing label");
6554       return -99;
6555     }
6556
6557   /* Construct the API message */
6558   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6559
6560   mp->mb_create_table_if_needed = create_table_if_needed;
6561   mp->mb_is_bind = is_bind;
6562   mp->mb_is_ip4 = is_ip4;
6563   mp->mb_ip_table_id = ntohl (ip_table_id);
6564   mp->mb_mpls_table_id = 0;
6565   mp->mb_label = ntohl (local_label);
6566   mp->mb_address_length = address_length;
6567
6568   if (is_ip4)
6569     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6570   else
6571     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6572
6573   /* send it... */
6574   S;
6575
6576   /* Wait for a reply... */
6577   W;
6578 }
6579
6580 static int
6581 api_proxy_arp_add_del (vat_main_t * vam)
6582 {
6583   unformat_input_t *i = vam->input;
6584   vl_api_proxy_arp_add_del_t *mp;
6585   f64 timeout;
6586   u32 vrf_id = 0;
6587   u8 is_add = 1;
6588   ip4_address_t lo, hi;
6589   u8 range_set = 0;
6590
6591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6592     {
6593       if (unformat (i, "vrf %d", &vrf_id))
6594         ;
6595       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6596                          unformat_ip4_address, &hi))
6597         range_set = 1;
6598       else if (unformat (i, "del"))
6599         is_add = 0;
6600       else
6601         {
6602           clib_warning ("parse error '%U'", format_unformat_error, i);
6603           return -99;
6604         }
6605     }
6606
6607   if (range_set == 0)
6608     {
6609       errmsg ("address range not set");
6610       return -99;
6611     }
6612
6613   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6614
6615   mp->vrf_id = ntohl (vrf_id);
6616   mp->is_add = is_add;
6617   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6618   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6619
6620   S;
6621   W;
6622   /* NOTREACHED */
6623   return 0;
6624 }
6625
6626 static int
6627 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6628 {
6629   unformat_input_t *i = vam->input;
6630   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6631   f64 timeout;
6632   u32 sw_if_index;
6633   u8 enable = 1;
6634   u8 sw_if_index_set = 0;
6635
6636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6637     {
6638       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6639         sw_if_index_set = 1;
6640       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6641         sw_if_index_set = 1;
6642       else if (unformat (i, "enable"))
6643         enable = 1;
6644       else if (unformat (i, "disable"))
6645         enable = 0;
6646       else
6647         {
6648           clib_warning ("parse error '%U'", format_unformat_error, i);
6649           return -99;
6650         }
6651     }
6652
6653   if (sw_if_index_set == 0)
6654     {
6655       errmsg ("missing interface name or sw_if_index");
6656       return -99;
6657     }
6658
6659   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6660
6661   mp->sw_if_index = ntohl (sw_if_index);
6662   mp->enable_disable = enable;
6663
6664   S;
6665   W;
6666   /* NOTREACHED */
6667   return 0;
6668 }
6669
6670 static int
6671 api_mpls_tunnel_add_del (vat_main_t * vam)
6672 {
6673   unformat_input_t *i = vam->input;
6674   vl_api_mpls_tunnel_add_del_t *mp;
6675   f64 timeout;
6676
6677   u8 is_add = 1;
6678   u8 l2_only = 0;
6679   u32 sw_if_index = ~0;
6680   u32 next_hop_sw_if_index = ~0;
6681   u32 next_hop_proto_is_ip4 = 1;
6682
6683   u32 next_hop_table_id = 0;
6684   ip4_address_t v4_next_hop_address = {
6685     .as_u32 = 0,
6686   };
6687   ip6_address_t v6_next_hop_address = { {0} };
6688   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
6689
6690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6691     {
6692       if (unformat (i, "add"))
6693         is_add = 1;
6694       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6695         is_add = 0;
6696       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
6697         ;
6698       else if (unformat (i, "via %U",
6699                          unformat_ip4_address, &v4_next_hop_address))
6700         {
6701           next_hop_proto_is_ip4 = 1;
6702         }
6703       else if (unformat (i, "via %U",
6704                          unformat_ip6_address, &v6_next_hop_address))
6705         {
6706           next_hop_proto_is_ip4 = 0;
6707         }
6708       else if (unformat (i, "l2-only"))
6709         l2_only = 1;
6710       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6711         ;
6712       else if (unformat (i, "out-label %d", &next_hop_out_label))
6713         vec_add1 (labels, ntohl (next_hop_out_label));
6714       else
6715         {
6716           clib_warning ("parse error '%U'", format_unformat_error, i);
6717           return -99;
6718         }
6719     }
6720
6721   M2 (MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del,
6722       sizeof (mpls_label_t) * vec_len (labels));
6723
6724   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
6725   mp->mt_sw_if_index = ntohl (sw_if_index);
6726   mp->mt_is_add = is_add;
6727   mp->mt_l2_only = l2_only;
6728   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
6729   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6730
6731   mp->mt_next_hop_n_out_labels = vec_len (labels);
6732
6733   if (0 != mp->mt_next_hop_n_out_labels)
6734     {
6735       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
6736                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
6737       vec_free (labels);
6738     }
6739
6740   if (next_hop_proto_is_ip4)
6741     {
6742       clib_memcpy (mp->mt_next_hop,
6743                    &v4_next_hop_address, sizeof (v4_next_hop_address));
6744     }
6745   else
6746     {
6747       clib_memcpy (mp->mt_next_hop,
6748                    &v6_next_hop_address, sizeof (v6_next_hop_address));
6749     }
6750
6751   S;
6752   W;
6753   /* NOTREACHED */
6754   return 0;
6755 }
6756
6757 static int
6758 api_sw_interface_set_unnumbered (vat_main_t * vam)
6759 {
6760   unformat_input_t *i = vam->input;
6761   vl_api_sw_interface_set_unnumbered_t *mp;
6762   f64 timeout;
6763   u32 sw_if_index;
6764   u32 unnum_sw_index = ~0;
6765   u8 is_add = 1;
6766   u8 sw_if_index_set = 0;
6767
6768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6769     {
6770       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6771         sw_if_index_set = 1;
6772       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6773         sw_if_index_set = 1;
6774       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6775         ;
6776       else if (unformat (i, "del"))
6777         is_add = 0;
6778       else
6779         {
6780           clib_warning ("parse error '%U'", format_unformat_error, i);
6781           return -99;
6782         }
6783     }
6784
6785   if (sw_if_index_set == 0)
6786     {
6787       errmsg ("missing interface name or sw_if_index");
6788       return -99;
6789     }
6790
6791   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6792
6793   mp->sw_if_index = ntohl (sw_if_index);
6794   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6795   mp->is_add = is_add;
6796
6797   S;
6798   W;
6799   /* NOTREACHED */
6800   return 0;
6801 }
6802
6803 static int
6804 api_ip_neighbor_add_del (vat_main_t * vam)
6805 {
6806   unformat_input_t *i = vam->input;
6807   vl_api_ip_neighbor_add_del_t *mp;
6808   f64 timeout;
6809   u32 sw_if_index;
6810   u8 sw_if_index_set = 0;
6811   u32 vrf_id = 0;
6812   u8 is_add = 1;
6813   u8 is_static = 0;
6814   u8 mac_address[6];
6815   u8 mac_set = 0;
6816   u8 v4_address_set = 0;
6817   u8 v6_address_set = 0;
6818   ip4_address_t v4address;
6819   ip6_address_t v6address;
6820
6821   memset (mac_address, 0, sizeof (mac_address));
6822
6823   /* Parse args required to build the message */
6824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6825     {
6826       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6827         {
6828           mac_set = 1;
6829         }
6830       else if (unformat (i, "del"))
6831         is_add = 0;
6832       else
6833         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6834         sw_if_index_set = 1;
6835       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6836         sw_if_index_set = 1;
6837       else if (unformat (i, "is_static"))
6838         is_static = 1;
6839       else if (unformat (i, "vrf %d", &vrf_id))
6840         ;
6841       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6842         v4_address_set = 1;
6843       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6844         v6_address_set = 1;
6845       else
6846         {
6847           clib_warning ("parse error '%U'", format_unformat_error, i);
6848           return -99;
6849         }
6850     }
6851
6852   if (sw_if_index_set == 0)
6853     {
6854       errmsg ("missing interface name or sw_if_index");
6855       return -99;
6856     }
6857   if (v4_address_set && v6_address_set)
6858     {
6859       errmsg ("both v4 and v6 addresses set");
6860       return -99;
6861     }
6862   if (!v4_address_set && !v6_address_set)
6863     {
6864       errmsg ("no address set");
6865       return -99;
6866     }
6867
6868   /* Construct the API message */
6869   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6870
6871   mp->sw_if_index = ntohl (sw_if_index);
6872   mp->is_add = is_add;
6873   mp->vrf_id = ntohl (vrf_id);
6874   mp->is_static = is_static;
6875   if (mac_set)
6876     clib_memcpy (mp->mac_address, mac_address, 6);
6877   if (v6_address_set)
6878     {
6879       mp->is_ipv6 = 1;
6880       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6881     }
6882   else
6883     {
6884       /* mp->is_ipv6 = 0; via memset in M macro above */
6885       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6886     }
6887
6888   /* send it... */
6889   S;
6890
6891   /* Wait for a reply, return good/bad news  */
6892   W;
6893
6894   /* NOTREACHED */
6895   return 0;
6896 }
6897
6898 static int
6899 api_reset_vrf (vat_main_t * vam)
6900 {
6901   unformat_input_t *i = vam->input;
6902   vl_api_reset_vrf_t *mp;
6903   f64 timeout;
6904   u32 vrf_id = 0;
6905   u8 is_ipv6 = 0;
6906   u8 vrf_id_set = 0;
6907
6908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6909     {
6910       if (unformat (i, "vrf %d", &vrf_id))
6911         vrf_id_set = 1;
6912       else if (unformat (i, "ipv6"))
6913         is_ipv6 = 1;
6914       else
6915         {
6916           clib_warning ("parse error '%U'", format_unformat_error, i);
6917           return -99;
6918         }
6919     }
6920
6921   if (vrf_id_set == 0)
6922     {
6923       errmsg ("missing vrf id");
6924       return -99;
6925     }
6926
6927   M (RESET_VRF, reset_vrf);
6928
6929   mp->vrf_id = ntohl (vrf_id);
6930   mp->is_ipv6 = is_ipv6;
6931
6932   S;
6933   W;
6934   /* NOTREACHED */
6935   return 0;
6936 }
6937
6938 static int
6939 api_create_vlan_subif (vat_main_t * vam)
6940 {
6941   unformat_input_t *i = vam->input;
6942   vl_api_create_vlan_subif_t *mp;
6943   f64 timeout;
6944   u32 sw_if_index;
6945   u8 sw_if_index_set = 0;
6946   u32 vlan_id;
6947   u8 vlan_id_set = 0;
6948
6949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6950     {
6951       if (unformat (i, "sw_if_index %d", &sw_if_index))
6952         sw_if_index_set = 1;
6953       else
6954         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6955         sw_if_index_set = 1;
6956       else if (unformat (i, "vlan %d", &vlan_id))
6957         vlan_id_set = 1;
6958       else
6959         {
6960           clib_warning ("parse error '%U'", format_unformat_error, i);
6961           return -99;
6962         }
6963     }
6964
6965   if (sw_if_index_set == 0)
6966     {
6967       errmsg ("missing interface name or sw_if_index");
6968       return -99;
6969     }
6970
6971   if (vlan_id_set == 0)
6972     {
6973       errmsg ("missing vlan_id");
6974       return -99;
6975     }
6976   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6977
6978   mp->sw_if_index = ntohl (sw_if_index);
6979   mp->vlan_id = ntohl (vlan_id);
6980
6981   S;
6982   W;
6983   /* NOTREACHED */
6984   return 0;
6985 }
6986
6987 #define foreach_create_subif_bit                \
6988 _(no_tags)                                      \
6989 _(one_tag)                                      \
6990 _(two_tags)                                     \
6991 _(dot1ad)                                       \
6992 _(exact_match)                                  \
6993 _(default_sub)                                  \
6994 _(outer_vlan_id_any)                            \
6995 _(inner_vlan_id_any)
6996
6997 static int
6998 api_create_subif (vat_main_t * vam)
6999 {
7000   unformat_input_t *i = vam->input;
7001   vl_api_create_subif_t *mp;
7002   f64 timeout;
7003   u32 sw_if_index;
7004   u8 sw_if_index_set = 0;
7005   u32 sub_id;
7006   u8 sub_id_set = 0;
7007   u32 no_tags = 0;
7008   u32 one_tag = 0;
7009   u32 two_tags = 0;
7010   u32 dot1ad = 0;
7011   u32 exact_match = 0;
7012   u32 default_sub = 0;
7013   u32 outer_vlan_id_any = 0;
7014   u32 inner_vlan_id_any = 0;
7015   u32 tmp;
7016   u16 outer_vlan_id = 0;
7017   u16 inner_vlan_id = 0;
7018
7019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7020     {
7021       if (unformat (i, "sw_if_index %d", &sw_if_index))
7022         sw_if_index_set = 1;
7023       else
7024         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7025         sw_if_index_set = 1;
7026       else if (unformat (i, "sub_id %d", &sub_id))
7027         sub_id_set = 1;
7028       else if (unformat (i, "outer_vlan_id %d", &tmp))
7029         outer_vlan_id = tmp;
7030       else if (unformat (i, "inner_vlan_id %d", &tmp))
7031         inner_vlan_id = tmp;
7032
7033 #define _(a) else if (unformat (i, #a)) a = 1 ;
7034       foreach_create_subif_bit
7035 #undef _
7036         else
7037         {
7038           clib_warning ("parse error '%U'", format_unformat_error, i);
7039           return -99;
7040         }
7041     }
7042
7043   if (sw_if_index_set == 0)
7044     {
7045       errmsg ("missing interface name or sw_if_index");
7046       return -99;
7047     }
7048
7049   if (sub_id_set == 0)
7050     {
7051       errmsg ("missing sub_id");
7052       return -99;
7053     }
7054   M (CREATE_SUBIF, create_subif);
7055
7056   mp->sw_if_index = ntohl (sw_if_index);
7057   mp->sub_id = ntohl (sub_id);
7058
7059 #define _(a) mp->a = a;
7060   foreach_create_subif_bit;
7061 #undef _
7062
7063   mp->outer_vlan_id = ntohs (outer_vlan_id);
7064   mp->inner_vlan_id = ntohs (inner_vlan_id);
7065
7066   S;
7067   W;
7068   /* NOTREACHED */
7069   return 0;
7070 }
7071
7072 static int
7073 api_oam_add_del (vat_main_t * vam)
7074 {
7075   unformat_input_t *i = vam->input;
7076   vl_api_oam_add_del_t *mp;
7077   f64 timeout;
7078   u32 vrf_id = 0;
7079   u8 is_add = 1;
7080   ip4_address_t src, dst;
7081   u8 src_set = 0;
7082   u8 dst_set = 0;
7083
7084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7085     {
7086       if (unformat (i, "vrf %d", &vrf_id))
7087         ;
7088       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7089         src_set = 1;
7090       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7091         dst_set = 1;
7092       else if (unformat (i, "del"))
7093         is_add = 0;
7094       else
7095         {
7096           clib_warning ("parse error '%U'", format_unformat_error, i);
7097           return -99;
7098         }
7099     }
7100
7101   if (src_set == 0)
7102     {
7103       errmsg ("missing src addr");
7104       return -99;
7105     }
7106
7107   if (dst_set == 0)
7108     {
7109       errmsg ("missing dst addr");
7110       return -99;
7111     }
7112
7113   M (OAM_ADD_DEL, oam_add_del);
7114
7115   mp->vrf_id = ntohl (vrf_id);
7116   mp->is_add = is_add;
7117   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7118   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7119
7120   S;
7121   W;
7122   /* NOTREACHED */
7123   return 0;
7124 }
7125
7126 static int
7127 api_reset_fib (vat_main_t * vam)
7128 {
7129   unformat_input_t *i = vam->input;
7130   vl_api_reset_fib_t *mp;
7131   f64 timeout;
7132   u32 vrf_id = 0;
7133   u8 is_ipv6 = 0;
7134   u8 vrf_id_set = 0;
7135
7136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7137     {
7138       if (unformat (i, "vrf %d", &vrf_id))
7139         vrf_id_set = 1;
7140       else if (unformat (i, "ipv6"))
7141         is_ipv6 = 1;
7142       else
7143         {
7144           clib_warning ("parse error '%U'", format_unformat_error, i);
7145           return -99;
7146         }
7147     }
7148
7149   if (vrf_id_set == 0)
7150     {
7151       errmsg ("missing vrf id");
7152       return -99;
7153     }
7154
7155   M (RESET_FIB, reset_fib);
7156
7157   mp->vrf_id = ntohl (vrf_id);
7158   mp->is_ipv6 = is_ipv6;
7159
7160   S;
7161   W;
7162   /* NOTREACHED */
7163   return 0;
7164 }
7165
7166 static int
7167 api_dhcp_proxy_config (vat_main_t * vam)
7168 {
7169   unformat_input_t *i = vam->input;
7170   vl_api_dhcp_proxy_config_t *mp;
7171   f64 timeout;
7172   u32 vrf_id = 0;
7173   u8 is_add = 1;
7174   u8 insert_cid = 1;
7175   u8 v4_address_set = 0;
7176   u8 v6_address_set = 0;
7177   ip4_address_t v4address;
7178   ip6_address_t v6address;
7179   u8 v4_src_address_set = 0;
7180   u8 v6_src_address_set = 0;
7181   ip4_address_t v4srcaddress;
7182   ip6_address_t v6srcaddress;
7183
7184   /* Parse args required to build the message */
7185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7186     {
7187       if (unformat (i, "del"))
7188         is_add = 0;
7189       else if (unformat (i, "vrf %d", &vrf_id))
7190         ;
7191       else if (unformat (i, "insert-cid %d", &insert_cid))
7192         ;
7193       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7194         v4_address_set = 1;
7195       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7196         v6_address_set = 1;
7197       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7198         v4_src_address_set = 1;
7199       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7200         v6_src_address_set = 1;
7201       else
7202         break;
7203     }
7204
7205   if (v4_address_set && v6_address_set)
7206     {
7207       errmsg ("both v4 and v6 server addresses set");
7208       return -99;
7209     }
7210   if (!v4_address_set && !v6_address_set)
7211     {
7212       errmsg ("no server addresses set");
7213       return -99;
7214     }
7215
7216   if (v4_src_address_set && v6_src_address_set)
7217     {
7218       errmsg ("both v4 and v6  src addresses set");
7219       return -99;
7220     }
7221   if (!v4_src_address_set && !v6_src_address_set)
7222     {
7223       errmsg ("no src addresses set");
7224       return -99;
7225     }
7226
7227   if (!(v4_src_address_set && v4_address_set) &&
7228       !(v6_src_address_set && v6_address_set))
7229     {
7230       errmsg ("no matching server and src addresses set");
7231       return -99;
7232     }
7233
7234   /* Construct the API message */
7235   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7236
7237   mp->insert_circuit_id = insert_cid;
7238   mp->is_add = is_add;
7239   mp->vrf_id = ntohl (vrf_id);
7240   if (v6_address_set)
7241     {
7242       mp->is_ipv6 = 1;
7243       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7244       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7245     }
7246   else
7247     {
7248       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7249       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7250     }
7251
7252   /* send it... */
7253   S;
7254
7255   /* Wait for a reply, return good/bad news  */
7256   W;
7257   /* NOTREACHED */
7258   return 0;
7259 }
7260
7261 static int
7262 api_dhcp_proxy_config_2 (vat_main_t * vam)
7263 {
7264   unformat_input_t *i = vam->input;
7265   vl_api_dhcp_proxy_config_2_t *mp;
7266   f64 timeout;
7267   u32 rx_vrf_id = 0;
7268   u32 server_vrf_id = 0;
7269   u8 is_add = 1;
7270   u8 insert_cid = 1;
7271   u8 v4_address_set = 0;
7272   u8 v6_address_set = 0;
7273   ip4_address_t v4address;
7274   ip6_address_t v6address;
7275   u8 v4_src_address_set = 0;
7276   u8 v6_src_address_set = 0;
7277   ip4_address_t v4srcaddress;
7278   ip6_address_t v6srcaddress;
7279
7280   /* Parse args required to build the message */
7281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7282     {
7283       if (unformat (i, "del"))
7284         is_add = 0;
7285       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7286         ;
7287       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7288         ;
7289       else if (unformat (i, "insert-cid %d", &insert_cid))
7290         ;
7291       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7292         v4_address_set = 1;
7293       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7294         v6_address_set = 1;
7295       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7296         v4_src_address_set = 1;
7297       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7298         v6_src_address_set = 1;
7299       else
7300         break;
7301     }
7302
7303   if (v4_address_set && v6_address_set)
7304     {
7305       errmsg ("both v4 and v6 server addresses set");
7306       return -99;
7307     }
7308   if (!v4_address_set && !v6_address_set)
7309     {
7310       errmsg ("no server addresses set");
7311       return -99;
7312     }
7313
7314   if (v4_src_address_set && v6_src_address_set)
7315     {
7316       errmsg ("both v4 and v6  src addresses set");
7317       return -99;
7318     }
7319   if (!v4_src_address_set && !v6_src_address_set)
7320     {
7321       errmsg ("no src addresses set");
7322       return -99;
7323     }
7324
7325   if (!(v4_src_address_set && v4_address_set) &&
7326       !(v6_src_address_set && v6_address_set))
7327     {
7328       errmsg ("no matching server and src addresses set");
7329       return -99;
7330     }
7331
7332   /* Construct the API message */
7333   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7334
7335   mp->insert_circuit_id = insert_cid;
7336   mp->is_add = is_add;
7337   mp->rx_vrf_id = ntohl (rx_vrf_id);
7338   mp->server_vrf_id = ntohl (server_vrf_id);
7339   if (v6_address_set)
7340     {
7341       mp->is_ipv6 = 1;
7342       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7343       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7344     }
7345   else
7346     {
7347       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7348       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7349     }
7350
7351   /* send it... */
7352   S;
7353
7354   /* Wait for a reply, return good/bad news  */
7355   W;
7356   /* NOTREACHED */
7357   return 0;
7358 }
7359
7360 static int
7361 api_dhcp_proxy_set_vss (vat_main_t * vam)
7362 {
7363   unformat_input_t *i = vam->input;
7364   vl_api_dhcp_proxy_set_vss_t *mp;
7365   f64 timeout;
7366   u8 is_ipv6 = 0;
7367   u8 is_add = 1;
7368   u32 tbl_id;
7369   u8 tbl_id_set = 0;
7370   u32 oui;
7371   u8 oui_set = 0;
7372   u32 fib_id;
7373   u8 fib_id_set = 0;
7374
7375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7376     {
7377       if (unformat (i, "tbl_id %d", &tbl_id))
7378         tbl_id_set = 1;
7379       if (unformat (i, "fib_id %d", &fib_id))
7380         fib_id_set = 1;
7381       if (unformat (i, "oui %d", &oui))
7382         oui_set = 1;
7383       else if (unformat (i, "ipv6"))
7384         is_ipv6 = 1;
7385       else if (unformat (i, "del"))
7386         is_add = 0;
7387       else
7388         {
7389           clib_warning ("parse error '%U'", format_unformat_error, i);
7390           return -99;
7391         }
7392     }
7393
7394   if (tbl_id_set == 0)
7395     {
7396       errmsg ("missing tbl id");
7397       return -99;
7398     }
7399
7400   if (fib_id_set == 0)
7401     {
7402       errmsg ("missing fib id");
7403       return -99;
7404     }
7405   if (oui_set == 0)
7406     {
7407       errmsg ("missing oui");
7408       return -99;
7409     }
7410
7411   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7412   mp->tbl_id = ntohl (tbl_id);
7413   mp->fib_id = ntohl (fib_id);
7414   mp->oui = ntohl (oui);
7415   mp->is_ipv6 = is_ipv6;
7416   mp->is_add = is_add;
7417
7418   S;
7419   W;
7420   /* NOTREACHED */
7421   return 0;
7422 }
7423
7424 static int
7425 api_dhcp_client_config (vat_main_t * vam)
7426 {
7427   unformat_input_t *i = vam->input;
7428   vl_api_dhcp_client_config_t *mp;
7429   f64 timeout;
7430   u32 sw_if_index;
7431   u8 sw_if_index_set = 0;
7432   u8 is_add = 1;
7433   u8 *hostname = 0;
7434   u8 disable_event = 0;
7435
7436   /* Parse args required to build the message */
7437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7438     {
7439       if (unformat (i, "del"))
7440         is_add = 0;
7441       else
7442         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7443         sw_if_index_set = 1;
7444       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7445         sw_if_index_set = 1;
7446       else if (unformat (i, "hostname %s", &hostname))
7447         ;
7448       else if (unformat (i, "disable_event"))
7449         disable_event = 1;
7450       else
7451         break;
7452     }
7453
7454   if (sw_if_index_set == 0)
7455     {
7456       errmsg ("missing interface name or sw_if_index");
7457       return -99;
7458     }
7459
7460   if (vec_len (hostname) > 63)
7461     {
7462       errmsg ("hostname too long");
7463     }
7464   vec_add1 (hostname, 0);
7465
7466   /* Construct the API message */
7467   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7468
7469   mp->sw_if_index = ntohl (sw_if_index);
7470   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7471   vec_free (hostname);
7472   mp->is_add = is_add;
7473   mp->want_dhcp_event = disable_event ? 0 : 1;
7474   mp->pid = getpid ();
7475
7476   /* send it... */
7477   S;
7478
7479   /* Wait for a reply, return good/bad news  */
7480   W;
7481   /* NOTREACHED */
7482   return 0;
7483 }
7484
7485 static int
7486 api_set_ip_flow_hash (vat_main_t * vam)
7487 {
7488   unformat_input_t *i = vam->input;
7489   vl_api_set_ip_flow_hash_t *mp;
7490   f64 timeout;
7491   u32 vrf_id = 0;
7492   u8 is_ipv6 = 0;
7493   u8 vrf_id_set = 0;
7494   u8 src = 0;
7495   u8 dst = 0;
7496   u8 sport = 0;
7497   u8 dport = 0;
7498   u8 proto = 0;
7499   u8 reverse = 0;
7500
7501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7502     {
7503       if (unformat (i, "vrf %d", &vrf_id))
7504         vrf_id_set = 1;
7505       else if (unformat (i, "ipv6"))
7506         is_ipv6 = 1;
7507       else if (unformat (i, "src"))
7508         src = 1;
7509       else if (unformat (i, "dst"))
7510         dst = 1;
7511       else if (unformat (i, "sport"))
7512         sport = 1;
7513       else if (unformat (i, "dport"))
7514         dport = 1;
7515       else if (unformat (i, "proto"))
7516         proto = 1;
7517       else if (unformat (i, "reverse"))
7518         reverse = 1;
7519
7520       else
7521         {
7522           clib_warning ("parse error '%U'", format_unformat_error, i);
7523           return -99;
7524         }
7525     }
7526
7527   if (vrf_id_set == 0)
7528     {
7529       errmsg ("missing vrf id");
7530       return -99;
7531     }
7532
7533   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7534   mp->src = src;
7535   mp->dst = dst;
7536   mp->sport = sport;
7537   mp->dport = dport;
7538   mp->proto = proto;
7539   mp->reverse = reverse;
7540   mp->vrf_id = ntohl (vrf_id);
7541   mp->is_ipv6 = is_ipv6;
7542
7543   S;
7544   W;
7545   /* NOTREACHED */
7546   return 0;
7547 }
7548
7549 static int
7550 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7551 {
7552   unformat_input_t *i = vam->input;
7553   vl_api_sw_interface_ip6_enable_disable_t *mp;
7554   f64 timeout;
7555   u32 sw_if_index;
7556   u8 sw_if_index_set = 0;
7557   u8 enable = 0;
7558
7559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7560     {
7561       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7562         sw_if_index_set = 1;
7563       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7564         sw_if_index_set = 1;
7565       else if (unformat (i, "enable"))
7566         enable = 1;
7567       else if (unformat (i, "disable"))
7568         enable = 0;
7569       else
7570         {
7571           clib_warning ("parse error '%U'", format_unformat_error, i);
7572           return -99;
7573         }
7574     }
7575
7576   if (sw_if_index_set == 0)
7577     {
7578       errmsg ("missing interface name or sw_if_index");
7579       return -99;
7580     }
7581
7582   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7583
7584   mp->sw_if_index = ntohl (sw_if_index);
7585   mp->enable = enable;
7586
7587   S;
7588   W;
7589   /* NOTREACHED */
7590   return 0;
7591 }
7592
7593 static int
7594 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7595 {
7596   unformat_input_t *i = vam->input;
7597   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7598   f64 timeout;
7599   u32 sw_if_index;
7600   u8 sw_if_index_set = 0;
7601   u8 v6_address_set = 0;
7602   ip6_address_t v6address;
7603
7604   /* Parse args required to build the message */
7605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7606     {
7607       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7608         sw_if_index_set = 1;
7609       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7610         sw_if_index_set = 1;
7611       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
7612         v6_address_set = 1;
7613       else
7614         break;
7615     }
7616
7617   if (sw_if_index_set == 0)
7618     {
7619       errmsg ("missing interface name or sw_if_index");
7620       return -99;
7621     }
7622   if (!v6_address_set)
7623     {
7624       errmsg ("no address set");
7625       return -99;
7626     }
7627
7628   /* Construct the API message */
7629   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7630      sw_interface_ip6_set_link_local_address);
7631
7632   mp->sw_if_index = ntohl (sw_if_index);
7633   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7634
7635   /* send it... */
7636   S;
7637
7638   /* Wait for a reply, return good/bad news  */
7639   W;
7640
7641   /* NOTREACHED */
7642   return 0;
7643 }
7644
7645
7646 static int
7647 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7648 {
7649   unformat_input_t *i = vam->input;
7650   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7651   f64 timeout;
7652   u32 sw_if_index;
7653   u8 sw_if_index_set = 0;
7654   u32 address_length = 0;
7655   u8 v6_address_set = 0;
7656   ip6_address_t v6address;
7657   u8 use_default = 0;
7658   u8 no_advertise = 0;
7659   u8 off_link = 0;
7660   u8 no_autoconfig = 0;
7661   u8 no_onlink = 0;
7662   u8 is_no = 0;
7663   u32 val_lifetime = 0;
7664   u32 pref_lifetime = 0;
7665
7666   /* Parse args required to build the message */
7667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7668     {
7669       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7670         sw_if_index_set = 1;
7671       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7672         sw_if_index_set = 1;
7673       else if (unformat (i, "%U/%d",
7674                          unformat_ip6_address, &v6address, &address_length))
7675         v6_address_set = 1;
7676       else if (unformat (i, "val_life %d", &val_lifetime))
7677         ;
7678       else if (unformat (i, "pref_life %d", &pref_lifetime))
7679         ;
7680       else if (unformat (i, "def"))
7681         use_default = 1;
7682       else if (unformat (i, "noadv"))
7683         no_advertise = 1;
7684       else if (unformat (i, "offl"))
7685         off_link = 1;
7686       else if (unformat (i, "noauto"))
7687         no_autoconfig = 1;
7688       else if (unformat (i, "nolink"))
7689         no_onlink = 1;
7690       else if (unformat (i, "isno"))
7691         is_no = 1;
7692       else
7693         {
7694           clib_warning ("parse error '%U'", format_unformat_error, i);
7695           return -99;
7696         }
7697     }
7698
7699   if (sw_if_index_set == 0)
7700     {
7701       errmsg ("missing interface name or sw_if_index");
7702       return -99;
7703     }
7704   if (!v6_address_set)
7705     {
7706       errmsg ("no address set");
7707       return -99;
7708     }
7709
7710   /* Construct the API message */
7711   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7712
7713   mp->sw_if_index = ntohl (sw_if_index);
7714   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7715   mp->address_length = address_length;
7716   mp->use_default = use_default;
7717   mp->no_advertise = no_advertise;
7718   mp->off_link = off_link;
7719   mp->no_autoconfig = no_autoconfig;
7720   mp->no_onlink = no_onlink;
7721   mp->is_no = is_no;
7722   mp->val_lifetime = ntohl (val_lifetime);
7723   mp->pref_lifetime = ntohl (pref_lifetime);
7724
7725   /* send it... */
7726   S;
7727
7728   /* Wait for a reply, return good/bad news  */
7729   W;
7730
7731   /* NOTREACHED */
7732   return 0;
7733 }
7734
7735 static int
7736 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7737 {
7738   unformat_input_t *i = vam->input;
7739   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7740   f64 timeout;
7741   u32 sw_if_index;
7742   u8 sw_if_index_set = 0;
7743   u8 suppress = 0;
7744   u8 managed = 0;
7745   u8 other = 0;
7746   u8 ll_option = 0;
7747   u8 send_unicast = 0;
7748   u8 cease = 0;
7749   u8 is_no = 0;
7750   u8 default_router = 0;
7751   u32 max_interval = 0;
7752   u32 min_interval = 0;
7753   u32 lifetime = 0;
7754   u32 initial_count = 0;
7755   u32 initial_interval = 0;
7756
7757
7758   /* Parse args required to build the message */
7759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7760     {
7761       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7762         sw_if_index_set = 1;
7763       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7764         sw_if_index_set = 1;
7765       else if (unformat (i, "maxint %d", &max_interval))
7766         ;
7767       else if (unformat (i, "minint %d", &min_interval))
7768         ;
7769       else if (unformat (i, "life %d", &lifetime))
7770         ;
7771       else if (unformat (i, "count %d", &initial_count))
7772         ;
7773       else if (unformat (i, "interval %d", &initial_interval))
7774         ;
7775       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7776         suppress = 1;
7777       else if (unformat (i, "managed"))
7778         managed = 1;
7779       else if (unformat (i, "other"))
7780         other = 1;
7781       else if (unformat (i, "ll"))
7782         ll_option = 1;
7783       else if (unformat (i, "send"))
7784         send_unicast = 1;
7785       else if (unformat (i, "cease"))
7786         cease = 1;
7787       else if (unformat (i, "isno"))
7788         is_no = 1;
7789       else if (unformat (i, "def"))
7790         default_router = 1;
7791       else
7792         {
7793           clib_warning ("parse error '%U'", format_unformat_error, i);
7794           return -99;
7795         }
7796     }
7797
7798   if (sw_if_index_set == 0)
7799     {
7800       errmsg ("missing interface name or sw_if_index");
7801       return -99;
7802     }
7803
7804   /* Construct the API message */
7805   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7806
7807   mp->sw_if_index = ntohl (sw_if_index);
7808   mp->max_interval = ntohl (max_interval);
7809   mp->min_interval = ntohl (min_interval);
7810   mp->lifetime = ntohl (lifetime);
7811   mp->initial_count = ntohl (initial_count);
7812   mp->initial_interval = ntohl (initial_interval);
7813   mp->suppress = suppress;
7814   mp->managed = managed;
7815   mp->other = other;
7816   mp->ll_option = ll_option;
7817   mp->send_unicast = send_unicast;
7818   mp->cease = cease;
7819   mp->is_no = is_no;
7820   mp->default_router = default_router;
7821
7822   /* send it... */
7823   S;
7824
7825   /* Wait for a reply, return good/bad news  */
7826   W;
7827
7828   /* NOTREACHED */
7829   return 0;
7830 }
7831
7832 static int
7833 api_set_arp_neighbor_limit (vat_main_t * vam)
7834 {
7835   unformat_input_t *i = vam->input;
7836   vl_api_set_arp_neighbor_limit_t *mp;
7837   f64 timeout;
7838   u32 arp_nbr_limit;
7839   u8 limit_set = 0;
7840   u8 is_ipv6 = 0;
7841
7842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7843     {
7844       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7845         limit_set = 1;
7846       else if (unformat (i, "ipv6"))
7847         is_ipv6 = 1;
7848       else
7849         {
7850           clib_warning ("parse error '%U'", format_unformat_error, i);
7851           return -99;
7852         }
7853     }
7854
7855   if (limit_set == 0)
7856     {
7857       errmsg ("missing limit value");
7858       return -99;
7859     }
7860
7861   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7862
7863   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7864   mp->is_ipv6 = is_ipv6;
7865
7866   S;
7867   W;
7868   /* NOTREACHED */
7869   return 0;
7870 }
7871
7872 static int
7873 api_l2_patch_add_del (vat_main_t * vam)
7874 {
7875   unformat_input_t *i = vam->input;
7876   vl_api_l2_patch_add_del_t *mp;
7877   f64 timeout;
7878   u32 rx_sw_if_index;
7879   u8 rx_sw_if_index_set = 0;
7880   u32 tx_sw_if_index;
7881   u8 tx_sw_if_index_set = 0;
7882   u8 is_add = 1;
7883
7884   /* Parse args required to build the message */
7885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7886     {
7887       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7888         rx_sw_if_index_set = 1;
7889       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7890         tx_sw_if_index_set = 1;
7891       else if (unformat (i, "rx"))
7892         {
7893           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7894             {
7895               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7896                             &rx_sw_if_index))
7897                 rx_sw_if_index_set = 1;
7898             }
7899           else
7900             break;
7901         }
7902       else if (unformat (i, "tx"))
7903         {
7904           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7905             {
7906               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7907                             &tx_sw_if_index))
7908                 tx_sw_if_index_set = 1;
7909             }
7910           else
7911             break;
7912         }
7913       else if (unformat (i, "del"))
7914         is_add = 0;
7915       else
7916         break;
7917     }
7918
7919   if (rx_sw_if_index_set == 0)
7920     {
7921       errmsg ("missing rx interface name or rx_sw_if_index");
7922       return -99;
7923     }
7924
7925   if (tx_sw_if_index_set == 0)
7926     {
7927       errmsg ("missing tx interface name or tx_sw_if_index");
7928       return -99;
7929     }
7930
7931   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7932
7933   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7934   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7935   mp->is_add = is_add;
7936
7937   S;
7938   W;
7939   /* NOTREACHED */
7940   return 0;
7941 }
7942
7943 static int
7944 api_ioam_enable (vat_main_t * vam)
7945 {
7946   unformat_input_t *input = vam->input;
7947   vl_api_ioam_enable_t *mp;
7948   f64 timeout;
7949   u32 id = 0;
7950   int has_trace_option = 0;
7951   int has_pot_option = 0;
7952   int has_seqno_option = 0;
7953   int has_analyse_option = 0;
7954
7955   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7956     {
7957       if (unformat (input, "trace"))
7958         has_trace_option = 1;
7959       else if (unformat (input, "pot"))
7960         has_pot_option = 1;
7961       else if (unformat (input, "seqno"))
7962         has_seqno_option = 1;
7963       else if (unformat (input, "analyse"))
7964         has_analyse_option = 1;
7965       else
7966         break;
7967     }
7968   M (IOAM_ENABLE, ioam_enable);
7969   mp->id = htons (id);
7970   mp->seqno = has_seqno_option;
7971   mp->analyse = has_analyse_option;
7972   mp->pot_enable = has_pot_option;
7973   mp->trace_enable = has_trace_option;
7974
7975   S;
7976   W;
7977
7978   return (0);
7979
7980 }
7981
7982
7983 static int
7984 api_ioam_disable (vat_main_t * vam)
7985 {
7986   vl_api_ioam_disable_t *mp;
7987   f64 timeout;
7988
7989   M (IOAM_DISABLE, ioam_disable);
7990   S;
7991   W;
7992   return 0;
7993 }
7994
7995 static int
7996 api_sr_tunnel_add_del (vat_main_t * vam)
7997 {
7998   unformat_input_t *i = vam->input;
7999   vl_api_sr_tunnel_add_del_t *mp;
8000   f64 timeout;
8001   int is_del = 0;
8002   int pl_index;
8003   ip6_address_t src_address;
8004   int src_address_set = 0;
8005   ip6_address_t dst_address;
8006   u32 dst_mask_width;
8007   int dst_address_set = 0;
8008   u16 flags = 0;
8009   u32 rx_table_id = 0;
8010   u32 tx_table_id = 0;
8011   ip6_address_t *segments = 0;
8012   ip6_address_t *this_seg;
8013   ip6_address_t *tags = 0;
8014   ip6_address_t *this_tag;
8015   ip6_address_t next_address, tag;
8016   u8 *name = 0;
8017   u8 *policy_name = 0;
8018
8019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8020     {
8021       if (unformat (i, "del"))
8022         is_del = 1;
8023       else if (unformat (i, "name %s", &name))
8024         ;
8025       else if (unformat (i, "policy %s", &policy_name))
8026         ;
8027       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8028         ;
8029       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8030         ;
8031       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8032         src_address_set = 1;
8033       else if (unformat (i, "dst %U/%d",
8034                          unformat_ip6_address, &dst_address, &dst_mask_width))
8035         dst_address_set = 1;
8036       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8037         {
8038           vec_add2 (segments, this_seg, 1);
8039           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8040                        sizeof (*this_seg));
8041         }
8042       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8043         {
8044           vec_add2 (tags, this_tag, 1);
8045           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8046         }
8047       else if (unformat (i, "clean"))
8048         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8049       else if (unformat (i, "protected"))
8050         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8051       else if (unformat (i, "InPE %d", &pl_index))
8052         {
8053           if (pl_index <= 0 || pl_index > 4)
8054             {
8055             pl_index_range_error:
8056               errmsg ("pl index %d out of range", pl_index);
8057               return -99;
8058             }
8059           flags |=
8060             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8061         }
8062       else if (unformat (i, "EgPE %d", &pl_index))
8063         {
8064           if (pl_index <= 0 || pl_index > 4)
8065             goto pl_index_range_error;
8066           flags |=
8067             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8068         }
8069       else if (unformat (i, "OrgSrc %d", &pl_index))
8070         {
8071           if (pl_index <= 0 || pl_index > 4)
8072             goto pl_index_range_error;
8073           flags |=
8074             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8075         }
8076       else
8077         break;
8078     }
8079
8080   if (!src_address_set)
8081     {
8082       errmsg ("src address required");
8083       return -99;
8084     }
8085
8086   if (!dst_address_set)
8087     {
8088       errmsg ("dst address required");
8089       return -99;
8090     }
8091
8092   if (!segments)
8093     {
8094       errmsg ("at least one sr segment required");
8095       return -99;
8096     }
8097
8098   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
8099       vec_len (segments) * sizeof (ip6_address_t)
8100       + vec_len (tags) * sizeof (ip6_address_t));
8101
8102   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8103   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8104   mp->dst_mask_width = dst_mask_width;
8105   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8106   mp->n_segments = vec_len (segments);
8107   mp->n_tags = vec_len (tags);
8108   mp->is_add = is_del == 0;
8109   clib_memcpy (mp->segs_and_tags, segments,
8110                vec_len (segments) * sizeof (ip6_address_t));
8111   clib_memcpy (mp->segs_and_tags +
8112                vec_len (segments) * sizeof (ip6_address_t), tags,
8113                vec_len (tags) * sizeof (ip6_address_t));
8114
8115   mp->outer_vrf_id = ntohl (rx_table_id);
8116   mp->inner_vrf_id = ntohl (tx_table_id);
8117   memcpy (mp->name, name, vec_len (name));
8118   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8119
8120   vec_free (segments);
8121   vec_free (tags);
8122
8123   S;
8124   W;
8125   /* NOTREACHED */
8126 }
8127
8128 static int
8129 api_sr_policy_add_del (vat_main_t * vam)
8130 {
8131   unformat_input_t *input = vam->input;
8132   vl_api_sr_policy_add_del_t *mp;
8133   f64 timeout;
8134   int is_del = 0;
8135   u8 *name = 0;
8136   u8 *tunnel_name = 0;
8137   u8 **tunnel_names = 0;
8138
8139   int name_set = 0;
8140   int tunnel_set = 0;
8141   int j = 0;
8142   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8143   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8144
8145   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8146     {
8147       if (unformat (input, "del"))
8148         is_del = 1;
8149       else if (unformat (input, "name %s", &name))
8150         name_set = 1;
8151       else if (unformat (input, "tunnel %s", &tunnel_name))
8152         {
8153           if (tunnel_name)
8154             {
8155               vec_add1 (tunnel_names, tunnel_name);
8156               /* For serializer:
8157                  - length = #bytes to store in serial vector
8158                  - +1 = byte to store that length
8159                */
8160               tunnel_names_length += (vec_len (tunnel_name) + 1);
8161               tunnel_set = 1;
8162               tunnel_name = 0;
8163             }
8164         }
8165       else
8166         break;
8167     }
8168
8169   if (!name_set)
8170     {
8171       errmsg ("policy name required");
8172       return -99;
8173     }
8174
8175   if ((!tunnel_set) && (!is_del))
8176     {
8177       errmsg ("tunnel name required");
8178       return -99;
8179     }
8180
8181   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8182
8183
8184
8185   mp->is_add = !is_del;
8186
8187   memcpy (mp->name, name, vec_len (name));
8188   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8189   u8 *serial_orig = 0;
8190   vec_validate (serial_orig, tunnel_names_length);
8191   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8192   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8193
8194   for (j = 0; j < vec_len (tunnel_names); j++)
8195     {
8196       tun_name_len = vec_len (tunnel_names[j]);
8197       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8198       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8199       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8200       serial_orig += tun_name_len;      // Advance past the copy
8201     }
8202   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8203
8204   vec_free (tunnel_names);
8205   vec_free (tunnel_name);
8206
8207   S;
8208   W;
8209   /* NOTREACHED */
8210 }
8211
8212 static int
8213 api_sr_multicast_map_add_del (vat_main_t * vam)
8214 {
8215   unformat_input_t *input = vam->input;
8216   vl_api_sr_multicast_map_add_del_t *mp;
8217   f64 timeout;
8218   int is_del = 0;
8219   ip6_address_t multicast_address;
8220   u8 *policy_name = 0;
8221   int multicast_address_set = 0;
8222
8223   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8224     {
8225       if (unformat (input, "del"))
8226         is_del = 1;
8227       else
8228         if (unformat
8229             (input, "address %U", unformat_ip6_address, &multicast_address))
8230         multicast_address_set = 1;
8231       else if (unformat (input, "sr-policy %s", &policy_name))
8232         ;
8233       else
8234         break;
8235     }
8236
8237   if (!is_del && !policy_name)
8238     {
8239       errmsg ("sr-policy name required");
8240       return -99;
8241     }
8242
8243
8244   if (!multicast_address_set)
8245     {
8246       errmsg ("address required");
8247       return -99;
8248     }
8249
8250   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8251
8252   mp->is_add = !is_del;
8253   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8254   clib_memcpy (mp->multicast_address, &multicast_address,
8255                sizeof (mp->multicast_address));
8256
8257
8258   vec_free (policy_name);
8259
8260   S;
8261   W;
8262   /* NOTREACHED */
8263 }
8264
8265
8266 #define foreach_tcp_proto_field                 \
8267 _(src_port)                                     \
8268 _(dst_port)
8269
8270 #define foreach_udp_proto_field                 \
8271 _(src_port)                                     \
8272 _(dst_port)
8273
8274 #define foreach_ip4_proto_field                 \
8275 _(src_address)                                  \
8276 _(dst_address)                                  \
8277 _(tos)                                          \
8278 _(length)                                       \
8279 _(fragment_id)                                  \
8280 _(ttl)                                          \
8281 _(protocol)                                     \
8282 _(checksum)
8283
8284 uword
8285 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8286 {
8287   u8 **maskp = va_arg (*args, u8 **);
8288   u8 *mask = 0;
8289   u8 found_something = 0;
8290   tcp_header_t *tcp;
8291
8292 #define _(a) u8 a=0;
8293   foreach_tcp_proto_field;
8294 #undef _
8295
8296   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8297     {
8298       if (0);
8299 #define _(a) else if (unformat (input, #a)) a=1;
8300       foreach_tcp_proto_field
8301 #undef _
8302         else
8303         break;
8304     }
8305
8306 #define _(a) found_something += a;
8307   foreach_tcp_proto_field;
8308 #undef _
8309
8310   if (found_something == 0)
8311     return 0;
8312
8313   vec_validate (mask, sizeof (*tcp) - 1);
8314
8315   tcp = (tcp_header_t *) mask;
8316
8317 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8318   foreach_tcp_proto_field;
8319 #undef _
8320
8321   *maskp = mask;
8322   return 1;
8323 }
8324
8325 uword
8326 unformat_udp_mask (unformat_input_t * input, va_list * args)
8327 {
8328   u8 **maskp = va_arg (*args, u8 **);
8329   u8 *mask = 0;
8330   u8 found_something = 0;
8331   udp_header_t *udp;
8332
8333 #define _(a) u8 a=0;
8334   foreach_udp_proto_field;
8335 #undef _
8336
8337   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8338     {
8339       if (0);
8340 #define _(a) else if (unformat (input, #a)) a=1;
8341       foreach_udp_proto_field
8342 #undef _
8343         else
8344         break;
8345     }
8346
8347 #define _(a) found_something += a;
8348   foreach_udp_proto_field;
8349 #undef _
8350
8351   if (found_something == 0)
8352     return 0;
8353
8354   vec_validate (mask, sizeof (*udp) - 1);
8355
8356   udp = (udp_header_t *) mask;
8357
8358 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8359   foreach_udp_proto_field;
8360 #undef _
8361
8362   *maskp = mask;
8363   return 1;
8364 }
8365
8366 typedef struct
8367 {
8368   u16 src_port, dst_port;
8369 } tcpudp_header_t;
8370
8371 uword
8372 unformat_l4_mask (unformat_input_t * input, va_list * args)
8373 {
8374   u8 **maskp = va_arg (*args, u8 **);
8375   u16 src_port = 0, dst_port = 0;
8376   tcpudp_header_t *tcpudp;
8377
8378   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8379     {
8380       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8381         return 1;
8382       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8383         return 1;
8384       else if (unformat (input, "src_port"))
8385         src_port = 0xFFFF;
8386       else if (unformat (input, "dst_port"))
8387         dst_port = 0xFFFF;
8388       else
8389         return 0;
8390     }
8391
8392   if (!src_port && !dst_port)
8393     return 0;
8394
8395   u8 *mask = 0;
8396   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8397
8398   tcpudp = (tcpudp_header_t *) mask;
8399   tcpudp->src_port = src_port;
8400   tcpudp->dst_port = dst_port;
8401
8402   *maskp = mask;
8403
8404   return 1;
8405 }
8406
8407 uword
8408 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8409 {
8410   u8 **maskp = va_arg (*args, u8 **);
8411   u8 *mask = 0;
8412   u8 found_something = 0;
8413   ip4_header_t *ip;
8414
8415 #define _(a) u8 a=0;
8416   foreach_ip4_proto_field;
8417 #undef _
8418   u8 version = 0;
8419   u8 hdr_length = 0;
8420
8421
8422   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8423     {
8424       if (unformat (input, "version"))
8425         version = 1;
8426       else if (unformat (input, "hdr_length"))
8427         hdr_length = 1;
8428       else if (unformat (input, "src"))
8429         src_address = 1;
8430       else if (unformat (input, "dst"))
8431         dst_address = 1;
8432       else if (unformat (input, "proto"))
8433         protocol = 1;
8434
8435 #define _(a) else if (unformat (input, #a)) a=1;
8436       foreach_ip4_proto_field
8437 #undef _
8438         else
8439         break;
8440     }
8441
8442 #define _(a) found_something += a;
8443   foreach_ip4_proto_field;
8444 #undef _
8445
8446   if (found_something == 0)
8447     return 0;
8448
8449   vec_validate (mask, sizeof (*ip) - 1);
8450
8451   ip = (ip4_header_t *) mask;
8452
8453 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8454   foreach_ip4_proto_field;
8455 #undef _
8456
8457   ip->ip_version_and_header_length = 0;
8458
8459   if (version)
8460     ip->ip_version_and_header_length |= 0xF0;
8461
8462   if (hdr_length)
8463     ip->ip_version_and_header_length |= 0x0F;
8464
8465   *maskp = mask;
8466   return 1;
8467 }
8468
8469 #define foreach_ip6_proto_field                 \
8470 _(src_address)                                  \
8471 _(dst_address)                                  \
8472 _(payload_length)                               \
8473 _(hop_limit)                                    \
8474 _(protocol)
8475
8476 uword
8477 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8478 {
8479   u8 **maskp = va_arg (*args, u8 **);
8480   u8 *mask = 0;
8481   u8 found_something = 0;
8482   ip6_header_t *ip;
8483   u32 ip_version_traffic_class_and_flow_label;
8484
8485 #define _(a) u8 a=0;
8486   foreach_ip6_proto_field;
8487 #undef _
8488   u8 version = 0;
8489   u8 traffic_class = 0;
8490   u8 flow_label = 0;
8491
8492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8493     {
8494       if (unformat (input, "version"))
8495         version = 1;
8496       else if (unformat (input, "traffic-class"))
8497         traffic_class = 1;
8498       else if (unformat (input, "flow-label"))
8499         flow_label = 1;
8500       else if (unformat (input, "src"))
8501         src_address = 1;
8502       else if (unformat (input, "dst"))
8503         dst_address = 1;
8504       else if (unformat (input, "proto"))
8505         protocol = 1;
8506
8507 #define _(a) else if (unformat (input, #a)) a=1;
8508       foreach_ip6_proto_field
8509 #undef _
8510         else
8511         break;
8512     }
8513
8514 #define _(a) found_something += a;
8515   foreach_ip6_proto_field;
8516 #undef _
8517
8518   if (found_something == 0)
8519     return 0;
8520
8521   vec_validate (mask, sizeof (*ip) - 1);
8522
8523   ip = (ip6_header_t *) mask;
8524
8525 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8526   foreach_ip6_proto_field;
8527 #undef _
8528
8529   ip_version_traffic_class_and_flow_label = 0;
8530
8531   if (version)
8532     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8533
8534   if (traffic_class)
8535     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8536
8537   if (flow_label)
8538     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8539
8540   ip->ip_version_traffic_class_and_flow_label =
8541     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8542
8543   *maskp = mask;
8544   return 1;
8545 }
8546
8547 uword
8548 unformat_l3_mask (unformat_input_t * input, va_list * args)
8549 {
8550   u8 **maskp = va_arg (*args, u8 **);
8551
8552   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8553     {
8554       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8555         return 1;
8556       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8557         return 1;
8558       else
8559         break;
8560     }
8561   return 0;
8562 }
8563
8564 uword
8565 unformat_l2_mask (unformat_input_t * input, va_list * args)
8566 {
8567   u8 **maskp = va_arg (*args, u8 **);
8568   u8 *mask = 0;
8569   u8 src = 0;
8570   u8 dst = 0;
8571   u8 proto = 0;
8572   u8 tag1 = 0;
8573   u8 tag2 = 0;
8574   u8 ignore_tag1 = 0;
8575   u8 ignore_tag2 = 0;
8576   u8 cos1 = 0;
8577   u8 cos2 = 0;
8578   u8 dot1q = 0;
8579   u8 dot1ad = 0;
8580   int len = 14;
8581
8582   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8583     {
8584       if (unformat (input, "src"))
8585         src = 1;
8586       else if (unformat (input, "dst"))
8587         dst = 1;
8588       else if (unformat (input, "proto"))
8589         proto = 1;
8590       else if (unformat (input, "tag1"))
8591         tag1 = 1;
8592       else if (unformat (input, "tag2"))
8593         tag2 = 1;
8594       else if (unformat (input, "ignore-tag1"))
8595         ignore_tag1 = 1;
8596       else if (unformat (input, "ignore-tag2"))
8597         ignore_tag2 = 1;
8598       else if (unformat (input, "cos1"))
8599         cos1 = 1;
8600       else if (unformat (input, "cos2"))
8601         cos2 = 1;
8602       else if (unformat (input, "dot1q"))
8603         dot1q = 1;
8604       else if (unformat (input, "dot1ad"))
8605         dot1ad = 1;
8606       else
8607         break;
8608     }
8609   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8610        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8611     return 0;
8612
8613   if (tag1 || ignore_tag1 || cos1 || dot1q)
8614     len = 18;
8615   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8616     len = 22;
8617
8618   vec_validate (mask, len - 1);
8619
8620   if (dst)
8621     memset (mask, 0xff, 6);
8622
8623   if (src)
8624     memset (mask + 6, 0xff, 6);
8625
8626   if (tag2 || dot1ad)
8627     {
8628       /* inner vlan tag */
8629       if (tag2)
8630         {
8631           mask[19] = 0xff;
8632           mask[18] = 0x0f;
8633         }
8634       if (cos2)
8635         mask[18] |= 0xe0;
8636       if (proto)
8637         mask[21] = mask[20] = 0xff;
8638       if (tag1)
8639         {
8640           mask[15] = 0xff;
8641           mask[14] = 0x0f;
8642         }
8643       if (cos1)
8644         mask[14] |= 0xe0;
8645       *maskp = mask;
8646       return 1;
8647     }
8648   if (tag1 | dot1q)
8649     {
8650       if (tag1)
8651         {
8652           mask[15] = 0xff;
8653           mask[14] = 0x0f;
8654         }
8655       if (cos1)
8656         mask[14] |= 0xe0;
8657       if (proto)
8658         mask[16] = mask[17] = 0xff;
8659
8660       *maskp = mask;
8661       return 1;
8662     }
8663   if (cos2)
8664     mask[18] |= 0xe0;
8665   if (cos1)
8666     mask[14] |= 0xe0;
8667   if (proto)
8668     mask[12] = mask[13] = 0xff;
8669
8670   *maskp = mask;
8671   return 1;
8672 }
8673
8674 uword
8675 unformat_classify_mask (unformat_input_t * input, va_list * args)
8676 {
8677   u8 **maskp = va_arg (*args, u8 **);
8678   u32 *skipp = va_arg (*args, u32 *);
8679   u32 *matchp = va_arg (*args, u32 *);
8680   u32 match;
8681   u8 *mask = 0;
8682   u8 *l2 = 0;
8683   u8 *l3 = 0;
8684   u8 *l4 = 0;
8685   int i;
8686
8687   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8688     {
8689       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8690         ;
8691       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8692         ;
8693       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8694         ;
8695       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8696         ;
8697       else
8698         break;
8699     }
8700
8701   if (l4 && !l3)
8702     {
8703       vec_free (mask);
8704       vec_free (l2);
8705       vec_free (l4);
8706       return 0;
8707     }
8708
8709   if (mask || l2 || l3 || l4)
8710     {
8711       if (l2 || l3 || l4)
8712         {
8713           /* "With a free Ethernet header in every package" */
8714           if (l2 == 0)
8715             vec_validate (l2, 13);
8716           mask = l2;
8717           if (vec_len (l3))
8718             {
8719               vec_append (mask, l3);
8720               vec_free (l3);
8721             }
8722           if (vec_len (l4))
8723             {
8724               vec_append (mask, l4);
8725               vec_free (l4);
8726             }
8727         }
8728
8729       /* Scan forward looking for the first significant mask octet */
8730       for (i = 0; i < vec_len (mask); i++)
8731         if (mask[i])
8732           break;
8733
8734       /* compute (skip, match) params */
8735       *skipp = i / sizeof (u32x4);
8736       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8737
8738       /* Pad mask to an even multiple of the vector size */
8739       while (vec_len (mask) % sizeof (u32x4))
8740         vec_add1 (mask, 0);
8741
8742       match = vec_len (mask) / sizeof (u32x4);
8743
8744       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8745         {
8746           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8747           if (*tmp || *(tmp + 1))
8748             break;
8749           match--;
8750         }
8751       if (match == 0)
8752         clib_warning ("BUG: match 0");
8753
8754       _vec_len (mask) = match * sizeof (u32x4);
8755
8756       *matchp = match;
8757       *maskp = mask;
8758
8759       return 1;
8760     }
8761
8762   return 0;
8763 }
8764
8765 #define foreach_l2_next                         \
8766 _(drop, DROP)                                   \
8767 _(ethernet, ETHERNET_INPUT)                     \
8768 _(ip4, IP4_INPUT)                               \
8769 _(ip6, IP6_INPUT)
8770
8771 uword
8772 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8773 {
8774   u32 *miss_next_indexp = va_arg (*args, u32 *);
8775   u32 next_index = 0;
8776   u32 tmp;
8777
8778 #define _(n,N) \
8779   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8780   foreach_l2_next;
8781 #undef _
8782
8783   if (unformat (input, "%d", &tmp))
8784     {
8785       next_index = tmp;
8786       goto out;
8787     }
8788
8789   return 0;
8790
8791 out:
8792   *miss_next_indexp = next_index;
8793   return 1;
8794 }
8795
8796 #define foreach_ip_next                         \
8797 _(drop, DROP)                                   \
8798 _(local, LOCAL)                                 \
8799 _(rewrite, REWRITE)
8800
8801 uword
8802 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8803 {
8804   u32 *miss_next_indexp = va_arg (*args, u32 *);
8805   u32 next_index = 0;
8806   u32 tmp;
8807
8808 #define _(n,N) \
8809   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8810   foreach_ip_next;
8811 #undef _
8812
8813   if (unformat (input, "%d", &tmp))
8814     {
8815       next_index = tmp;
8816       goto out;
8817     }
8818
8819   return 0;
8820
8821 out:
8822   *miss_next_indexp = next_index;
8823   return 1;
8824 }
8825
8826 #define foreach_acl_next                        \
8827 _(deny, DENY)
8828
8829 uword
8830 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8831 {
8832   u32 *miss_next_indexp = va_arg (*args, u32 *);
8833   u32 next_index = 0;
8834   u32 tmp;
8835
8836 #define _(n,N) \
8837   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8838   foreach_acl_next;
8839 #undef _
8840
8841   if (unformat (input, "permit"))
8842     {
8843       next_index = ~0;
8844       goto out;
8845     }
8846   else 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 uword
8860 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8861 {
8862   u32 *r = va_arg (*args, u32 *);
8863
8864   if (unformat (input, "conform-color"))
8865     *r = POLICE_CONFORM;
8866   else if (unformat (input, "exceed-color"))
8867     *r = POLICE_EXCEED;
8868   else
8869     return 0;
8870
8871   return 1;
8872 }
8873
8874 static int
8875 api_classify_add_del_table (vat_main_t * vam)
8876 {
8877   unformat_input_t *i = vam->input;
8878   vl_api_classify_add_del_table_t *mp;
8879
8880   u32 nbuckets = 2;
8881   u32 skip = ~0;
8882   u32 match = ~0;
8883   int is_add = 1;
8884   int del_chain = 0;
8885   u32 table_index = ~0;
8886   u32 next_table_index = ~0;
8887   u32 miss_next_index = ~0;
8888   u32 memory_size = 32 << 20;
8889   u8 *mask = 0;
8890   f64 timeout;
8891   u32 current_data_flag = 0;
8892   int current_data_offset = 0;
8893
8894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8895     {
8896       if (unformat (i, "del"))
8897         is_add = 0;
8898       else if (unformat (i, "del-chain"))
8899         {
8900           is_add = 0;
8901           del_chain = 1;
8902         }
8903       else if (unformat (i, "buckets %d", &nbuckets))
8904         ;
8905       else if (unformat (i, "memory_size %d", &memory_size))
8906         ;
8907       else if (unformat (i, "skip %d", &skip))
8908         ;
8909       else if (unformat (i, "match %d", &match))
8910         ;
8911       else if (unformat (i, "table %d", &table_index))
8912         ;
8913       else if (unformat (i, "mask %U", unformat_classify_mask,
8914                          &mask, &skip, &match))
8915         ;
8916       else if (unformat (i, "next-table %d", &next_table_index))
8917         ;
8918       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8919                          &miss_next_index))
8920         ;
8921       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8922                          &miss_next_index))
8923         ;
8924       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8925                          &miss_next_index))
8926         ;
8927       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8928         ;
8929       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8930         ;
8931       else
8932         break;
8933     }
8934
8935   if (is_add && mask == 0)
8936     {
8937       errmsg ("Mask required");
8938       return -99;
8939     }
8940
8941   if (is_add && skip == ~0)
8942     {
8943       errmsg ("skip count required");
8944       return -99;
8945     }
8946
8947   if (is_add && match == ~0)
8948     {
8949       errmsg ("match count required");
8950       return -99;
8951     }
8952
8953   if (!is_add && table_index == ~0)
8954     {
8955       errmsg ("table index required for delete");
8956       return -99;
8957     }
8958
8959   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8960
8961   mp->is_add = is_add;
8962   mp->del_chain = del_chain;
8963   mp->table_index = ntohl (table_index);
8964   mp->nbuckets = ntohl (nbuckets);
8965   mp->memory_size = ntohl (memory_size);
8966   mp->skip_n_vectors = ntohl (skip);
8967   mp->match_n_vectors = ntohl (match);
8968   mp->next_table_index = ntohl (next_table_index);
8969   mp->miss_next_index = ntohl (miss_next_index);
8970   mp->current_data_flag = ntohl (current_data_flag);
8971   mp->current_data_offset = ntohl (current_data_offset);
8972   clib_memcpy (mp->mask, mask, vec_len (mask));
8973
8974   vec_free (mask);
8975
8976   S;
8977   W;
8978   /* NOTREACHED */
8979 }
8980
8981 uword
8982 unformat_l4_match (unformat_input_t * input, va_list * args)
8983 {
8984   u8 **matchp = va_arg (*args, u8 **);
8985
8986   u8 *proto_header = 0;
8987   int src_port = 0;
8988   int dst_port = 0;
8989
8990   tcpudp_header_t h;
8991
8992   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8993     {
8994       if (unformat (input, "src_port %d", &src_port))
8995         ;
8996       else if (unformat (input, "dst_port %d", &dst_port))
8997         ;
8998       else
8999         return 0;
9000     }
9001
9002   h.src_port = clib_host_to_net_u16 (src_port);
9003   h.dst_port = clib_host_to_net_u16 (dst_port);
9004   vec_validate (proto_header, sizeof (h) - 1);
9005   memcpy (proto_header, &h, sizeof (h));
9006
9007   *matchp = proto_header;
9008
9009   return 1;
9010 }
9011
9012 uword
9013 unformat_ip4_match (unformat_input_t * input, va_list * args)
9014 {
9015   u8 **matchp = va_arg (*args, u8 **);
9016   u8 *match = 0;
9017   ip4_header_t *ip;
9018   int version = 0;
9019   u32 version_val;
9020   int hdr_length = 0;
9021   u32 hdr_length_val;
9022   int src = 0, dst = 0;
9023   ip4_address_t src_val, dst_val;
9024   int proto = 0;
9025   u32 proto_val;
9026   int tos = 0;
9027   u32 tos_val;
9028   int length = 0;
9029   u32 length_val;
9030   int fragment_id = 0;
9031   u32 fragment_id_val;
9032   int ttl = 0;
9033   int ttl_val;
9034   int checksum = 0;
9035   u32 checksum_val;
9036
9037   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9038     {
9039       if (unformat (input, "version %d", &version_val))
9040         version = 1;
9041       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9042         hdr_length = 1;
9043       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9044         src = 1;
9045       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9046         dst = 1;
9047       else if (unformat (input, "proto %d", &proto_val))
9048         proto = 1;
9049       else if (unformat (input, "tos %d", &tos_val))
9050         tos = 1;
9051       else if (unformat (input, "length %d", &length_val))
9052         length = 1;
9053       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9054         fragment_id = 1;
9055       else if (unformat (input, "ttl %d", &ttl_val))
9056         ttl = 1;
9057       else if (unformat (input, "checksum %d", &checksum_val))
9058         checksum = 1;
9059       else
9060         break;
9061     }
9062
9063   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9064       + ttl + checksum == 0)
9065     return 0;
9066
9067   /*
9068    * Aligned because we use the real comparison functions
9069    */
9070   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9071
9072   ip = (ip4_header_t *) match;
9073
9074   /* These are realistically matched in practice */
9075   if (src)
9076     ip->src_address.as_u32 = src_val.as_u32;
9077
9078   if (dst)
9079     ip->dst_address.as_u32 = dst_val.as_u32;
9080
9081   if (proto)
9082     ip->protocol = proto_val;
9083
9084
9085   /* These are not, but they're included for completeness */
9086   if (version)
9087     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9088
9089   if (hdr_length)
9090     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9091
9092   if (tos)
9093     ip->tos = tos_val;
9094
9095   if (length)
9096     ip->length = clib_host_to_net_u16 (length_val);
9097
9098   if (ttl)
9099     ip->ttl = ttl_val;
9100
9101   if (checksum)
9102     ip->checksum = clib_host_to_net_u16 (checksum_val);
9103
9104   *matchp = match;
9105   return 1;
9106 }
9107
9108 uword
9109 unformat_ip6_match (unformat_input_t * input, va_list * args)
9110 {
9111   u8 **matchp = va_arg (*args, u8 **);
9112   u8 *match = 0;
9113   ip6_header_t *ip;
9114   int version = 0;
9115   u32 version_val;
9116   u8 traffic_class = 0;
9117   u32 traffic_class_val = 0;
9118   u8 flow_label = 0;
9119   u8 flow_label_val;
9120   int src = 0, dst = 0;
9121   ip6_address_t src_val, dst_val;
9122   int proto = 0;
9123   u32 proto_val;
9124   int payload_length = 0;
9125   u32 payload_length_val;
9126   int hop_limit = 0;
9127   int hop_limit_val;
9128   u32 ip_version_traffic_class_and_flow_label;
9129
9130   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9131     {
9132       if (unformat (input, "version %d", &version_val))
9133         version = 1;
9134       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9135         traffic_class = 1;
9136       else if (unformat (input, "flow_label %d", &flow_label_val))
9137         flow_label = 1;
9138       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9139         src = 1;
9140       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9141         dst = 1;
9142       else if (unformat (input, "proto %d", &proto_val))
9143         proto = 1;
9144       else if (unformat (input, "payload_length %d", &payload_length_val))
9145         payload_length = 1;
9146       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9147         hop_limit = 1;
9148       else
9149         break;
9150     }
9151
9152   if (version + traffic_class + flow_label + src + dst + proto +
9153       payload_length + hop_limit == 0)
9154     return 0;
9155
9156   /*
9157    * Aligned because we use the real comparison functions
9158    */
9159   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9160
9161   ip = (ip6_header_t *) match;
9162
9163   if (src)
9164     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9165
9166   if (dst)
9167     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9168
9169   if (proto)
9170     ip->protocol = proto_val;
9171
9172   ip_version_traffic_class_and_flow_label = 0;
9173
9174   if (version)
9175     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9176
9177   if (traffic_class)
9178     ip_version_traffic_class_and_flow_label |=
9179       (traffic_class_val & 0xFF) << 20;
9180
9181   if (flow_label)
9182     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9183
9184   ip->ip_version_traffic_class_and_flow_label =
9185     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9186
9187   if (payload_length)
9188     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9189
9190   if (hop_limit)
9191     ip->hop_limit = hop_limit_val;
9192
9193   *matchp = match;
9194   return 1;
9195 }
9196
9197 uword
9198 unformat_l3_match (unformat_input_t * input, va_list * args)
9199 {
9200   u8 **matchp = va_arg (*args, u8 **);
9201
9202   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9203     {
9204       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9205         return 1;
9206       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9207         return 1;
9208       else
9209         break;
9210     }
9211   return 0;
9212 }
9213
9214 uword
9215 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9216 {
9217   u8 *tagp = va_arg (*args, u8 *);
9218   u32 tag;
9219
9220   if (unformat (input, "%d", &tag))
9221     {
9222       tagp[0] = (tag >> 8) & 0x0F;
9223       tagp[1] = tag & 0xFF;
9224       return 1;
9225     }
9226
9227   return 0;
9228 }
9229
9230 uword
9231 unformat_l2_match (unformat_input_t * input, va_list * args)
9232 {
9233   u8 **matchp = va_arg (*args, u8 **);
9234   u8 *match = 0;
9235   u8 src = 0;
9236   u8 src_val[6];
9237   u8 dst = 0;
9238   u8 dst_val[6];
9239   u8 proto = 0;
9240   u16 proto_val;
9241   u8 tag1 = 0;
9242   u8 tag1_val[2];
9243   u8 tag2 = 0;
9244   u8 tag2_val[2];
9245   int len = 14;
9246   u8 ignore_tag1 = 0;
9247   u8 ignore_tag2 = 0;
9248   u8 cos1 = 0;
9249   u8 cos2 = 0;
9250   u32 cos1_val = 0;
9251   u32 cos2_val = 0;
9252
9253   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9254     {
9255       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9256         src = 1;
9257       else
9258         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9259         dst = 1;
9260       else if (unformat (input, "proto %U",
9261                          unformat_ethernet_type_host_byte_order, &proto_val))
9262         proto = 1;
9263       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9264         tag1 = 1;
9265       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9266         tag2 = 1;
9267       else if (unformat (input, "ignore-tag1"))
9268         ignore_tag1 = 1;
9269       else if (unformat (input, "ignore-tag2"))
9270         ignore_tag2 = 1;
9271       else if (unformat (input, "cos1 %d", &cos1_val))
9272         cos1 = 1;
9273       else if (unformat (input, "cos2 %d", &cos2_val))
9274         cos2 = 1;
9275       else
9276         break;
9277     }
9278   if ((src + dst + proto + tag1 + tag2 +
9279        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9280     return 0;
9281
9282   if (tag1 || ignore_tag1 || cos1)
9283     len = 18;
9284   if (tag2 || ignore_tag2 || cos2)
9285     len = 22;
9286
9287   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9288
9289   if (dst)
9290     clib_memcpy (match, dst_val, 6);
9291
9292   if (src)
9293     clib_memcpy (match + 6, src_val, 6);
9294
9295   if (tag2)
9296     {
9297       /* inner vlan tag */
9298       match[19] = tag2_val[1];
9299       match[18] = tag2_val[0];
9300       if (cos2)
9301         match[18] |= (cos2_val & 0x7) << 5;
9302       if (proto)
9303         {
9304           match[21] = proto_val & 0xff;
9305           match[20] = proto_val >> 8;
9306         }
9307       if (tag1)
9308         {
9309           match[15] = tag1_val[1];
9310           match[14] = tag1_val[0];
9311         }
9312       if (cos1)
9313         match[14] |= (cos1_val & 0x7) << 5;
9314       *matchp = match;
9315       return 1;
9316     }
9317   if (tag1)
9318     {
9319       match[15] = tag1_val[1];
9320       match[14] = tag1_val[0];
9321       if (proto)
9322         {
9323           match[17] = proto_val & 0xff;
9324           match[16] = proto_val >> 8;
9325         }
9326       if (cos1)
9327         match[14] |= (cos1_val & 0x7) << 5;
9328
9329       *matchp = match;
9330       return 1;
9331     }
9332   if (cos2)
9333     match[18] |= (cos2_val & 0x7) << 5;
9334   if (cos1)
9335     match[14] |= (cos1_val & 0x7) << 5;
9336   if (proto)
9337     {
9338       match[13] = proto_val & 0xff;
9339       match[12] = proto_val >> 8;
9340     }
9341
9342   *matchp = match;
9343   return 1;
9344 }
9345
9346
9347 uword
9348 unformat_classify_match (unformat_input_t * input, va_list * args)
9349 {
9350   u8 **matchp = va_arg (*args, u8 **);
9351   u32 skip_n_vectors = va_arg (*args, u32);
9352   u32 match_n_vectors = va_arg (*args, u32);
9353
9354   u8 *match = 0;
9355   u8 *l2 = 0;
9356   u8 *l3 = 0;
9357   u8 *l4 = 0;
9358
9359   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9360     {
9361       if (unformat (input, "hex %U", unformat_hex_string, &match))
9362         ;
9363       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9364         ;
9365       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9366         ;
9367       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9368         ;
9369       else
9370         break;
9371     }
9372
9373   if (l4 && !l3)
9374     {
9375       vec_free (match);
9376       vec_free (l2);
9377       vec_free (l4);
9378       return 0;
9379     }
9380
9381   if (match || l2 || l3 || l4)
9382     {
9383       if (l2 || l3 || l4)
9384         {
9385           /* "Win a free Ethernet header in every packet" */
9386           if (l2 == 0)
9387             vec_validate_aligned (l2, 13, sizeof (u32x4));
9388           match = l2;
9389           if (vec_len (l3))
9390             {
9391               vec_append_aligned (match, l3, sizeof (u32x4));
9392               vec_free (l3);
9393             }
9394           if (vec_len (l4))
9395             {
9396               vec_append_aligned (match, l4, sizeof (u32x4));
9397               vec_free (l4);
9398             }
9399         }
9400
9401       /* Make sure the vector is big enough even if key is all 0's */
9402       vec_validate_aligned
9403         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9404          sizeof (u32x4));
9405
9406       /* Set size, include skipped vectors */
9407       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9408
9409       *matchp = match;
9410
9411       return 1;
9412     }
9413
9414   return 0;
9415 }
9416
9417 static int
9418 api_classify_add_del_session (vat_main_t * vam)
9419 {
9420   unformat_input_t *i = vam->input;
9421   vl_api_classify_add_del_session_t *mp;
9422   int is_add = 1;
9423   u32 table_index = ~0;
9424   u32 hit_next_index = ~0;
9425   u32 opaque_index = ~0;
9426   u8 *match = 0;
9427   i32 advance = 0;
9428   f64 timeout;
9429   u32 skip_n_vectors = 0;
9430   u32 match_n_vectors = 0;
9431   u32 action = 0;
9432   u32 metadata = 0;
9433
9434   /*
9435    * Warning: you have to supply skip_n and match_n
9436    * because the API client cant simply look at the classify
9437    * table object.
9438    */
9439
9440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9441     {
9442       if (unformat (i, "del"))
9443         is_add = 0;
9444       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9445                          &hit_next_index))
9446         ;
9447       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9448                          &hit_next_index))
9449         ;
9450       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9451                          &hit_next_index))
9452         ;
9453       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9454         ;
9455       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9456         ;
9457       else if (unformat (i, "opaque-index %d", &opaque_index))
9458         ;
9459       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9460         ;
9461       else if (unformat (i, "match_n %d", &match_n_vectors))
9462         ;
9463       else if (unformat (i, "match %U", unformat_classify_match,
9464                          &match, skip_n_vectors, match_n_vectors))
9465         ;
9466       else if (unformat (i, "advance %d", &advance))
9467         ;
9468       else if (unformat (i, "table-index %d", &table_index))
9469         ;
9470       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9471         action = 1;
9472       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9473         action = 2;
9474       else if (unformat (i, "action %d", &action))
9475         ;
9476       else if (unformat (i, "metadata %d", &metadata))
9477         ;
9478       else
9479         break;
9480     }
9481
9482   if (table_index == ~0)
9483     {
9484       errmsg ("Table index required");
9485       return -99;
9486     }
9487
9488   if (is_add && match == 0)
9489     {
9490       errmsg ("Match value required");
9491       return -99;
9492     }
9493
9494   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9495
9496   mp->is_add = is_add;
9497   mp->table_index = ntohl (table_index);
9498   mp->hit_next_index = ntohl (hit_next_index);
9499   mp->opaque_index = ntohl (opaque_index);
9500   mp->advance = ntohl (advance);
9501   mp->action = action;
9502   mp->metadata = ntohl (metadata);
9503   clib_memcpy (mp->match, match, vec_len (match));
9504   vec_free (match);
9505
9506   S;
9507   W;
9508   /* NOTREACHED */
9509 }
9510
9511 static int
9512 api_classify_set_interface_ip_table (vat_main_t * vam)
9513 {
9514   unformat_input_t *i = vam->input;
9515   vl_api_classify_set_interface_ip_table_t *mp;
9516   f64 timeout;
9517   u32 sw_if_index;
9518   int sw_if_index_set;
9519   u32 table_index = ~0;
9520   u8 is_ipv6 = 0;
9521
9522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9523     {
9524       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9525         sw_if_index_set = 1;
9526       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9527         sw_if_index_set = 1;
9528       else if (unformat (i, "table %d", &table_index))
9529         ;
9530       else
9531         {
9532           clib_warning ("parse error '%U'", format_unformat_error, i);
9533           return -99;
9534         }
9535     }
9536
9537   if (sw_if_index_set == 0)
9538     {
9539       errmsg ("missing interface name or sw_if_index");
9540       return -99;
9541     }
9542
9543
9544   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9545
9546   mp->sw_if_index = ntohl (sw_if_index);
9547   mp->table_index = ntohl (table_index);
9548   mp->is_ipv6 = is_ipv6;
9549
9550   S;
9551   W;
9552   /* NOTREACHED */
9553   return 0;
9554 }
9555
9556 static int
9557 api_classify_set_interface_l2_tables (vat_main_t * vam)
9558 {
9559   unformat_input_t *i = vam->input;
9560   vl_api_classify_set_interface_l2_tables_t *mp;
9561   f64 timeout;
9562   u32 sw_if_index;
9563   int sw_if_index_set;
9564   u32 ip4_table_index = ~0;
9565   u32 ip6_table_index = ~0;
9566   u32 other_table_index = ~0;
9567   u32 is_input = 1;
9568
9569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9570     {
9571       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9572         sw_if_index_set = 1;
9573       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9574         sw_if_index_set = 1;
9575       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9576         ;
9577       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9578         ;
9579       else if (unformat (i, "other-table %d", &other_table_index))
9580         ;
9581       else if (unformat (i, "is-input %d", &is_input))
9582         ;
9583       else
9584         {
9585           clib_warning ("parse error '%U'", format_unformat_error, i);
9586           return -99;
9587         }
9588     }
9589
9590   if (sw_if_index_set == 0)
9591     {
9592       errmsg ("missing interface name or sw_if_index");
9593       return -99;
9594     }
9595
9596
9597   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9598
9599   mp->sw_if_index = ntohl (sw_if_index);
9600   mp->ip4_table_index = ntohl (ip4_table_index);
9601   mp->ip6_table_index = ntohl (ip6_table_index);
9602   mp->other_table_index = ntohl (other_table_index);
9603   mp->is_input = (u8) is_input;
9604
9605   S;
9606   W;
9607   /* NOTREACHED */
9608   return 0;
9609 }
9610
9611 static int
9612 api_set_ipfix_exporter (vat_main_t * vam)
9613 {
9614   unformat_input_t *i = vam->input;
9615   vl_api_set_ipfix_exporter_t *mp;
9616   ip4_address_t collector_address;
9617   u8 collector_address_set = 0;
9618   u32 collector_port = ~0;
9619   ip4_address_t src_address;
9620   u8 src_address_set = 0;
9621   u32 vrf_id = ~0;
9622   u32 path_mtu = ~0;
9623   u32 template_interval = ~0;
9624   u8 udp_checksum = 0;
9625   f64 timeout;
9626
9627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9628     {
9629       if (unformat (i, "collector_address %U", unformat_ip4_address,
9630                     &collector_address))
9631         collector_address_set = 1;
9632       else if (unformat (i, "collector_port %d", &collector_port))
9633         ;
9634       else if (unformat (i, "src_address %U", unformat_ip4_address,
9635                          &src_address))
9636         src_address_set = 1;
9637       else if (unformat (i, "vrf_id %d", &vrf_id))
9638         ;
9639       else if (unformat (i, "path_mtu %d", &path_mtu))
9640         ;
9641       else if (unformat (i, "template_interval %d", &template_interval))
9642         ;
9643       else if (unformat (i, "udp_checksum"))
9644         udp_checksum = 1;
9645       else
9646         break;
9647     }
9648
9649   if (collector_address_set == 0)
9650     {
9651       errmsg ("collector_address required");
9652       return -99;
9653     }
9654
9655   if (src_address_set == 0)
9656     {
9657       errmsg ("src_address required");
9658       return -99;
9659     }
9660
9661   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9662
9663   memcpy (mp->collector_address, collector_address.data,
9664           sizeof (collector_address.data));
9665   mp->collector_port = htons ((u16) collector_port);
9666   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9667   mp->vrf_id = htonl (vrf_id);
9668   mp->path_mtu = htonl (path_mtu);
9669   mp->template_interval = htonl (template_interval);
9670   mp->udp_checksum = udp_checksum;
9671
9672   S;
9673   W;
9674   /* NOTREACHED */
9675 }
9676
9677 static int
9678 api_set_ipfix_classify_stream (vat_main_t * vam)
9679 {
9680   unformat_input_t *i = vam->input;
9681   vl_api_set_ipfix_classify_stream_t *mp;
9682   u32 domain_id = 0;
9683   u32 src_port = UDP_DST_PORT_ipfix;
9684   f64 timeout;
9685
9686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9687     {
9688       if (unformat (i, "domain %d", &domain_id))
9689         ;
9690       else if (unformat (i, "src_port %d", &src_port))
9691         ;
9692       else
9693         {
9694           errmsg ("unknown input `%U'", format_unformat_error, i);
9695           return -99;
9696         }
9697     }
9698
9699   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9700
9701   mp->domain_id = htonl (domain_id);
9702   mp->src_port = htons ((u16) src_port);
9703
9704   S;
9705   W;
9706   /* NOTREACHED */
9707 }
9708
9709 static int
9710 api_ipfix_classify_table_add_del (vat_main_t * vam)
9711 {
9712   unformat_input_t *i = vam->input;
9713   vl_api_ipfix_classify_table_add_del_t *mp;
9714   int is_add = -1;
9715   u32 classify_table_index = ~0;
9716   u8 ip_version = 0;
9717   u8 transport_protocol = 255;
9718   f64 timeout;
9719
9720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9721     {
9722       if (unformat (i, "add"))
9723         is_add = 1;
9724       else if (unformat (i, "del"))
9725         is_add = 0;
9726       else if (unformat (i, "table %d", &classify_table_index))
9727         ;
9728       else if (unformat (i, "ip4"))
9729         ip_version = 4;
9730       else if (unformat (i, "ip6"))
9731         ip_version = 6;
9732       else if (unformat (i, "tcp"))
9733         transport_protocol = 6;
9734       else if (unformat (i, "udp"))
9735         transport_protocol = 17;
9736       else
9737         {
9738           errmsg ("unknown input `%U'", format_unformat_error, i);
9739           return -99;
9740         }
9741     }
9742
9743   if (is_add == -1)
9744     {
9745       errmsg ("expecting: add|del");
9746       return -99;
9747     }
9748   if (classify_table_index == ~0)
9749     {
9750       errmsg ("classifier table not specified");
9751       return -99;
9752     }
9753   if (ip_version == 0)
9754     {
9755       errmsg ("IP version not specified");
9756       return -99;
9757     }
9758
9759   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9760
9761   mp->is_add = is_add;
9762   mp->table_id = htonl (classify_table_index);
9763   mp->ip_version = ip_version;
9764   mp->transport_protocol = transport_protocol;
9765
9766   S;
9767   W;
9768   /* NOTREACHED */
9769 }
9770
9771 static int
9772 api_get_node_index (vat_main_t * vam)
9773 {
9774   unformat_input_t *i = vam->input;
9775   vl_api_get_node_index_t *mp;
9776   f64 timeout;
9777   u8 *name = 0;
9778
9779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9780     {
9781       if (unformat (i, "node %s", &name))
9782         ;
9783       else
9784         break;
9785     }
9786   if (name == 0)
9787     {
9788       errmsg ("node name required");
9789       return -99;
9790     }
9791   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9792     {
9793       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9794       return -99;
9795     }
9796
9797   M (GET_NODE_INDEX, get_node_index);
9798   clib_memcpy (mp->node_name, name, vec_len (name));
9799   vec_free (name);
9800
9801   S;
9802   W;
9803   /* NOTREACHED */
9804   return 0;
9805 }
9806
9807 static int
9808 api_get_next_index (vat_main_t * vam)
9809 {
9810   unformat_input_t *i = vam->input;
9811   vl_api_get_next_index_t *mp;
9812   f64 timeout;
9813   u8 *node_name = 0, *next_node_name = 0;
9814
9815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9816     {
9817       if (unformat (i, "node-name %s", &node_name))
9818         ;
9819       else if (unformat (i, "next-node-name %s", &next_node_name))
9820         break;
9821     }
9822
9823   if (node_name == 0)
9824     {
9825       errmsg ("node name required");
9826       return -99;
9827     }
9828   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9829     {
9830       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9831       return -99;
9832     }
9833
9834   if (next_node_name == 0)
9835     {
9836       errmsg ("next node name required");
9837       return -99;
9838     }
9839   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9840     {
9841       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9842       return -99;
9843     }
9844
9845   M (GET_NEXT_INDEX, get_next_index);
9846   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9847   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9848   vec_free (node_name);
9849   vec_free (next_node_name);
9850
9851   S;
9852   W;
9853   /* NOTREACHED */
9854   return 0;
9855 }
9856
9857 static int
9858 api_add_node_next (vat_main_t * vam)
9859 {
9860   unformat_input_t *i = vam->input;
9861   vl_api_add_node_next_t *mp;
9862   f64 timeout;
9863   u8 *name = 0;
9864   u8 *next = 0;
9865
9866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9867     {
9868       if (unformat (i, "node %s", &name))
9869         ;
9870       else if (unformat (i, "next %s", &next))
9871         ;
9872       else
9873         break;
9874     }
9875   if (name == 0)
9876     {
9877       errmsg ("node name required");
9878       return -99;
9879     }
9880   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9881     {
9882       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9883       return -99;
9884     }
9885   if (next == 0)
9886     {
9887       errmsg ("next node required");
9888       return -99;
9889     }
9890   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9891     {
9892       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9893       return -99;
9894     }
9895
9896   M (ADD_NODE_NEXT, add_node_next);
9897   clib_memcpy (mp->node_name, name, vec_len (name));
9898   clib_memcpy (mp->next_name, next, vec_len (next));
9899   vec_free (name);
9900   vec_free (next);
9901
9902   S;
9903   W;
9904   /* NOTREACHED */
9905   return 0;
9906 }
9907
9908 static int
9909 api_l2tpv3_create_tunnel (vat_main_t * vam)
9910 {
9911   unformat_input_t *i = vam->input;
9912   ip6_address_t client_address, our_address;
9913   int client_address_set = 0;
9914   int our_address_set = 0;
9915   u32 local_session_id = 0;
9916   u32 remote_session_id = 0;
9917   u64 local_cookie = 0;
9918   u64 remote_cookie = 0;
9919   u8 l2_sublayer_present = 0;
9920   vl_api_l2tpv3_create_tunnel_t *mp;
9921   f64 timeout;
9922
9923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9924     {
9925       if (unformat (i, "client_address %U", unformat_ip6_address,
9926                     &client_address))
9927         client_address_set = 1;
9928       else if (unformat (i, "our_address %U", unformat_ip6_address,
9929                          &our_address))
9930         our_address_set = 1;
9931       else if (unformat (i, "local_session_id %d", &local_session_id))
9932         ;
9933       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9934         ;
9935       else if (unformat (i, "local_cookie %lld", &local_cookie))
9936         ;
9937       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9938         ;
9939       else if (unformat (i, "l2-sublayer-present"))
9940         l2_sublayer_present = 1;
9941       else
9942         break;
9943     }
9944
9945   if (client_address_set == 0)
9946     {
9947       errmsg ("client_address required");
9948       return -99;
9949     }
9950
9951   if (our_address_set == 0)
9952     {
9953       errmsg ("our_address required");
9954       return -99;
9955     }
9956
9957   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9958
9959   clib_memcpy (mp->client_address, client_address.as_u8,
9960                sizeof (mp->client_address));
9961
9962   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9963
9964   mp->local_session_id = ntohl (local_session_id);
9965   mp->remote_session_id = ntohl (remote_session_id);
9966   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9967   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9968   mp->l2_sublayer_present = l2_sublayer_present;
9969   mp->is_ipv6 = 1;
9970
9971   S;
9972   W;
9973   /* NOTREACHED */
9974   return 0;
9975 }
9976
9977 static int
9978 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9979 {
9980   unformat_input_t *i = vam->input;
9981   u32 sw_if_index;
9982   u8 sw_if_index_set = 0;
9983   u64 new_local_cookie = 0;
9984   u64 new_remote_cookie = 0;
9985   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9986   f64 timeout;
9987
9988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9989     {
9990       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9991         sw_if_index_set = 1;
9992       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9993         sw_if_index_set = 1;
9994       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9995         ;
9996       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9997         ;
9998       else
9999         break;
10000     }
10001
10002   if (sw_if_index_set == 0)
10003     {
10004       errmsg ("missing interface name or sw_if_index");
10005       return -99;
10006     }
10007
10008   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
10009
10010   mp->sw_if_index = ntohl (sw_if_index);
10011   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10012   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10013
10014   S;
10015   W;
10016   /* NOTREACHED */
10017   return 0;
10018 }
10019
10020 static int
10021 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10022 {
10023   unformat_input_t *i = vam->input;
10024   vl_api_l2tpv3_interface_enable_disable_t *mp;
10025   f64 timeout;
10026   u32 sw_if_index;
10027   u8 sw_if_index_set = 0;
10028   u8 enable_disable = 1;
10029
10030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10031     {
10032       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10033         sw_if_index_set = 1;
10034       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10035         sw_if_index_set = 1;
10036       else if (unformat (i, "enable"))
10037         enable_disable = 1;
10038       else if (unformat (i, "disable"))
10039         enable_disable = 0;
10040       else
10041         break;
10042     }
10043
10044   if (sw_if_index_set == 0)
10045     {
10046       errmsg ("missing interface name or sw_if_index");
10047       return -99;
10048     }
10049
10050   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
10051
10052   mp->sw_if_index = ntohl (sw_if_index);
10053   mp->enable_disable = enable_disable;
10054
10055   S;
10056   W;
10057   /* NOTREACHED */
10058   return 0;
10059 }
10060
10061 static int
10062 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10063 {
10064   unformat_input_t *i = vam->input;
10065   vl_api_l2tpv3_set_lookup_key_t *mp;
10066   f64 timeout;
10067   u8 key = ~0;
10068
10069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10070     {
10071       if (unformat (i, "lookup_v6_src"))
10072         key = L2T_LOOKUP_SRC_ADDRESS;
10073       else if (unformat (i, "lookup_v6_dst"))
10074         key = L2T_LOOKUP_DST_ADDRESS;
10075       else if (unformat (i, "lookup_session_id"))
10076         key = L2T_LOOKUP_SESSION_ID;
10077       else
10078         break;
10079     }
10080
10081   if (key == (u8) ~ 0)
10082     {
10083       errmsg ("l2tp session lookup key unset");
10084       return -99;
10085     }
10086
10087   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
10088
10089   mp->key = key;
10090
10091   S;
10092   W;
10093   /* NOTREACHED */
10094   return 0;
10095 }
10096
10097 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10098   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10099 {
10100   vat_main_t *vam = &vat_main;
10101
10102   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10103          format_ip6_address, mp->our_address,
10104          format_ip6_address, mp->client_address,
10105          clib_net_to_host_u32 (mp->sw_if_index));
10106
10107   print (vam->ofp,
10108          "   local cookies %016llx %016llx remote cookie %016llx",
10109          clib_net_to_host_u64 (mp->local_cookie[0]),
10110          clib_net_to_host_u64 (mp->local_cookie[1]),
10111          clib_net_to_host_u64 (mp->remote_cookie));
10112
10113   print (vam->ofp, "   local session-id %d remote session-id %d",
10114          clib_net_to_host_u32 (mp->local_session_id),
10115          clib_net_to_host_u32 (mp->remote_session_id));
10116
10117   print (vam->ofp, "   l2 specific sublayer %s\n",
10118          mp->l2_sublayer_present ? "preset" : "absent");
10119
10120 }
10121
10122 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10123   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10124 {
10125   vat_main_t *vam = &vat_main;
10126   vat_json_node_t *node = NULL;
10127   struct in6_addr addr;
10128
10129   if (VAT_JSON_ARRAY != vam->json_tree.type)
10130     {
10131       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10132       vat_json_init_array (&vam->json_tree);
10133     }
10134   node = vat_json_array_add (&vam->json_tree);
10135
10136   vat_json_init_object (node);
10137
10138   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10139   vat_json_object_add_ip6 (node, "our_address", addr);
10140   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10141   vat_json_object_add_ip6 (node, "client_address", addr);
10142
10143   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10144   vat_json_init_array (lc);
10145   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10146   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10147   vat_json_object_add_uint (node, "remote_cookie",
10148                             clib_net_to_host_u64 (mp->remote_cookie));
10149
10150   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10151   vat_json_object_add_uint (node, "local_session_id",
10152                             clib_net_to_host_u32 (mp->local_session_id));
10153   vat_json_object_add_uint (node, "remote_session_id",
10154                             clib_net_to_host_u32 (mp->remote_session_id));
10155   vat_json_object_add_string_copy (node, "l2_sublayer",
10156                                    mp->l2_sublayer_present ? (u8 *) "present"
10157                                    : (u8 *) "absent");
10158 }
10159
10160 static int
10161 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10162 {
10163   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10164   f64 timeout;
10165
10166   /* Get list of l2tpv3-tunnel interfaces */
10167   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10168   S;
10169
10170   /* Use a control ping for synchronization */
10171   {
10172     vl_api_control_ping_t *mp;
10173     M (CONTROL_PING, control_ping);
10174     S;
10175   }
10176   W;
10177 }
10178
10179
10180 static void vl_api_sw_interface_tap_details_t_handler
10181   (vl_api_sw_interface_tap_details_t * mp)
10182 {
10183   vat_main_t *vam = &vat_main;
10184
10185   print (vam->ofp, "%-16s %d",
10186          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10187 }
10188
10189 static void vl_api_sw_interface_tap_details_t_handler_json
10190   (vl_api_sw_interface_tap_details_t * mp)
10191 {
10192   vat_main_t *vam = &vat_main;
10193   vat_json_node_t *node = NULL;
10194
10195   if (VAT_JSON_ARRAY != vam->json_tree.type)
10196     {
10197       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10198       vat_json_init_array (&vam->json_tree);
10199     }
10200   node = vat_json_array_add (&vam->json_tree);
10201
10202   vat_json_init_object (node);
10203   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10204   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10205 }
10206
10207 static int
10208 api_sw_interface_tap_dump (vat_main_t * vam)
10209 {
10210   vl_api_sw_interface_tap_dump_t *mp;
10211   f64 timeout;
10212
10213   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10214   /* Get list of tap interfaces */
10215   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10216   S;
10217
10218   /* Use a control ping for synchronization */
10219   {
10220     vl_api_control_ping_t *mp;
10221     M (CONTROL_PING, control_ping);
10222     S;
10223   }
10224   W;
10225 }
10226
10227 static uword unformat_vxlan_decap_next
10228   (unformat_input_t * input, va_list * args)
10229 {
10230   u32 *result = va_arg (*args, u32 *);
10231   u32 tmp;
10232
10233   if (unformat (input, "l2"))
10234     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10235   else if (unformat (input, "%d", &tmp))
10236     *result = tmp;
10237   else
10238     return 0;
10239   return 1;
10240 }
10241
10242 static int
10243 api_vxlan_add_del_tunnel (vat_main_t * vam)
10244 {
10245   unformat_input_t *line_input = vam->input;
10246   vl_api_vxlan_add_del_tunnel_t *mp;
10247   f64 timeout;
10248   ip46_address_t src, dst;
10249   u8 is_add = 1;
10250   u8 ipv4_set = 0, ipv6_set = 0;
10251   u8 src_set = 0;
10252   u8 dst_set = 0;
10253   u8 grp_set = 0;
10254   u32 mcast_sw_if_index = ~0;
10255   u32 encap_vrf_id = 0;
10256   u32 decap_next_index = ~0;
10257   u32 vni = 0;
10258
10259   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10260   memset (&src, 0, sizeof src);
10261   memset (&dst, 0, sizeof dst);
10262
10263   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10264     {
10265       if (unformat (line_input, "del"))
10266         is_add = 0;
10267       else
10268         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10269         {
10270           ipv4_set = 1;
10271           src_set = 1;
10272         }
10273       else
10274         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10275         {
10276           ipv4_set = 1;
10277           dst_set = 1;
10278         }
10279       else
10280         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10281         {
10282           ipv6_set = 1;
10283           src_set = 1;
10284         }
10285       else
10286         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10287         {
10288           ipv6_set = 1;
10289           dst_set = 1;
10290         }
10291       else if (unformat (line_input, "group %U %U",
10292                          unformat_ip4_address, &dst.ip4,
10293                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10294         {
10295           grp_set = dst_set = 1;
10296           ipv4_set = 1;
10297         }
10298       else if (unformat (line_input, "group %U",
10299                          unformat_ip4_address, &dst.ip4))
10300         {
10301           grp_set = dst_set = 1;
10302           ipv4_set = 1;
10303         }
10304       else if (unformat (line_input, "group %U %U",
10305                          unformat_ip6_address, &dst.ip6,
10306                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10307         {
10308           grp_set = dst_set = 1;
10309           ipv6_set = 1;
10310         }
10311       else if (unformat (line_input, "group %U",
10312                          unformat_ip6_address, &dst.ip6))
10313         {
10314           grp_set = dst_set = 1;
10315           ipv6_set = 1;
10316         }
10317       else
10318         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10319         ;
10320       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10321         ;
10322       else if (unformat (line_input, "decap-next %U",
10323                          unformat_vxlan_decap_next, &decap_next_index))
10324         ;
10325       else if (unformat (line_input, "vni %d", &vni))
10326         ;
10327       else
10328         {
10329           errmsg ("parse error '%U'", format_unformat_error, line_input);
10330           return -99;
10331         }
10332     }
10333
10334   if (src_set == 0)
10335     {
10336       errmsg ("tunnel src address not specified");
10337       return -99;
10338     }
10339   if (dst_set == 0)
10340     {
10341       errmsg ("tunnel dst address not specified");
10342       return -99;
10343     }
10344
10345   if (grp_set && !ip46_address_is_multicast (&dst))
10346     {
10347       errmsg ("tunnel group address not multicast");
10348       return -99;
10349     }
10350   if (grp_set && mcast_sw_if_index == ~0)
10351     {
10352       errmsg ("tunnel nonexistent multicast device");
10353       return -99;
10354     }
10355   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10356     {
10357       errmsg ("tunnel dst address must be unicast");
10358       return -99;
10359     }
10360
10361
10362   if (ipv4_set && ipv6_set)
10363     {
10364       errmsg ("both IPv4 and IPv6 addresses specified");
10365       return -99;
10366     }
10367
10368   if ((vni == 0) || (vni >> 24))
10369     {
10370       errmsg ("vni not specified or out of range");
10371       return -99;
10372     }
10373
10374   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10375
10376   if (ipv6_set)
10377     {
10378       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10379       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10380     }
10381   else
10382     {
10383       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10384       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10385     }
10386   mp->encap_vrf_id = ntohl (encap_vrf_id);
10387   mp->decap_next_index = ntohl (decap_next_index);
10388   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10389   mp->vni = ntohl (vni);
10390   mp->is_add = is_add;
10391   mp->is_ipv6 = ipv6_set;
10392
10393   S;
10394   W;
10395   /* NOTREACHED */
10396   return 0;
10397 }
10398
10399 static void vl_api_vxlan_tunnel_details_t_handler
10400   (vl_api_vxlan_tunnel_details_t * mp)
10401 {
10402   vat_main_t *vam = &vat_main;
10403   ip46_address_t src, dst;
10404
10405   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10406   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10407
10408   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10409          ntohl (mp->sw_if_index),
10410          format_ip46_address, &src, IP46_TYPE_ANY,
10411          format_ip46_address, &dst, IP46_TYPE_ANY,
10412          ntohl (mp->encap_vrf_id),
10413          ntohl (mp->decap_next_index), ntohl (mp->vni),
10414          ntohl (mp->mcast_sw_if_index));
10415 }
10416
10417 static void vl_api_vxlan_tunnel_details_t_handler_json
10418   (vl_api_vxlan_tunnel_details_t * mp)
10419 {
10420   vat_main_t *vam = &vat_main;
10421   vat_json_node_t *node = NULL;
10422
10423   if (VAT_JSON_ARRAY != vam->json_tree.type)
10424     {
10425       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10426       vat_json_init_array (&vam->json_tree);
10427     }
10428   node = vat_json_array_add (&vam->json_tree);
10429
10430   vat_json_init_object (node);
10431   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10432   if (mp->is_ipv6)
10433     {
10434       struct in6_addr ip6;
10435
10436       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10437       vat_json_object_add_ip6 (node, "src_address", ip6);
10438       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10439       vat_json_object_add_ip6 (node, "dst_address", ip6);
10440     }
10441   else
10442     {
10443       struct in_addr ip4;
10444
10445       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10446       vat_json_object_add_ip4 (node, "src_address", ip4);
10447       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10448       vat_json_object_add_ip4 (node, "dst_address", ip4);
10449     }
10450   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10451   vat_json_object_add_uint (node, "decap_next_index",
10452                             ntohl (mp->decap_next_index));
10453   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10454   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10455   vat_json_object_add_uint (node, "mcast_sw_if_index",
10456                             ntohl (mp->mcast_sw_if_index));
10457 }
10458
10459 static int
10460 api_vxlan_tunnel_dump (vat_main_t * vam)
10461 {
10462   unformat_input_t *i = vam->input;
10463   vl_api_vxlan_tunnel_dump_t *mp;
10464   f64 timeout;
10465   u32 sw_if_index;
10466   u8 sw_if_index_set = 0;
10467
10468   /* Parse args required to build the message */
10469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10470     {
10471       if (unformat (i, "sw_if_index %d", &sw_if_index))
10472         sw_if_index_set = 1;
10473       else
10474         break;
10475     }
10476
10477   if (sw_if_index_set == 0)
10478     {
10479       sw_if_index = ~0;
10480     }
10481
10482   if (!vam->json_output)
10483     {
10484       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10485              "sw_if_index", "src_address", "dst_address",
10486              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10487     }
10488
10489   /* Get list of vxlan-tunnel interfaces */
10490   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10491
10492   mp->sw_if_index = htonl (sw_if_index);
10493
10494   S;
10495
10496   /* Use a control ping for synchronization */
10497   {
10498     vl_api_control_ping_t *mp;
10499     M (CONTROL_PING, control_ping);
10500     S;
10501   }
10502   W;
10503 }
10504
10505 static int
10506 api_gre_add_del_tunnel (vat_main_t * vam)
10507 {
10508   unformat_input_t *line_input = vam->input;
10509   vl_api_gre_add_del_tunnel_t *mp;
10510   f64 timeout;
10511   ip4_address_t src4, dst4;
10512   u8 is_add = 1;
10513   u8 teb = 0;
10514   u8 src_set = 0;
10515   u8 dst_set = 0;
10516   u32 outer_fib_id = 0;
10517
10518   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10519     {
10520       if (unformat (line_input, "del"))
10521         is_add = 0;
10522       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10523         src_set = 1;
10524       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10525         dst_set = 1;
10526       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10527         ;
10528       else if (unformat (line_input, "teb"))
10529         teb = 1;
10530       else
10531         {
10532           errmsg ("parse error '%U'", format_unformat_error, line_input);
10533           return -99;
10534         }
10535     }
10536
10537   if (src_set == 0)
10538     {
10539       errmsg ("tunnel src address not specified");
10540       return -99;
10541     }
10542   if (dst_set == 0)
10543     {
10544       errmsg ("tunnel dst address not specified");
10545       return -99;
10546     }
10547
10548
10549   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10550
10551   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10552   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10553   mp->outer_fib_id = ntohl (outer_fib_id);
10554   mp->is_add = is_add;
10555   mp->teb = teb;
10556
10557   S;
10558   W;
10559   /* NOTREACHED */
10560   return 0;
10561 }
10562
10563 static void vl_api_gre_tunnel_details_t_handler
10564   (vl_api_gre_tunnel_details_t * mp)
10565 {
10566   vat_main_t *vam = &vat_main;
10567
10568   print (vam->ofp, "%11d%15U%15U%6d%14d",
10569          ntohl (mp->sw_if_index),
10570          format_ip4_address, &mp->src_address,
10571          format_ip4_address, &mp->dst_address,
10572          mp->teb, ntohl (mp->outer_fib_id));
10573 }
10574
10575 static void vl_api_gre_tunnel_details_t_handler_json
10576   (vl_api_gre_tunnel_details_t * mp)
10577 {
10578   vat_main_t *vam = &vat_main;
10579   vat_json_node_t *node = NULL;
10580   struct in_addr ip4;
10581
10582   if (VAT_JSON_ARRAY != vam->json_tree.type)
10583     {
10584       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10585       vat_json_init_array (&vam->json_tree);
10586     }
10587   node = vat_json_array_add (&vam->json_tree);
10588
10589   vat_json_init_object (node);
10590   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10591   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10592   vat_json_object_add_ip4 (node, "src_address", ip4);
10593   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10594   vat_json_object_add_ip4 (node, "dst_address", ip4);
10595   vat_json_object_add_uint (node, "teb", mp->teb);
10596   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10597 }
10598
10599 static int
10600 api_gre_tunnel_dump (vat_main_t * vam)
10601 {
10602   unformat_input_t *i = vam->input;
10603   vl_api_gre_tunnel_dump_t *mp;
10604   f64 timeout;
10605   u32 sw_if_index;
10606   u8 sw_if_index_set = 0;
10607
10608   /* Parse args required to build the message */
10609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10610     {
10611       if (unformat (i, "sw_if_index %d", &sw_if_index))
10612         sw_if_index_set = 1;
10613       else
10614         break;
10615     }
10616
10617   if (sw_if_index_set == 0)
10618     {
10619       sw_if_index = ~0;
10620     }
10621
10622   if (!vam->json_output)
10623     {
10624       print (vam->ofp, "%11s%15s%15s%6s%14s",
10625              "sw_if_index", "src_address", "dst_address", "teb",
10626              "outer_fib_id");
10627     }
10628
10629   /* Get list of gre-tunnel interfaces */
10630   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10631
10632   mp->sw_if_index = htonl (sw_if_index);
10633
10634   S;
10635
10636   /* Use a control ping for synchronization */
10637   {
10638     vl_api_control_ping_t *mp;
10639     M (CONTROL_PING, control_ping);
10640     S;
10641   }
10642   W;
10643 }
10644
10645 static int
10646 api_l2_fib_clear_table (vat_main_t * vam)
10647 {
10648 //  unformat_input_t * i = vam->input;
10649   vl_api_l2_fib_clear_table_t *mp;
10650   f64 timeout;
10651
10652   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10653
10654   S;
10655   W;
10656   /* NOTREACHED */
10657   return 0;
10658 }
10659
10660 static int
10661 api_l2_interface_efp_filter (vat_main_t * vam)
10662 {
10663   unformat_input_t *i = vam->input;
10664   vl_api_l2_interface_efp_filter_t *mp;
10665   f64 timeout;
10666   u32 sw_if_index;
10667   u8 enable = 1;
10668   u8 sw_if_index_set = 0;
10669
10670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10671     {
10672       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10673         sw_if_index_set = 1;
10674       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10675         sw_if_index_set = 1;
10676       else if (unformat (i, "enable"))
10677         enable = 1;
10678       else if (unformat (i, "disable"))
10679         enable = 0;
10680       else
10681         {
10682           clib_warning ("parse error '%U'", format_unformat_error, i);
10683           return -99;
10684         }
10685     }
10686
10687   if (sw_if_index_set == 0)
10688     {
10689       errmsg ("missing sw_if_index");
10690       return -99;
10691     }
10692
10693   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10694
10695   mp->sw_if_index = ntohl (sw_if_index);
10696   mp->enable_disable = enable;
10697
10698   S;
10699   W;
10700   /* NOTREACHED */
10701   return 0;
10702 }
10703
10704 #define foreach_vtr_op                          \
10705 _("disable",  L2_VTR_DISABLED)                  \
10706 _("push-1",  L2_VTR_PUSH_1)                     \
10707 _("push-2",  L2_VTR_PUSH_2)                     \
10708 _("pop-1",  L2_VTR_POP_1)                       \
10709 _("pop-2",  L2_VTR_POP_2)                       \
10710 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10711 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10712 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10713 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10714
10715 static int
10716 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10717 {
10718   unformat_input_t *i = vam->input;
10719   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10720   f64 timeout;
10721   u32 sw_if_index;
10722   u8 sw_if_index_set = 0;
10723   u8 vtr_op_set = 0;
10724   u32 vtr_op = 0;
10725   u32 push_dot1q = 1;
10726   u32 tag1 = ~0;
10727   u32 tag2 = ~0;
10728
10729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10730     {
10731       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10732         sw_if_index_set = 1;
10733       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10734         sw_if_index_set = 1;
10735       else if (unformat (i, "vtr_op %d", &vtr_op))
10736         vtr_op_set = 1;
10737 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10738       foreach_vtr_op
10739 #undef _
10740         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10741         ;
10742       else if (unformat (i, "tag1 %d", &tag1))
10743         ;
10744       else if (unformat (i, "tag2 %d", &tag2))
10745         ;
10746       else
10747         {
10748           clib_warning ("parse error '%U'", format_unformat_error, i);
10749           return -99;
10750         }
10751     }
10752
10753   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10754     {
10755       errmsg ("missing vtr operation or sw_if_index");
10756       return -99;
10757     }
10758
10759   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10760     mp->sw_if_index = ntohl (sw_if_index);
10761   mp->vtr_op = ntohl (vtr_op);
10762   mp->push_dot1q = ntohl (push_dot1q);
10763   mp->tag1 = ntohl (tag1);
10764   mp->tag2 = ntohl (tag2);
10765
10766   S;
10767   W;
10768   /* NOTREACHED */
10769   return 0;
10770 }
10771
10772 static int
10773 api_create_vhost_user_if (vat_main_t * vam)
10774 {
10775   unformat_input_t *i = vam->input;
10776   vl_api_create_vhost_user_if_t *mp;
10777   f64 timeout;
10778   u8 *file_name;
10779   u8 is_server = 0;
10780   u8 file_name_set = 0;
10781   u32 custom_dev_instance = ~0;
10782   u8 hwaddr[6];
10783   u8 use_custom_mac = 0;
10784   u8 *tag = 0;
10785
10786   /* Shut up coverity */
10787   memset (hwaddr, 0, sizeof (hwaddr));
10788
10789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10790     {
10791       if (unformat (i, "socket %s", &file_name))
10792         {
10793           file_name_set = 1;
10794         }
10795       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10796         ;
10797       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10798         use_custom_mac = 1;
10799       else if (unformat (i, "server"))
10800         is_server = 1;
10801       else if (unformat (i, "tag %s", &tag))
10802         ;
10803       else
10804         break;
10805     }
10806
10807   if (file_name_set == 0)
10808     {
10809       errmsg ("missing socket file name");
10810       return -99;
10811     }
10812
10813   if (vec_len (file_name) > 255)
10814     {
10815       errmsg ("socket file name too long");
10816       return -99;
10817     }
10818   vec_add1 (file_name, 0);
10819
10820   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10821
10822   mp->is_server = is_server;
10823   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10824   vec_free (file_name);
10825   if (custom_dev_instance != ~0)
10826     {
10827       mp->renumber = 1;
10828       mp->custom_dev_instance = ntohl (custom_dev_instance);
10829     }
10830   mp->use_custom_mac = use_custom_mac;
10831   clib_memcpy (mp->mac_address, hwaddr, 6);
10832   if (tag)
10833     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10834   vec_free (tag);
10835
10836   S;
10837   W;
10838   /* NOTREACHED */
10839   return 0;
10840 }
10841
10842 static int
10843 api_modify_vhost_user_if (vat_main_t * vam)
10844 {
10845   unformat_input_t *i = vam->input;
10846   vl_api_modify_vhost_user_if_t *mp;
10847   f64 timeout;
10848   u8 *file_name;
10849   u8 is_server = 0;
10850   u8 file_name_set = 0;
10851   u32 custom_dev_instance = ~0;
10852   u8 sw_if_index_set = 0;
10853   u32 sw_if_index = (u32) ~ 0;
10854
10855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10856     {
10857       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10858         sw_if_index_set = 1;
10859       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10860         sw_if_index_set = 1;
10861       else if (unformat (i, "socket %s", &file_name))
10862         {
10863           file_name_set = 1;
10864         }
10865       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10866         ;
10867       else if (unformat (i, "server"))
10868         is_server = 1;
10869       else
10870         break;
10871     }
10872
10873   if (sw_if_index_set == 0)
10874     {
10875       errmsg ("missing sw_if_index or interface name");
10876       return -99;
10877     }
10878
10879   if (file_name_set == 0)
10880     {
10881       errmsg ("missing socket file name");
10882       return -99;
10883     }
10884
10885   if (vec_len (file_name) > 255)
10886     {
10887       errmsg ("socket file name too long");
10888       return -99;
10889     }
10890   vec_add1 (file_name, 0);
10891
10892   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10893
10894   mp->sw_if_index = ntohl (sw_if_index);
10895   mp->is_server = is_server;
10896   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10897   vec_free (file_name);
10898   if (custom_dev_instance != ~0)
10899     {
10900       mp->renumber = 1;
10901       mp->custom_dev_instance = ntohl (custom_dev_instance);
10902     }
10903
10904   S;
10905   W;
10906   /* NOTREACHED */
10907   return 0;
10908 }
10909
10910 static int
10911 api_delete_vhost_user_if (vat_main_t * vam)
10912 {
10913   unformat_input_t *i = vam->input;
10914   vl_api_delete_vhost_user_if_t *mp;
10915   f64 timeout;
10916   u32 sw_if_index = ~0;
10917   u8 sw_if_index_set = 0;
10918
10919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10920     {
10921       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10922         sw_if_index_set = 1;
10923       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10924         sw_if_index_set = 1;
10925       else
10926         break;
10927     }
10928
10929   if (sw_if_index_set == 0)
10930     {
10931       errmsg ("missing sw_if_index or interface name");
10932       return -99;
10933     }
10934
10935
10936   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10937
10938   mp->sw_if_index = ntohl (sw_if_index);
10939
10940   S;
10941   W;
10942   /* NOTREACHED */
10943   return 0;
10944 }
10945
10946 static void vl_api_sw_interface_vhost_user_details_t_handler
10947   (vl_api_sw_interface_vhost_user_details_t * mp)
10948 {
10949   vat_main_t *vam = &vat_main;
10950
10951   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
10952          (char *) mp->interface_name,
10953          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10954          clib_net_to_host_u64 (mp->features), mp->is_server,
10955          ntohl (mp->num_regions), (char *) mp->sock_filename);
10956   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
10957 }
10958
10959 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10960   (vl_api_sw_interface_vhost_user_details_t * mp)
10961 {
10962   vat_main_t *vam = &vat_main;
10963   vat_json_node_t *node = NULL;
10964
10965   if (VAT_JSON_ARRAY != vam->json_tree.type)
10966     {
10967       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10968       vat_json_init_array (&vam->json_tree);
10969     }
10970   node = vat_json_array_add (&vam->json_tree);
10971
10972   vat_json_init_object (node);
10973   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10974   vat_json_object_add_string_copy (node, "interface_name",
10975                                    mp->interface_name);
10976   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10977                             ntohl (mp->virtio_net_hdr_sz));
10978   vat_json_object_add_uint (node, "features",
10979                             clib_net_to_host_u64 (mp->features));
10980   vat_json_object_add_uint (node, "is_server", mp->is_server);
10981   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10982   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10983   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10984 }
10985
10986 static int
10987 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10988 {
10989   vl_api_sw_interface_vhost_user_dump_t *mp;
10990   f64 timeout;
10991   print (vam->ofp,
10992          "Interface name           idx hdr_sz features server regions filename");
10993
10994   /* Get list of vhost-user interfaces */
10995   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10996   S;
10997
10998   /* Use a control ping for synchronization */
10999   {
11000     vl_api_control_ping_t *mp;
11001     M (CONTROL_PING, control_ping);
11002     S;
11003   }
11004   W;
11005 }
11006
11007 static int
11008 api_show_version (vat_main_t * vam)
11009 {
11010   vl_api_show_version_t *mp;
11011   f64 timeout;
11012
11013   M (SHOW_VERSION, show_version);
11014
11015   S;
11016   W;
11017   /* NOTREACHED */
11018   return 0;
11019 }
11020
11021
11022 static int
11023 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11024 {
11025   unformat_input_t *line_input = vam->input;
11026   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11027   f64 timeout;
11028   ip4_address_t local4, remote4;
11029   ip6_address_t local6, remote6;
11030   u8 is_add = 1;
11031   u8 ipv4_set = 0, ipv6_set = 0;
11032   u8 local_set = 0;
11033   u8 remote_set = 0;
11034   u32 encap_vrf_id = 0;
11035   u32 decap_vrf_id = 0;
11036   u8 protocol = ~0;
11037   u32 vni;
11038   u8 vni_set = 0;
11039
11040   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11041     {
11042       if (unformat (line_input, "del"))
11043         is_add = 0;
11044       else if (unformat (line_input, "local %U",
11045                          unformat_ip4_address, &local4))
11046         {
11047           local_set = 1;
11048           ipv4_set = 1;
11049         }
11050       else if (unformat (line_input, "remote %U",
11051                          unformat_ip4_address, &remote4))
11052         {
11053           remote_set = 1;
11054           ipv4_set = 1;
11055         }
11056       else if (unformat (line_input, "local %U",
11057                          unformat_ip6_address, &local6))
11058         {
11059           local_set = 1;
11060           ipv6_set = 1;
11061         }
11062       else if (unformat (line_input, "remote %U",
11063                          unformat_ip6_address, &remote6))
11064         {
11065           remote_set = 1;
11066           ipv6_set = 1;
11067         }
11068       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11069         ;
11070       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11071         ;
11072       else if (unformat (line_input, "vni %d", &vni))
11073         vni_set = 1;
11074       else if (unformat (line_input, "next-ip4"))
11075         protocol = 1;
11076       else if (unformat (line_input, "next-ip6"))
11077         protocol = 2;
11078       else if (unformat (line_input, "next-ethernet"))
11079         protocol = 3;
11080       else if (unformat (line_input, "next-nsh"))
11081         protocol = 4;
11082       else
11083         {
11084           errmsg ("parse error '%U'", format_unformat_error, line_input);
11085           return -99;
11086         }
11087     }
11088
11089   if (local_set == 0)
11090     {
11091       errmsg ("tunnel local address not specified");
11092       return -99;
11093     }
11094   if (remote_set == 0)
11095     {
11096       errmsg ("tunnel remote address not specified");
11097       return -99;
11098     }
11099   if (ipv4_set && ipv6_set)
11100     {
11101       errmsg ("both IPv4 and IPv6 addresses specified");
11102       return -99;
11103     }
11104
11105   if (vni_set == 0)
11106     {
11107       errmsg ("vni not specified");
11108       return -99;
11109     }
11110
11111   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
11112
11113
11114   if (ipv6_set)
11115     {
11116       clib_memcpy (&mp->local, &local6, sizeof (local6));
11117       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11118     }
11119   else
11120     {
11121       clib_memcpy (&mp->local, &local4, sizeof (local4));
11122       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11123     }
11124
11125   mp->encap_vrf_id = ntohl (encap_vrf_id);
11126   mp->decap_vrf_id = ntohl (decap_vrf_id);
11127   mp->protocol = protocol;
11128   mp->vni = ntohl (vni);
11129   mp->is_add = is_add;
11130   mp->is_ipv6 = ipv6_set;
11131
11132   S;
11133   W;
11134   /* NOTREACHED */
11135   return 0;
11136 }
11137
11138 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11139   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11140 {
11141   vat_main_t *vam = &vat_main;
11142
11143   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11144          ntohl (mp->sw_if_index),
11145          format_ip46_address, &(mp->local[0]),
11146          format_ip46_address, &(mp->remote[0]),
11147          ntohl (mp->vni),
11148          ntohl (mp->protocol),
11149          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11150 }
11151
11152 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11153   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11154 {
11155   vat_main_t *vam = &vat_main;
11156   vat_json_node_t *node = NULL;
11157   struct in_addr ip4;
11158   struct in6_addr ip6;
11159
11160   if (VAT_JSON_ARRAY != vam->json_tree.type)
11161     {
11162       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11163       vat_json_init_array (&vam->json_tree);
11164     }
11165   node = vat_json_array_add (&vam->json_tree);
11166
11167   vat_json_init_object (node);
11168   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11169   if (mp->is_ipv6)
11170     {
11171       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11172       vat_json_object_add_ip6 (node, "local", ip6);
11173       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11174       vat_json_object_add_ip6 (node, "remote", ip6);
11175     }
11176   else
11177     {
11178       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11179       vat_json_object_add_ip4 (node, "local", ip4);
11180       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11181       vat_json_object_add_ip4 (node, "remote", ip4);
11182     }
11183   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11184   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11185   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11186   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11187   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11188 }
11189
11190 static int
11191 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11192 {
11193   unformat_input_t *i = vam->input;
11194   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11195   f64 timeout;
11196   u32 sw_if_index;
11197   u8 sw_if_index_set = 0;
11198
11199   /* Parse args required to build the message */
11200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11201     {
11202       if (unformat (i, "sw_if_index %d", &sw_if_index))
11203         sw_if_index_set = 1;
11204       else
11205         break;
11206     }
11207
11208   if (sw_if_index_set == 0)
11209     {
11210       sw_if_index = ~0;
11211     }
11212
11213   if (!vam->json_output)
11214     {
11215       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11216              "sw_if_index", "local", "remote", "vni",
11217              "protocol", "encap_vrf_id", "decap_vrf_id");
11218     }
11219
11220   /* Get list of vxlan-tunnel interfaces */
11221   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11222
11223   mp->sw_if_index = htonl (sw_if_index);
11224
11225   S;
11226
11227   /* Use a control ping for synchronization */
11228   {
11229     vl_api_control_ping_t *mp;
11230     M (CONTROL_PING, control_ping);
11231     S;
11232   }
11233   W;
11234 }
11235
11236 u8 *
11237 format_l2_fib_mac_address (u8 * s, va_list * args)
11238 {
11239   u8 *a = va_arg (*args, u8 *);
11240
11241   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11242                  a[2], a[3], a[4], a[5], a[6], a[7]);
11243 }
11244
11245 static void vl_api_l2_fib_table_entry_t_handler
11246   (vl_api_l2_fib_table_entry_t * mp)
11247 {
11248   vat_main_t *vam = &vat_main;
11249
11250   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11251          "       %d       %d     %d",
11252          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11253          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11254          mp->bvi_mac);
11255 }
11256
11257 static void vl_api_l2_fib_table_entry_t_handler_json
11258   (vl_api_l2_fib_table_entry_t * mp)
11259 {
11260   vat_main_t *vam = &vat_main;
11261   vat_json_node_t *node = NULL;
11262
11263   if (VAT_JSON_ARRAY != vam->json_tree.type)
11264     {
11265       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11266       vat_json_init_array (&vam->json_tree);
11267     }
11268   node = vat_json_array_add (&vam->json_tree);
11269
11270   vat_json_init_object (node);
11271   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11272   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11273   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11274   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11275   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11276   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11277 }
11278
11279 static int
11280 api_l2_fib_table_dump (vat_main_t * vam)
11281 {
11282   unformat_input_t *i = vam->input;
11283   vl_api_l2_fib_table_dump_t *mp;
11284   f64 timeout;
11285   u32 bd_id;
11286   u8 bd_id_set = 0;
11287
11288   /* Parse args required to build the message */
11289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11290     {
11291       if (unformat (i, "bd_id %d", &bd_id))
11292         bd_id_set = 1;
11293       else
11294         break;
11295     }
11296
11297   if (bd_id_set == 0)
11298     {
11299       errmsg ("missing bridge domain");
11300       return -99;
11301     }
11302
11303   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11304
11305   /* Get list of l2 fib entries */
11306   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11307
11308   mp->bd_id = ntohl (bd_id);
11309   S;
11310
11311   /* Use a control ping for synchronization */
11312   {
11313     vl_api_control_ping_t *mp;
11314     M (CONTROL_PING, control_ping);
11315     S;
11316   }
11317   W;
11318 }
11319
11320
11321 static int
11322 api_interface_name_renumber (vat_main_t * vam)
11323 {
11324   unformat_input_t *line_input = vam->input;
11325   vl_api_interface_name_renumber_t *mp;
11326   u32 sw_if_index = ~0;
11327   f64 timeout;
11328   u32 new_show_dev_instance = ~0;
11329
11330   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11331     {
11332       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11333                     &sw_if_index))
11334         ;
11335       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11336         ;
11337       else if (unformat (line_input, "new_show_dev_instance %d",
11338                          &new_show_dev_instance))
11339         ;
11340       else
11341         break;
11342     }
11343
11344   if (sw_if_index == ~0)
11345     {
11346       errmsg ("missing interface name or sw_if_index");
11347       return -99;
11348     }
11349
11350   if (new_show_dev_instance == ~0)
11351     {
11352       errmsg ("missing new_show_dev_instance");
11353       return -99;
11354     }
11355
11356   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11357
11358   mp->sw_if_index = ntohl (sw_if_index);
11359   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11360
11361   S;
11362   W;
11363 }
11364
11365 static int
11366 api_want_ip4_arp_events (vat_main_t * vam)
11367 {
11368   unformat_input_t *line_input = vam->input;
11369   vl_api_want_ip4_arp_events_t *mp;
11370   f64 timeout;
11371   ip4_address_t address;
11372   int address_set = 0;
11373   u32 enable_disable = 1;
11374
11375   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11376     {
11377       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11378         address_set = 1;
11379       else if (unformat (line_input, "del"))
11380         enable_disable = 0;
11381       else
11382         break;
11383     }
11384
11385   if (address_set == 0)
11386     {
11387       errmsg ("missing addresses");
11388       return -99;
11389     }
11390
11391   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11392   mp->enable_disable = enable_disable;
11393   mp->pid = getpid ();
11394   mp->address = address.as_u32;
11395
11396   S;
11397   W;
11398 }
11399
11400 static int
11401 api_want_ip6_nd_events (vat_main_t * vam)
11402 {
11403   unformat_input_t *line_input = vam->input;
11404   vl_api_want_ip6_nd_events_t *mp;
11405   f64 timeout;
11406   ip6_address_t address;
11407   int address_set = 0;
11408   u32 enable_disable = 1;
11409
11410   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11411     {
11412       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11413         address_set = 1;
11414       else if (unformat (line_input, "del"))
11415         enable_disable = 0;
11416       else
11417         break;
11418     }
11419
11420   if (address_set == 0)
11421     {
11422       errmsg ("missing addresses");
11423       return -99;
11424     }
11425
11426   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11427   mp->enable_disable = enable_disable;
11428   mp->pid = getpid ();
11429   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11430
11431   S;
11432   W;
11433 }
11434
11435 static int
11436 api_input_acl_set_interface (vat_main_t * vam)
11437 {
11438   unformat_input_t *i = vam->input;
11439   vl_api_input_acl_set_interface_t *mp;
11440   f64 timeout;
11441   u32 sw_if_index;
11442   int sw_if_index_set;
11443   u32 ip4_table_index = ~0;
11444   u32 ip6_table_index = ~0;
11445   u32 l2_table_index = ~0;
11446   u8 is_add = 1;
11447
11448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11449     {
11450       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11451         sw_if_index_set = 1;
11452       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11453         sw_if_index_set = 1;
11454       else if (unformat (i, "del"))
11455         is_add = 0;
11456       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11457         ;
11458       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11459         ;
11460       else if (unformat (i, "l2-table %d", &l2_table_index))
11461         ;
11462       else
11463         {
11464           clib_warning ("parse error '%U'", format_unformat_error, i);
11465           return -99;
11466         }
11467     }
11468
11469   if (sw_if_index_set == 0)
11470     {
11471       errmsg ("missing interface name or sw_if_index");
11472       return -99;
11473     }
11474
11475   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11476
11477   mp->sw_if_index = ntohl (sw_if_index);
11478   mp->ip4_table_index = ntohl (ip4_table_index);
11479   mp->ip6_table_index = ntohl (ip6_table_index);
11480   mp->l2_table_index = ntohl (l2_table_index);
11481   mp->is_add = is_add;
11482
11483   S;
11484   W;
11485   /* NOTREACHED */
11486   return 0;
11487 }
11488
11489 static int
11490 api_ip_address_dump (vat_main_t * vam)
11491 {
11492   unformat_input_t *i = vam->input;
11493   vl_api_ip_address_dump_t *mp;
11494   u32 sw_if_index = ~0;
11495   u8 sw_if_index_set = 0;
11496   u8 ipv4_set = 0;
11497   u8 ipv6_set = 0;
11498   f64 timeout;
11499
11500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11501     {
11502       if (unformat (i, "sw_if_index %d", &sw_if_index))
11503         sw_if_index_set = 1;
11504       else
11505         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11506         sw_if_index_set = 1;
11507       else if (unformat (i, "ipv4"))
11508         ipv4_set = 1;
11509       else if (unformat (i, "ipv6"))
11510         ipv6_set = 1;
11511       else
11512         break;
11513     }
11514
11515   if (ipv4_set && ipv6_set)
11516     {
11517       errmsg ("ipv4 and ipv6 flags cannot be both set");
11518       return -99;
11519     }
11520
11521   if ((!ipv4_set) && (!ipv6_set))
11522     {
11523       errmsg ("no ipv4 nor ipv6 flag set");
11524       return -99;
11525     }
11526
11527   if (sw_if_index_set == 0)
11528     {
11529       errmsg ("missing interface name or sw_if_index");
11530       return -99;
11531     }
11532
11533   vam->current_sw_if_index = sw_if_index;
11534   vam->is_ipv6 = ipv6_set;
11535
11536   M (IP_ADDRESS_DUMP, ip_address_dump);
11537   mp->sw_if_index = ntohl (sw_if_index);
11538   mp->is_ipv6 = ipv6_set;
11539   S;
11540
11541   /* Use a control ping for synchronization */
11542   {
11543     vl_api_control_ping_t *mp;
11544     M (CONTROL_PING, control_ping);
11545     S;
11546   }
11547   W;
11548 }
11549
11550 static int
11551 api_ip_dump (vat_main_t * vam)
11552 {
11553   vl_api_ip_dump_t *mp;
11554   unformat_input_t *in = vam->input;
11555   int ipv4_set = 0;
11556   int ipv6_set = 0;
11557   int is_ipv6;
11558   f64 timeout;
11559   int i;
11560
11561   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11562     {
11563       if (unformat (in, "ipv4"))
11564         ipv4_set = 1;
11565       else if (unformat (in, "ipv6"))
11566         ipv6_set = 1;
11567       else
11568         break;
11569     }
11570
11571   if (ipv4_set && ipv6_set)
11572     {
11573       errmsg ("ipv4 and ipv6 flags cannot be both set");
11574       return -99;
11575     }
11576
11577   if ((!ipv4_set) && (!ipv6_set))
11578     {
11579       errmsg ("no ipv4 nor ipv6 flag set");
11580       return -99;
11581     }
11582
11583   is_ipv6 = ipv6_set;
11584   vam->is_ipv6 = is_ipv6;
11585
11586   /* free old data */
11587   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11588     {
11589       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11590     }
11591   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11592
11593   M (IP_DUMP, ip_dump);
11594   mp->is_ipv6 = ipv6_set;
11595   S;
11596
11597   /* Use a control ping for synchronization */
11598   {
11599     vl_api_control_ping_t *mp;
11600     M (CONTROL_PING, control_ping);
11601     S;
11602   }
11603   W;
11604 }
11605
11606 static int
11607 api_ipsec_spd_add_del (vat_main_t * vam)
11608 {
11609   unformat_input_t *i = vam->input;
11610   vl_api_ipsec_spd_add_del_t *mp;
11611   f64 timeout;
11612   u32 spd_id = ~0;
11613   u8 is_add = 1;
11614
11615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11616     {
11617       if (unformat (i, "spd_id %d", &spd_id))
11618         ;
11619       else if (unformat (i, "del"))
11620         is_add = 0;
11621       else
11622         {
11623           clib_warning ("parse error '%U'", format_unformat_error, i);
11624           return -99;
11625         }
11626     }
11627   if (spd_id == ~0)
11628     {
11629       errmsg ("spd_id must be set");
11630       return -99;
11631     }
11632
11633   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11634
11635   mp->spd_id = ntohl (spd_id);
11636   mp->is_add = is_add;
11637
11638   S;
11639   W;
11640   /* NOTREACHED */
11641   return 0;
11642 }
11643
11644 static int
11645 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11646 {
11647   unformat_input_t *i = vam->input;
11648   vl_api_ipsec_interface_add_del_spd_t *mp;
11649   f64 timeout;
11650   u32 sw_if_index;
11651   u8 sw_if_index_set = 0;
11652   u32 spd_id = (u32) ~ 0;
11653   u8 is_add = 1;
11654
11655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11656     {
11657       if (unformat (i, "del"))
11658         is_add = 0;
11659       else if (unformat (i, "spd_id %d", &spd_id))
11660         ;
11661       else
11662         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11663         sw_if_index_set = 1;
11664       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11665         sw_if_index_set = 1;
11666       else
11667         {
11668           clib_warning ("parse error '%U'", format_unformat_error, i);
11669           return -99;
11670         }
11671
11672     }
11673
11674   if (spd_id == (u32) ~ 0)
11675     {
11676       errmsg ("spd_id must be set");
11677       return -99;
11678     }
11679
11680   if (sw_if_index_set == 0)
11681     {
11682       errmsg ("missing interface name or sw_if_index");
11683       return -99;
11684     }
11685
11686   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11687
11688   mp->spd_id = ntohl (spd_id);
11689   mp->sw_if_index = ntohl (sw_if_index);
11690   mp->is_add = is_add;
11691
11692   S;
11693   W;
11694   /* NOTREACHED */
11695   return 0;
11696 }
11697
11698 static int
11699 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11700 {
11701   unformat_input_t *i = vam->input;
11702   vl_api_ipsec_spd_add_del_entry_t *mp;
11703   f64 timeout;
11704   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11705   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11706   i32 priority = 0;
11707   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11708   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11709   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11710   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11711
11712   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11713   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11714   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11715   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11716   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11717   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11718
11719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11720     {
11721       if (unformat (i, "del"))
11722         is_add = 0;
11723       if (unformat (i, "outbound"))
11724         is_outbound = 1;
11725       if (unformat (i, "inbound"))
11726         is_outbound = 0;
11727       else if (unformat (i, "spd_id %d", &spd_id))
11728         ;
11729       else if (unformat (i, "sa_id %d", &sa_id))
11730         ;
11731       else if (unformat (i, "priority %d", &priority))
11732         ;
11733       else if (unformat (i, "protocol %d", &protocol))
11734         ;
11735       else if (unformat (i, "lport_start %d", &lport_start))
11736         ;
11737       else if (unformat (i, "lport_stop %d", &lport_stop))
11738         ;
11739       else if (unformat (i, "rport_start %d", &rport_start))
11740         ;
11741       else if (unformat (i, "rport_stop %d", &rport_stop))
11742         ;
11743       else
11744         if (unformat
11745             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11746         {
11747           is_ipv6 = 0;
11748           is_ip_any = 0;
11749         }
11750       else
11751         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11752         {
11753           is_ipv6 = 0;
11754           is_ip_any = 0;
11755         }
11756       else
11757         if (unformat
11758             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11759         {
11760           is_ipv6 = 0;
11761           is_ip_any = 0;
11762         }
11763       else
11764         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11765         {
11766           is_ipv6 = 0;
11767           is_ip_any = 0;
11768         }
11769       else
11770         if (unformat
11771             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11772         {
11773           is_ipv6 = 1;
11774           is_ip_any = 0;
11775         }
11776       else
11777         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11778         {
11779           is_ipv6 = 1;
11780           is_ip_any = 0;
11781         }
11782       else
11783         if (unformat
11784             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11785         {
11786           is_ipv6 = 1;
11787           is_ip_any = 0;
11788         }
11789       else
11790         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11791         {
11792           is_ipv6 = 1;
11793           is_ip_any = 0;
11794         }
11795       else
11796         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11797         {
11798           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11799             {
11800               clib_warning ("unsupported action: 'resolve'");
11801               return -99;
11802             }
11803         }
11804       else
11805         {
11806           clib_warning ("parse error '%U'", format_unformat_error, i);
11807           return -99;
11808         }
11809
11810     }
11811
11812   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11813
11814   mp->spd_id = ntohl (spd_id);
11815   mp->priority = ntohl (priority);
11816   mp->is_outbound = is_outbound;
11817
11818   mp->is_ipv6 = is_ipv6;
11819   if (is_ipv6 || is_ip_any)
11820     {
11821       clib_memcpy (mp->remote_address_start, &raddr6_start,
11822                    sizeof (ip6_address_t));
11823       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11824                    sizeof (ip6_address_t));
11825       clib_memcpy (mp->local_address_start, &laddr6_start,
11826                    sizeof (ip6_address_t));
11827       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11828                    sizeof (ip6_address_t));
11829     }
11830   else
11831     {
11832       clib_memcpy (mp->remote_address_start, &raddr4_start,
11833                    sizeof (ip4_address_t));
11834       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11835                    sizeof (ip4_address_t));
11836       clib_memcpy (mp->local_address_start, &laddr4_start,
11837                    sizeof (ip4_address_t));
11838       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11839                    sizeof (ip4_address_t));
11840     }
11841   mp->protocol = (u8) protocol;
11842   mp->local_port_start = ntohs ((u16) lport_start);
11843   mp->local_port_stop = ntohs ((u16) lport_stop);
11844   mp->remote_port_start = ntohs ((u16) rport_start);
11845   mp->remote_port_stop = ntohs ((u16) rport_stop);
11846   mp->policy = (u8) policy;
11847   mp->sa_id = ntohl (sa_id);
11848   mp->is_add = is_add;
11849   mp->is_ip_any = is_ip_any;
11850   S;
11851   W;
11852   /* NOTREACHED */
11853   return 0;
11854 }
11855
11856 static int
11857 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11858 {
11859   unformat_input_t *i = vam->input;
11860   vl_api_ipsec_sad_add_del_entry_t *mp;
11861   f64 timeout;
11862   u32 sad_id = 0, spi = 0;
11863   u8 *ck = 0, *ik = 0;
11864   u8 is_add = 1;
11865
11866   u8 protocol = IPSEC_PROTOCOL_AH;
11867   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11868   u32 crypto_alg = 0, integ_alg = 0;
11869   ip4_address_t tun_src4;
11870   ip4_address_t tun_dst4;
11871   ip6_address_t tun_src6;
11872   ip6_address_t tun_dst6;
11873
11874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11875     {
11876       if (unformat (i, "del"))
11877         is_add = 0;
11878       else if (unformat (i, "sad_id %d", &sad_id))
11879         ;
11880       else if (unformat (i, "spi %d", &spi))
11881         ;
11882       else if (unformat (i, "esp"))
11883         protocol = IPSEC_PROTOCOL_ESP;
11884       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11885         {
11886           is_tunnel = 1;
11887           is_tunnel_ipv6 = 0;
11888         }
11889       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11890         {
11891           is_tunnel = 1;
11892           is_tunnel_ipv6 = 0;
11893         }
11894       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11895         {
11896           is_tunnel = 1;
11897           is_tunnel_ipv6 = 1;
11898         }
11899       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11900         {
11901           is_tunnel = 1;
11902           is_tunnel_ipv6 = 1;
11903         }
11904       else
11905         if (unformat
11906             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11907         {
11908           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11909               crypto_alg >= IPSEC_CRYPTO_N_ALG)
11910             {
11911               clib_warning ("unsupported crypto-alg: '%U'",
11912                             format_ipsec_crypto_alg, crypto_alg);
11913               return -99;
11914             }
11915         }
11916       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11917         ;
11918       else
11919         if (unformat
11920             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11921         {
11922 #if DPDK_CRYPTO==1
11923           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
11924 #else
11925           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11926 #endif
11927               integ_alg >= IPSEC_INTEG_N_ALG)
11928             {
11929               clib_warning ("unsupported integ-alg: '%U'",
11930                             format_ipsec_integ_alg, integ_alg);
11931               return -99;
11932             }
11933         }
11934       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11935         ;
11936       else
11937         {
11938           clib_warning ("parse error '%U'", format_unformat_error, i);
11939           return -99;
11940         }
11941
11942     }
11943
11944 #if DPDK_CRYPTO==1
11945   /*Special cases, aes-gcm-128 encryption */
11946   if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
11947     {
11948       if (integ_alg != IPSEC_INTEG_ALG_NONE
11949           && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
11950         {
11951           clib_warning
11952             ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
11953           return -99;
11954         }
11955       else                      /*set integ-alg internally to aes-gcm-128 */
11956         integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
11957     }
11958   else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
11959     {
11960       clib_warning ("unsupported integ-alg: aes-gcm-128");
11961       return -99;
11962     }
11963   else if (integ_alg == IPSEC_INTEG_ALG_NONE)
11964     {
11965       clib_warning ("unsupported integ-alg: none");
11966       return -99;
11967     }
11968 #endif
11969
11970
11971   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11972
11973   mp->sad_id = ntohl (sad_id);
11974   mp->is_add = is_add;
11975   mp->protocol = protocol;
11976   mp->spi = ntohl (spi);
11977   mp->is_tunnel = is_tunnel;
11978   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11979   mp->crypto_algorithm = crypto_alg;
11980   mp->integrity_algorithm = integ_alg;
11981   mp->crypto_key_length = vec_len (ck);
11982   mp->integrity_key_length = vec_len (ik);
11983
11984   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11985     mp->crypto_key_length = sizeof (mp->crypto_key);
11986
11987   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11988     mp->integrity_key_length = sizeof (mp->integrity_key);
11989
11990   if (ck)
11991     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11992   if (ik)
11993     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11994
11995   if (is_tunnel)
11996     {
11997       if (is_tunnel_ipv6)
11998         {
11999           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12000                        sizeof (ip6_address_t));
12001           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12002                        sizeof (ip6_address_t));
12003         }
12004       else
12005         {
12006           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12007                        sizeof (ip4_address_t));
12008           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12009                        sizeof (ip4_address_t));
12010         }
12011     }
12012
12013   S;
12014   W;
12015   /* NOTREACHED */
12016   return 0;
12017 }
12018
12019 static int
12020 api_ipsec_sa_set_key (vat_main_t * vam)
12021 {
12022   unformat_input_t *i = vam->input;
12023   vl_api_ipsec_sa_set_key_t *mp;
12024   f64 timeout;
12025   u32 sa_id;
12026   u8 *ck = 0, *ik = 0;
12027
12028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12029     {
12030       if (unformat (i, "sa_id %d", &sa_id))
12031         ;
12032       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12033         ;
12034       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12035         ;
12036       else
12037         {
12038           clib_warning ("parse error '%U'", format_unformat_error, i);
12039           return -99;
12040         }
12041     }
12042
12043   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
12044
12045   mp->sa_id = ntohl (sa_id);
12046   mp->crypto_key_length = vec_len (ck);
12047   mp->integrity_key_length = vec_len (ik);
12048
12049   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12050     mp->crypto_key_length = sizeof (mp->crypto_key);
12051
12052   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12053     mp->integrity_key_length = sizeof (mp->integrity_key);
12054
12055   if (ck)
12056     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12057   if (ik)
12058     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12059
12060   S;
12061   W;
12062   /* NOTREACHED */
12063   return 0;
12064 }
12065
12066 static int
12067 api_ikev2_profile_add_del (vat_main_t * vam)
12068 {
12069   unformat_input_t *i = vam->input;
12070   vl_api_ikev2_profile_add_del_t *mp;
12071   f64 timeout;
12072   u8 is_add = 1;
12073   u8 *name = 0;
12074
12075   const char *valid_chars = "a-zA-Z0-9_";
12076
12077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12078     {
12079       if (unformat (i, "del"))
12080         is_add = 0;
12081       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12082         vec_add1 (name, 0);
12083       else
12084         {
12085           errmsg ("parse error '%U'", format_unformat_error, i);
12086           return -99;
12087         }
12088     }
12089
12090   if (!vec_len (name))
12091     {
12092       errmsg ("profile name must be specified");
12093       return -99;
12094     }
12095
12096   if (vec_len (name) > 64)
12097     {
12098       errmsg ("profile name too long");
12099       return -99;
12100     }
12101
12102   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
12103
12104   clib_memcpy (mp->name, name, vec_len (name));
12105   mp->is_add = is_add;
12106   vec_free (name);
12107
12108   S;
12109   W;
12110   /* NOTREACHED */
12111   return 0;
12112 }
12113
12114 static int
12115 api_ikev2_profile_set_auth (vat_main_t * vam)
12116 {
12117   unformat_input_t *i = vam->input;
12118   vl_api_ikev2_profile_set_auth_t *mp;
12119   f64 timeout;
12120   u8 *name = 0;
12121   u8 *data = 0;
12122   u32 auth_method = 0;
12123   u8 is_hex = 0;
12124
12125   const char *valid_chars = "a-zA-Z0-9_";
12126
12127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12128     {
12129       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12130         vec_add1 (name, 0);
12131       else if (unformat (i, "auth_method %U",
12132                          unformat_ikev2_auth_method, &auth_method))
12133         ;
12134       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12135         is_hex = 1;
12136       else if (unformat (i, "auth_data %v", &data))
12137         ;
12138       else
12139         {
12140           errmsg ("parse error '%U'", format_unformat_error, i);
12141           return -99;
12142         }
12143     }
12144
12145   if (!vec_len (name))
12146     {
12147       errmsg ("profile name must be specified");
12148       return -99;
12149     }
12150
12151   if (vec_len (name) > 64)
12152     {
12153       errmsg ("profile name too long");
12154       return -99;
12155     }
12156
12157   if (!vec_len (data))
12158     {
12159       errmsg ("auth_data must be specified");
12160       return -99;
12161     }
12162
12163   if (!auth_method)
12164     {
12165       errmsg ("auth_method must be specified");
12166       return -99;
12167     }
12168
12169   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12170
12171   mp->is_hex = is_hex;
12172   mp->auth_method = (u8) auth_method;
12173   mp->data_len = vec_len (data);
12174   clib_memcpy (mp->name, name, vec_len (name));
12175   clib_memcpy (mp->data, data, vec_len (data));
12176   vec_free (name);
12177   vec_free (data);
12178
12179   S;
12180   W;
12181   /* NOTREACHED */
12182   return 0;
12183 }
12184
12185 static int
12186 api_ikev2_profile_set_id (vat_main_t * vam)
12187 {
12188   unformat_input_t *i = vam->input;
12189   vl_api_ikev2_profile_set_id_t *mp;
12190   f64 timeout;
12191   u8 *name = 0;
12192   u8 *data = 0;
12193   u8 is_local = 0;
12194   u32 id_type = 0;
12195   ip4_address_t ip4;
12196
12197   const char *valid_chars = "a-zA-Z0-9_";
12198
12199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12200     {
12201       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12202         vec_add1 (name, 0);
12203       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12204         ;
12205       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12206         {
12207           data = vec_new (u8, 4);
12208           clib_memcpy (data, ip4.as_u8, 4);
12209         }
12210       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12211         ;
12212       else if (unformat (i, "id_data %v", &data))
12213         ;
12214       else if (unformat (i, "local"))
12215         is_local = 1;
12216       else if (unformat (i, "remote"))
12217         is_local = 0;
12218       else
12219         {
12220           errmsg ("parse error '%U'", format_unformat_error, i);
12221           return -99;
12222         }
12223     }
12224
12225   if (!vec_len (name))
12226     {
12227       errmsg ("profile name must be specified");
12228       return -99;
12229     }
12230
12231   if (vec_len (name) > 64)
12232     {
12233       errmsg ("profile name too long");
12234       return -99;
12235     }
12236
12237   if (!vec_len (data))
12238     {
12239       errmsg ("id_data must be specified");
12240       return -99;
12241     }
12242
12243   if (!id_type)
12244     {
12245       errmsg ("id_type must be specified");
12246       return -99;
12247     }
12248
12249   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12250
12251   mp->is_local = is_local;
12252   mp->id_type = (u8) id_type;
12253   mp->data_len = vec_len (data);
12254   clib_memcpy (mp->name, name, vec_len (name));
12255   clib_memcpy (mp->data, data, vec_len (data));
12256   vec_free (name);
12257   vec_free (data);
12258
12259   S;
12260   W;
12261   /* NOTREACHED */
12262   return 0;
12263 }
12264
12265 static int
12266 api_ikev2_profile_set_ts (vat_main_t * vam)
12267 {
12268   unformat_input_t *i = vam->input;
12269   vl_api_ikev2_profile_set_ts_t *mp;
12270   f64 timeout;
12271   u8 *name = 0;
12272   u8 is_local = 0;
12273   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12274   ip4_address_t start_addr, end_addr;
12275
12276   const char *valid_chars = "a-zA-Z0-9_";
12277
12278   start_addr.as_u32 = 0;
12279   end_addr.as_u32 = (u32) ~ 0;
12280
12281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12282     {
12283       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12284         vec_add1 (name, 0);
12285       else if (unformat (i, "protocol %d", &proto))
12286         ;
12287       else if (unformat (i, "start_port %d", &start_port))
12288         ;
12289       else if (unformat (i, "end_port %d", &end_port))
12290         ;
12291       else
12292         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12293         ;
12294       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12295         ;
12296       else if (unformat (i, "local"))
12297         is_local = 1;
12298       else if (unformat (i, "remote"))
12299         is_local = 0;
12300       else
12301         {
12302           errmsg ("parse error '%U'", format_unformat_error, i);
12303           return -99;
12304         }
12305     }
12306
12307   if (!vec_len (name))
12308     {
12309       errmsg ("profile name must be specified");
12310       return -99;
12311     }
12312
12313   if (vec_len (name) > 64)
12314     {
12315       errmsg ("profile name too long");
12316       return -99;
12317     }
12318
12319   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12320
12321   mp->is_local = is_local;
12322   mp->proto = (u8) proto;
12323   mp->start_port = (u16) start_port;
12324   mp->end_port = (u16) end_port;
12325   mp->start_addr = start_addr.as_u32;
12326   mp->end_addr = end_addr.as_u32;
12327   clib_memcpy (mp->name, name, vec_len (name));
12328   vec_free (name);
12329
12330   S;
12331   W;
12332   /* NOTREACHED */
12333   return 0;
12334 }
12335
12336 static int
12337 api_ikev2_set_local_key (vat_main_t * vam)
12338 {
12339   unformat_input_t *i = vam->input;
12340   vl_api_ikev2_set_local_key_t *mp;
12341   f64 timeout;
12342   u8 *file = 0;
12343
12344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12345     {
12346       if (unformat (i, "file %v", &file))
12347         vec_add1 (file, 0);
12348       else
12349         {
12350           errmsg ("parse error '%U'", format_unformat_error, i);
12351           return -99;
12352         }
12353     }
12354
12355   if (!vec_len (file))
12356     {
12357       errmsg ("RSA key file must be specified");
12358       return -99;
12359     }
12360
12361   if (vec_len (file) > 256)
12362     {
12363       errmsg ("file name too long");
12364       return -99;
12365     }
12366
12367   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12368
12369   clib_memcpy (mp->key_file, file, vec_len (file));
12370   vec_free (file);
12371
12372   S;
12373   W;
12374   /* NOTREACHED */
12375   return 0;
12376 }
12377
12378 /*
12379  * MAP
12380  */
12381 static int
12382 api_map_add_domain (vat_main_t * vam)
12383 {
12384   unformat_input_t *i = vam->input;
12385   vl_api_map_add_domain_t *mp;
12386   f64 timeout;
12387
12388   ip4_address_t ip4_prefix;
12389   ip6_address_t ip6_prefix;
12390   ip6_address_t ip6_src;
12391   u32 num_m_args = 0;
12392   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12393     0, psid_length = 0;
12394   u8 is_translation = 0;
12395   u32 mtu = 0;
12396   u32 ip6_src_len = 128;
12397
12398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12399     {
12400       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12401                     &ip4_prefix, &ip4_prefix_len))
12402         num_m_args++;
12403       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12404                          &ip6_prefix, &ip6_prefix_len))
12405         num_m_args++;
12406       else
12407         if (unformat
12408             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12409              &ip6_src_len))
12410         num_m_args++;
12411       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12412         num_m_args++;
12413       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12414         num_m_args++;
12415       else if (unformat (i, "psid-offset %d", &psid_offset))
12416         num_m_args++;
12417       else if (unformat (i, "psid-len %d", &psid_length))
12418         num_m_args++;
12419       else if (unformat (i, "mtu %d", &mtu))
12420         num_m_args++;
12421       else if (unformat (i, "map-t"))
12422         is_translation = 1;
12423       else
12424         {
12425           clib_warning ("parse error '%U'", format_unformat_error, i);
12426           return -99;
12427         }
12428     }
12429
12430   if (num_m_args < 3)
12431     {
12432       errmsg ("mandatory argument(s) missing");
12433       return -99;
12434     }
12435
12436   /* Construct the API message */
12437   M (MAP_ADD_DOMAIN, map_add_domain);
12438
12439   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12440   mp->ip4_prefix_len = ip4_prefix_len;
12441
12442   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12443   mp->ip6_prefix_len = ip6_prefix_len;
12444
12445   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12446   mp->ip6_src_prefix_len = ip6_src_len;
12447
12448   mp->ea_bits_len = ea_bits_len;
12449   mp->psid_offset = psid_offset;
12450   mp->psid_length = psid_length;
12451   mp->is_translation = is_translation;
12452   mp->mtu = htons (mtu);
12453
12454   /* send it... */
12455   S;
12456
12457   /* Wait for a reply, return good/bad news  */
12458   W;
12459 }
12460
12461 static int
12462 api_map_del_domain (vat_main_t * vam)
12463 {
12464   unformat_input_t *i = vam->input;
12465   vl_api_map_del_domain_t *mp;
12466   f64 timeout;
12467
12468   u32 num_m_args = 0;
12469   u32 index;
12470
12471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12472     {
12473       if (unformat (i, "index %d", &index))
12474         num_m_args++;
12475       else
12476         {
12477           clib_warning ("parse error '%U'", format_unformat_error, i);
12478           return -99;
12479         }
12480     }
12481
12482   if (num_m_args != 1)
12483     {
12484       errmsg ("mandatory argument(s) missing");
12485       return -99;
12486     }
12487
12488   /* Construct the API message */
12489   M (MAP_DEL_DOMAIN, map_del_domain);
12490
12491   mp->index = ntohl (index);
12492
12493   /* send it... */
12494   S;
12495
12496   /* Wait for a reply, return good/bad news  */
12497   W;
12498 }
12499
12500 static int
12501 api_map_add_del_rule (vat_main_t * vam)
12502 {
12503   unformat_input_t *i = vam->input;
12504   vl_api_map_add_del_rule_t *mp;
12505   f64 timeout;
12506   u8 is_add = 1;
12507   ip6_address_t ip6_dst;
12508   u32 num_m_args = 0, index, psid = 0;
12509
12510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12511     {
12512       if (unformat (i, "index %d", &index))
12513         num_m_args++;
12514       else if (unformat (i, "psid %d", &psid))
12515         num_m_args++;
12516       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12517         num_m_args++;
12518       else if (unformat (i, "del"))
12519         {
12520           is_add = 0;
12521         }
12522       else
12523         {
12524           clib_warning ("parse error '%U'", format_unformat_error, i);
12525           return -99;
12526         }
12527     }
12528
12529   /* Construct the API message */
12530   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12531
12532   mp->index = ntohl (index);
12533   mp->is_add = is_add;
12534   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12535   mp->psid = ntohs (psid);
12536
12537   /* send it... */
12538   S;
12539
12540   /* Wait for a reply, return good/bad news  */
12541   W;
12542 }
12543
12544 static int
12545 api_map_domain_dump (vat_main_t * vam)
12546 {
12547   vl_api_map_domain_dump_t *mp;
12548   f64 timeout;
12549
12550   /* Construct the API message */
12551   M (MAP_DOMAIN_DUMP, map_domain_dump);
12552
12553   /* send it... */
12554   S;
12555
12556   /* Use a control ping for synchronization */
12557   {
12558     vl_api_control_ping_t *mp;
12559     M (CONTROL_PING, control_ping);
12560     S;
12561   }
12562   W;
12563 }
12564
12565 static int
12566 api_map_rule_dump (vat_main_t * vam)
12567 {
12568   unformat_input_t *i = vam->input;
12569   vl_api_map_rule_dump_t *mp;
12570   f64 timeout;
12571   u32 domain_index = ~0;
12572
12573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12574     {
12575       if (unformat (i, "index %u", &domain_index))
12576         ;
12577       else
12578         break;
12579     }
12580
12581   if (domain_index == ~0)
12582     {
12583       clib_warning ("parse error: domain index expected");
12584       return -99;
12585     }
12586
12587   /* Construct the API message */
12588   M (MAP_RULE_DUMP, map_rule_dump);
12589
12590   mp->domain_index = htonl (domain_index);
12591
12592   /* send it... */
12593   S;
12594
12595   /* Use a control ping for synchronization */
12596   {
12597     vl_api_control_ping_t *mp;
12598     M (CONTROL_PING, control_ping);
12599     S;
12600   }
12601   W;
12602 }
12603
12604 static void vl_api_map_add_domain_reply_t_handler
12605   (vl_api_map_add_domain_reply_t * mp)
12606 {
12607   vat_main_t *vam = &vat_main;
12608   i32 retval = ntohl (mp->retval);
12609
12610   if (vam->async_mode)
12611     {
12612       vam->async_errors += (retval < 0);
12613     }
12614   else
12615     {
12616       vam->retval = retval;
12617       vam->result_ready = 1;
12618     }
12619 }
12620
12621 static void vl_api_map_add_domain_reply_t_handler_json
12622   (vl_api_map_add_domain_reply_t * mp)
12623 {
12624   vat_main_t *vam = &vat_main;
12625   vat_json_node_t node;
12626
12627   vat_json_init_object (&node);
12628   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12629   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12630
12631   vat_json_print (vam->ofp, &node);
12632   vat_json_free (&node);
12633
12634   vam->retval = ntohl (mp->retval);
12635   vam->result_ready = 1;
12636 }
12637
12638 static int
12639 api_get_first_msg_id (vat_main_t * vam)
12640 {
12641   vl_api_get_first_msg_id_t *mp;
12642   f64 timeout;
12643   unformat_input_t *i = vam->input;
12644   u8 *name;
12645   u8 name_set = 0;
12646
12647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12648     {
12649       if (unformat (i, "client %s", &name))
12650         name_set = 1;
12651       else
12652         break;
12653     }
12654
12655   if (name_set == 0)
12656     {
12657       errmsg ("missing client name");
12658       return -99;
12659     }
12660   vec_add1 (name, 0);
12661
12662   if (vec_len (name) > 63)
12663     {
12664       errmsg ("client name too long");
12665       return -99;
12666     }
12667
12668   M (GET_FIRST_MSG_ID, get_first_msg_id);
12669   clib_memcpy (mp->name, name, vec_len (name));
12670   S;
12671   W;
12672   /* NOTREACHED */
12673   return 0;
12674 }
12675
12676 static int
12677 api_cop_interface_enable_disable (vat_main_t * vam)
12678 {
12679   unformat_input_t *line_input = vam->input;
12680   vl_api_cop_interface_enable_disable_t *mp;
12681   f64 timeout;
12682   u32 sw_if_index = ~0;
12683   u8 enable_disable = 1;
12684
12685   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12686     {
12687       if (unformat (line_input, "disable"))
12688         enable_disable = 0;
12689       if (unformat (line_input, "enable"))
12690         enable_disable = 1;
12691       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12692                          vam, &sw_if_index))
12693         ;
12694       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12695         ;
12696       else
12697         break;
12698     }
12699
12700   if (sw_if_index == ~0)
12701     {
12702       errmsg ("missing interface name or sw_if_index");
12703       return -99;
12704     }
12705
12706   /* Construct the API message */
12707   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12708   mp->sw_if_index = ntohl (sw_if_index);
12709   mp->enable_disable = enable_disable;
12710
12711   /* send it... */
12712   S;
12713   /* Wait for the reply */
12714   W;
12715 }
12716
12717 static int
12718 api_cop_whitelist_enable_disable (vat_main_t * vam)
12719 {
12720   unformat_input_t *line_input = vam->input;
12721   vl_api_cop_whitelist_enable_disable_t *mp;
12722   f64 timeout;
12723   u32 sw_if_index = ~0;
12724   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12725   u32 fib_id = 0;
12726
12727   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12728     {
12729       if (unformat (line_input, "ip4"))
12730         ip4 = 1;
12731       else if (unformat (line_input, "ip6"))
12732         ip6 = 1;
12733       else if (unformat (line_input, "default"))
12734         default_cop = 1;
12735       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12736                          vam, &sw_if_index))
12737         ;
12738       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12739         ;
12740       else if (unformat (line_input, "fib-id %d", &fib_id))
12741         ;
12742       else
12743         break;
12744     }
12745
12746   if (sw_if_index == ~0)
12747     {
12748       errmsg ("missing interface name or sw_if_index");
12749       return -99;
12750     }
12751
12752   /* Construct the API message */
12753   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12754   mp->sw_if_index = ntohl (sw_if_index);
12755   mp->fib_id = ntohl (fib_id);
12756   mp->ip4 = ip4;
12757   mp->ip6 = ip6;
12758   mp->default_cop = default_cop;
12759
12760   /* send it... */
12761   S;
12762   /* Wait for the reply */
12763   W;
12764 }
12765
12766 static int
12767 api_get_node_graph (vat_main_t * vam)
12768 {
12769   vl_api_get_node_graph_t *mp;
12770   f64 timeout;
12771
12772   M (GET_NODE_GRAPH, get_node_graph);
12773
12774   /* send it... */
12775   S;
12776   /* Wait for the reply */
12777   W;
12778 }
12779
12780 /* *INDENT-OFF* */
12781 /** Used for parsing LISP eids */
12782 typedef CLIB_PACKED(struct{
12783   u8 addr[16];   /**< eid address */
12784   u32 len;       /**< prefix length if IP */
12785   u8 type;      /**< type of eid */
12786 }) lisp_eid_vat_t;
12787 /* *INDENT-ON* */
12788
12789 static uword
12790 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12791 {
12792   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12793
12794   memset (a, 0, sizeof (a[0]));
12795
12796   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12797     {
12798       a->type = 0;              /* ipv4 type */
12799     }
12800   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12801     {
12802       a->type = 1;              /* ipv6 type */
12803     }
12804   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12805     {
12806       a->type = 2;              /* mac type */
12807     }
12808   else
12809     {
12810       return 0;
12811     }
12812
12813   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12814     {
12815       return 0;
12816     }
12817
12818   return 1;
12819 }
12820
12821 static int
12822 lisp_eid_size_vat (u8 type)
12823 {
12824   switch (type)
12825     {
12826     case 0:
12827       return 4;
12828     case 1:
12829       return 16;
12830     case 2:
12831       return 6;
12832     }
12833   return 0;
12834 }
12835
12836 static void
12837 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12838 {
12839   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12840 }
12841
12842 /* *INDENT-OFF* */
12843 /** Used for transferring locators via VPP API */
12844 typedef CLIB_PACKED(struct
12845 {
12846   u32 sw_if_index; /**< locator sw_if_index */
12847   u8 priority; /**< locator priority */
12848   u8 weight;   /**< locator weight */
12849 }) ls_locator_t;
12850 /* *INDENT-ON* */
12851
12852 static int
12853 api_lisp_add_del_locator_set (vat_main_t * vam)
12854 {
12855   unformat_input_t *input = vam->input;
12856   vl_api_lisp_add_del_locator_set_t *mp;
12857   f64 timeout = ~0;
12858   u8 is_add = 1;
12859   u8 *locator_set_name = NULL;
12860   u8 locator_set_name_set = 0;
12861   ls_locator_t locator, *locators = 0;
12862   u32 sw_if_index, priority, weight;
12863   u32 data_len = 0;
12864
12865   /* Parse args required to build the message */
12866   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12867     {
12868       if (unformat (input, "del"))
12869         {
12870           is_add = 0;
12871         }
12872       else if (unformat (input, "locator-set %s", &locator_set_name))
12873         {
12874           locator_set_name_set = 1;
12875         }
12876       else if (unformat (input, "sw_if_index %u p %u w %u",
12877                          &sw_if_index, &priority, &weight))
12878         {
12879           locator.sw_if_index = htonl (sw_if_index);
12880           locator.priority = priority;
12881           locator.weight = weight;
12882           vec_add1 (locators, locator);
12883         }
12884       else
12885         if (unformat
12886             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
12887              &sw_if_index, &priority, &weight))
12888         {
12889           locator.sw_if_index = htonl (sw_if_index);
12890           locator.priority = priority;
12891           locator.weight = weight;
12892           vec_add1 (locators, locator);
12893         }
12894       else
12895         break;
12896     }
12897
12898   if (locator_set_name_set == 0)
12899     {
12900       errmsg ("missing locator-set name");
12901       vec_free (locators);
12902       return -99;
12903     }
12904
12905   if (vec_len (locator_set_name) > 64)
12906     {
12907       errmsg ("locator-set name too long");
12908       vec_free (locator_set_name);
12909       vec_free (locators);
12910       return -99;
12911     }
12912   vec_add1 (locator_set_name, 0);
12913
12914   data_len = sizeof (ls_locator_t) * vec_len (locators);
12915
12916   /* Construct the API message */
12917   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12918
12919   mp->is_add = is_add;
12920   clib_memcpy (mp->locator_set_name, locator_set_name,
12921                vec_len (locator_set_name));
12922   vec_free (locator_set_name);
12923
12924   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12925   if (locators)
12926     clib_memcpy (mp->locators, locators, data_len);
12927   vec_free (locators);
12928
12929   /* send it... */
12930   S;
12931
12932   /* Wait for a reply... */
12933   W;
12934
12935   /* NOTREACHED */
12936   return 0;
12937 }
12938
12939 static int
12940 api_lisp_add_del_locator (vat_main_t * vam)
12941 {
12942   unformat_input_t *input = vam->input;
12943   vl_api_lisp_add_del_locator_t *mp;
12944   f64 timeout = ~0;
12945   u32 tmp_if_index = ~0;
12946   u32 sw_if_index = ~0;
12947   u8 sw_if_index_set = 0;
12948   u8 sw_if_index_if_name_set = 0;
12949   u32 priority = ~0;
12950   u8 priority_set = 0;
12951   u32 weight = ~0;
12952   u8 weight_set = 0;
12953   u8 is_add = 1;
12954   u8 *locator_set_name = NULL;
12955   u8 locator_set_name_set = 0;
12956
12957   /* Parse args required to build the message */
12958   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12959     {
12960       if (unformat (input, "del"))
12961         {
12962           is_add = 0;
12963         }
12964       else if (unformat (input, "locator-set %s", &locator_set_name))
12965         {
12966           locator_set_name_set = 1;
12967         }
12968       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
12969                          &tmp_if_index))
12970         {
12971           sw_if_index_if_name_set = 1;
12972           sw_if_index = tmp_if_index;
12973         }
12974       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12975         {
12976           sw_if_index_set = 1;
12977           sw_if_index = tmp_if_index;
12978         }
12979       else if (unformat (input, "p %d", &priority))
12980         {
12981           priority_set = 1;
12982         }
12983       else if (unformat (input, "w %d", &weight))
12984         {
12985           weight_set = 1;
12986         }
12987       else
12988         break;
12989     }
12990
12991   if (locator_set_name_set == 0)
12992     {
12993       errmsg ("missing locator-set name");
12994       return -99;
12995     }
12996
12997   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12998     {
12999       errmsg ("missing sw_if_index");
13000       vec_free (locator_set_name);
13001       return -99;
13002     }
13003
13004   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13005     {
13006       errmsg ("cannot use both params interface name and sw_if_index");
13007       vec_free (locator_set_name);
13008       return -99;
13009     }
13010
13011   if (priority_set == 0)
13012     {
13013       errmsg ("missing locator-set priority");
13014       vec_free (locator_set_name);
13015       return -99;
13016     }
13017
13018   if (weight_set == 0)
13019     {
13020       errmsg ("missing locator-set weight");
13021       vec_free (locator_set_name);
13022       return -99;
13023     }
13024
13025   if (vec_len (locator_set_name) > 64)
13026     {
13027       errmsg ("locator-set name too long");
13028       vec_free (locator_set_name);
13029       return -99;
13030     }
13031   vec_add1 (locator_set_name, 0);
13032
13033   /* Construct the API message */
13034   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
13035
13036   mp->is_add = is_add;
13037   mp->sw_if_index = ntohl (sw_if_index);
13038   mp->priority = priority;
13039   mp->weight = weight;
13040   clib_memcpy (mp->locator_set_name, locator_set_name,
13041                vec_len (locator_set_name));
13042   vec_free (locator_set_name);
13043
13044   /* send it... */
13045   S;
13046
13047   /* Wait for a reply... */
13048   W;
13049
13050   /* NOTREACHED */
13051   return 0;
13052 }
13053
13054 uword
13055 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13056 {
13057   u32 *key_id = va_arg (*args, u32 *);
13058   u8 *s = 0;
13059
13060   if (unformat (input, "%s", &s))
13061     {
13062       if (!strcmp ((char *) s, "sha1"))
13063         key_id[0] = HMAC_SHA_1_96;
13064       else if (!strcmp ((char *) s, "sha256"))
13065         key_id[0] = HMAC_SHA_256_128;
13066       else
13067         {
13068           clib_warning ("invalid key_id: '%s'", s);
13069           key_id[0] = HMAC_NO_KEY;
13070         }
13071     }
13072   else
13073     return 0;
13074
13075   vec_free (s);
13076   return 1;
13077 }
13078
13079 static int
13080 api_lisp_add_del_local_eid (vat_main_t * vam)
13081 {
13082   unformat_input_t *input = vam->input;
13083   vl_api_lisp_add_del_local_eid_t *mp;
13084   f64 timeout = ~0;
13085   u8 is_add = 1;
13086   u8 eid_set = 0;
13087   lisp_eid_vat_t _eid, *eid = &_eid;
13088   u8 *locator_set_name = 0;
13089   u8 locator_set_name_set = 0;
13090   u32 vni = 0;
13091   u16 key_id = 0;
13092   u8 *key = 0;
13093
13094   /* Parse args required to build the message */
13095   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13096     {
13097       if (unformat (input, "del"))
13098         {
13099           is_add = 0;
13100         }
13101       else if (unformat (input, "vni %d", &vni))
13102         {
13103           ;
13104         }
13105       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13106         {
13107           eid_set = 1;
13108         }
13109       else if (unformat (input, "locator-set %s", &locator_set_name))
13110         {
13111           locator_set_name_set = 1;
13112         }
13113       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13114         ;
13115       else if (unformat (input, "secret-key %_%v%_", &key))
13116         ;
13117       else
13118         break;
13119     }
13120
13121   if (locator_set_name_set == 0)
13122     {
13123       errmsg ("missing locator-set name");
13124       return -99;
13125     }
13126
13127   if (0 == eid_set)
13128     {
13129       errmsg ("EID address not set!");
13130       vec_free (locator_set_name);
13131       return -99;
13132     }
13133
13134   if (key && (0 == key_id))
13135     {
13136       errmsg ("invalid key_id!");
13137       return -99;
13138     }
13139
13140   if (vec_len (key) > 64)
13141     {
13142       errmsg ("key too long");
13143       vec_free (key);
13144       return -99;
13145     }
13146
13147   if (vec_len (locator_set_name) > 64)
13148     {
13149       errmsg ("locator-set name too long");
13150       vec_free (locator_set_name);
13151       return -99;
13152     }
13153   vec_add1 (locator_set_name, 0);
13154
13155   /* Construct the API message */
13156   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
13157
13158   mp->is_add = is_add;
13159   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13160   mp->eid_type = eid->type;
13161   mp->prefix_len = eid->len;
13162   mp->vni = clib_host_to_net_u32 (vni);
13163   mp->key_id = clib_host_to_net_u16 (key_id);
13164   clib_memcpy (mp->locator_set_name, locator_set_name,
13165                vec_len (locator_set_name));
13166   clib_memcpy (mp->key, key, vec_len (key));
13167
13168   vec_free (locator_set_name);
13169   vec_free (key);
13170
13171   /* send it... */
13172   S;
13173
13174   /* Wait for a reply... */
13175   W;
13176
13177   /* NOTREACHED */
13178   return 0;
13179 }
13180
13181 /* *INDENT-OFF* */
13182 /** Used for transferring locators via VPP API */
13183 typedef CLIB_PACKED(struct
13184 {
13185   u8 is_ip4; /**< is locator an IPv4 address? */
13186   u8 priority; /**< locator priority */
13187   u8 weight;   /**< locator weight */
13188   u8 addr[16]; /**< IPv4/IPv6 address */
13189 }) rloc_t;
13190 /* *INDENT-ON* */
13191
13192 static int
13193 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13194 {
13195   u32 dp_table = 0, vni = 0;;
13196   unformat_input_t *input = vam->input;
13197   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13198   f64 timeout = ~0;
13199   u8 is_add = 1;
13200   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13201   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13202   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13203   u32 action = ~0, w;
13204   ip4_address_t rmt_rloc4, lcl_rloc4;
13205   ip6_address_t rmt_rloc6, lcl_rloc6;
13206   vl_api_lisp_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc =
13207     0;
13208
13209   memset (&rloc, 0, sizeof (rloc));
13210
13211   /* Parse args required to build the message */
13212   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13213     {
13214       if (unformat (input, "del"))
13215         is_add = 0;
13216       else if (unformat (input, "add"))
13217         is_add = 1;
13218       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13219         {
13220           rmt_eid_set = 1;
13221         }
13222       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13223         {
13224           lcl_eid_set = 1;
13225         }
13226       else if (unformat (input, "vrf %d", &dp_table))
13227         ;
13228       else if (unformat (input, "bd %d", &dp_table))
13229         ;
13230       else if (unformat (input, "vni %d", &vni))
13231         ;
13232       else if (unformat (input, "w %d", &w))
13233         {
13234           if (!curr_rloc)
13235             {
13236               errmsg ("No RLOC configured for setting priority/weight!");
13237               return -99;
13238             }
13239           curr_rloc->weight = w;
13240         }
13241       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13242                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13243         {
13244           rloc.is_ip4 = 1;
13245
13246           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13247           rloc.weight = 0;
13248           vec_add1 (lcl_locs, rloc);
13249
13250           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13251           vec_add1 (rmt_locs, rloc);
13252           /* weight saved in rmt loc */
13253           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13254         }
13255       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13256                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13257         {
13258           rloc.is_ip4 = 0;
13259           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13260           rloc.weight = 0;
13261           vec_add1 (lcl_locs, rloc);
13262
13263           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13264           vec_add1 (rmt_locs, rloc);
13265           /* weight saved in rmt loc */
13266           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13267         }
13268       else if (unformat (input, "action %d", &action))
13269         {
13270           ;
13271         }
13272       else
13273         {
13274           clib_warning ("parse error '%U'", format_unformat_error, input);
13275           return -99;
13276         }
13277     }
13278
13279   if (!rmt_eid_set)
13280     {
13281       errmsg ("remote eid addresses not set");
13282       return -99;
13283     }
13284
13285   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13286     {
13287       errmsg ("eid types don't match");
13288       return -99;
13289     }
13290
13291   if (0 == rmt_locs && (u32) ~ 0 == action)
13292     {
13293       errmsg ("action not set for negative mapping");
13294       return -99;
13295     }
13296
13297   /* Construct the API message */
13298   M2 (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry,
13299       sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs) * 2);
13300
13301   mp->is_add = is_add;
13302   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13303   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13304   mp->eid_type = rmt_eid->type;
13305   mp->dp_table = clib_host_to_net_u32 (dp_table);
13306   mp->vni = clib_host_to_net_u32 (vni);
13307   mp->rmt_len = rmt_eid->len;
13308   mp->lcl_len = lcl_eid->len;
13309   mp->action = action;
13310
13311   if (0 != rmt_locs && 0 != lcl_locs)
13312     {
13313       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13314       clib_memcpy (mp->locs, lcl_locs,
13315                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs)));
13316
13317       u32 offset = sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs);
13318       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13319                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs)));
13320     }
13321   vec_free (lcl_locs);
13322   vec_free (rmt_locs);
13323
13324   /* send it... */
13325   S;
13326
13327   /* Wait for a reply... */
13328   W;
13329
13330   /* NOTREACHED */
13331   return 0;
13332 }
13333
13334 static int
13335 api_lisp_add_del_map_server (vat_main_t * vam)
13336 {
13337   unformat_input_t *input = vam->input;
13338   vl_api_lisp_add_del_map_server_t *mp;
13339   f64 timeout = ~0;
13340   u8 is_add = 1;
13341   u8 ipv4_set = 0;
13342   u8 ipv6_set = 0;
13343   ip4_address_t ipv4;
13344   ip6_address_t ipv6;
13345
13346   /* Parse args required to build the message */
13347   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13348     {
13349       if (unformat (input, "del"))
13350         {
13351           is_add = 0;
13352         }
13353       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13354         {
13355           ipv4_set = 1;
13356         }
13357       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13358         {
13359           ipv6_set = 1;
13360         }
13361       else
13362         break;
13363     }
13364
13365   if (ipv4_set && ipv6_set)
13366     {
13367       errmsg ("both eid v4 and v6 addresses set");
13368       return -99;
13369     }
13370
13371   if (!ipv4_set && !ipv6_set)
13372     {
13373       errmsg ("eid addresses not set");
13374       return -99;
13375     }
13376
13377   /* Construct the API message */
13378   M (LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server);
13379
13380   mp->is_add = is_add;
13381   if (ipv6_set)
13382     {
13383       mp->is_ipv6 = 1;
13384       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13385     }
13386   else
13387     {
13388       mp->is_ipv6 = 0;
13389       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13390     }
13391
13392   /* send it... */
13393   S;
13394
13395   /* Wait for a reply... */
13396   W;
13397
13398   /* NOTREACHED */
13399   return 0;
13400 }
13401
13402 static int
13403 api_lisp_add_del_map_resolver (vat_main_t * vam)
13404 {
13405   unformat_input_t *input = vam->input;
13406   vl_api_lisp_add_del_map_resolver_t *mp;
13407   f64 timeout = ~0;
13408   u8 is_add = 1;
13409   u8 ipv4_set = 0;
13410   u8 ipv6_set = 0;
13411   ip4_address_t ipv4;
13412   ip6_address_t ipv6;
13413
13414   /* Parse args required to build the message */
13415   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13416     {
13417       if (unformat (input, "del"))
13418         {
13419           is_add = 0;
13420         }
13421       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13422         {
13423           ipv4_set = 1;
13424         }
13425       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13426         {
13427           ipv6_set = 1;
13428         }
13429       else
13430         break;
13431     }
13432
13433   if (ipv4_set && ipv6_set)
13434     {
13435       errmsg ("both eid v4 and v6 addresses set");
13436       return -99;
13437     }
13438
13439   if (!ipv4_set && !ipv6_set)
13440     {
13441       errmsg ("eid addresses not set");
13442       return -99;
13443     }
13444
13445   /* Construct the API message */
13446   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13447
13448   mp->is_add = is_add;
13449   if (ipv6_set)
13450     {
13451       mp->is_ipv6 = 1;
13452       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13453     }
13454   else
13455     {
13456       mp->is_ipv6 = 0;
13457       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13458     }
13459
13460   /* send it... */
13461   S;
13462
13463   /* Wait for a reply... */
13464   W;
13465
13466   /* NOTREACHED */
13467   return 0;
13468 }
13469
13470 static int
13471 api_lisp_gpe_enable_disable (vat_main_t * vam)
13472 {
13473   unformat_input_t *input = vam->input;
13474   vl_api_lisp_gpe_enable_disable_t *mp;
13475   f64 timeout = ~0;
13476   u8 is_set = 0;
13477   u8 is_en = 1;
13478
13479   /* Parse args required to build the message */
13480   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13481     {
13482       if (unformat (input, "enable"))
13483         {
13484           is_set = 1;
13485           is_en = 1;
13486         }
13487       else if (unformat (input, "disable"))
13488         {
13489           is_set = 1;
13490           is_en = 0;
13491         }
13492       else
13493         break;
13494     }
13495
13496   if (is_set == 0)
13497     {
13498       errmsg ("Value not set");
13499       return -99;
13500     }
13501
13502   /* Construct the API message */
13503   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13504
13505   mp->is_en = is_en;
13506
13507   /* send it... */
13508   S;
13509
13510   /* Wait for a reply... */
13511   W;
13512
13513   /* NOTREACHED */
13514   return 0;
13515 }
13516
13517 static int
13518 api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
13519 {
13520   unformat_input_t *input = vam->input;
13521   vl_api_lisp_rloc_probe_enable_disable_t *mp;
13522   f64 timeout = ~0;
13523   u8 is_set = 0;
13524   u8 is_en = 0;
13525
13526   /* Parse args required to build the message */
13527   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13528     {
13529       if (unformat (input, "enable"))
13530         {
13531           is_set = 1;
13532           is_en = 1;
13533         }
13534       else if (unformat (input, "disable"))
13535         is_set = 1;
13536       else
13537         break;
13538     }
13539
13540   if (!is_set)
13541     {
13542       errmsg ("Value not set");
13543       return -99;
13544     }
13545
13546   /* Construct the API message */
13547   M (LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable);
13548
13549   mp->is_enabled = is_en;
13550
13551   /* send it... */
13552   S;
13553
13554   /* Wait for a reply... */
13555   W;
13556
13557   /* NOTREACHED */
13558   return 0;
13559 }
13560
13561 static int
13562 api_lisp_map_register_enable_disable (vat_main_t * vam)
13563 {
13564   unformat_input_t *input = vam->input;
13565   vl_api_lisp_map_register_enable_disable_t *mp;
13566   f64 timeout = ~0;
13567   u8 is_set = 0;
13568   u8 is_en = 0;
13569
13570   /* Parse args required to build the message */
13571   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13572     {
13573       if (unformat (input, "enable"))
13574         {
13575           is_set = 1;
13576           is_en = 1;
13577         }
13578       else if (unformat (input, "disable"))
13579         is_set = 1;
13580       else
13581         break;
13582     }
13583
13584   if (!is_set)
13585     {
13586       errmsg ("Value not set");
13587       return -99;
13588     }
13589
13590   /* Construct the API message */
13591   M (LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable);
13592
13593   mp->is_enabled = is_en;
13594
13595   /* send it... */
13596   S;
13597
13598   /* Wait for a reply... */
13599   W;
13600
13601   /* NOTREACHED */
13602   return 0;
13603 }
13604
13605 static int
13606 api_lisp_enable_disable (vat_main_t * vam)
13607 {
13608   unformat_input_t *input = vam->input;
13609   vl_api_lisp_enable_disable_t *mp;
13610   f64 timeout = ~0;
13611   u8 is_set = 0;
13612   u8 is_en = 0;
13613
13614   /* Parse args required to build the message */
13615   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13616     {
13617       if (unformat (input, "enable"))
13618         {
13619           is_set = 1;
13620           is_en = 1;
13621         }
13622       else if (unformat (input, "disable"))
13623         {
13624           is_set = 1;
13625         }
13626       else
13627         break;
13628     }
13629
13630   if (!is_set)
13631     {
13632       errmsg ("Value not set");
13633       return -99;
13634     }
13635
13636   /* Construct the API message */
13637   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13638
13639   mp->is_en = is_en;
13640
13641   /* send it... */
13642   S;
13643
13644   /* Wait for a reply... */
13645   W;
13646
13647   /* NOTREACHED */
13648   return 0;
13649 }
13650
13651 static int
13652 api_show_lisp_map_register_state (vat_main_t * vam)
13653 {
13654   f64 timeout = ~0;
13655   vl_api_show_lisp_map_register_state_t *mp;
13656
13657   M (SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state);
13658
13659   /* send */
13660   S;
13661
13662   /* wait for reply */
13663   W;
13664
13665   return 0;
13666 }
13667
13668 static int
13669 api_show_lisp_rloc_probe_state (vat_main_t * vam)
13670 {
13671   f64 timeout = ~0;
13672   vl_api_show_lisp_rloc_probe_state_t *mp;
13673
13674   M (SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state);
13675
13676   /* send */
13677   S;
13678
13679   /* wait for reply */
13680   W;
13681
13682   return 0;
13683 }
13684
13685 static int
13686 api_show_lisp_map_request_mode (vat_main_t * vam)
13687 {
13688   f64 timeout = ~0;
13689   vl_api_show_lisp_map_request_mode_t *mp;
13690
13691   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13692
13693   /* send */
13694   S;
13695
13696   /* wait for reply */
13697   W;
13698
13699   return 0;
13700 }
13701
13702 static int
13703 api_lisp_map_request_mode (vat_main_t * vam)
13704 {
13705   f64 timeout = ~0;
13706   unformat_input_t *input = vam->input;
13707   vl_api_lisp_map_request_mode_t *mp;
13708   u8 mode = 0;
13709
13710   /* Parse args required to build the message */
13711   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13712     {
13713       if (unformat (input, "dst-only"))
13714         mode = 0;
13715       else if (unformat (input, "src-dst"))
13716         mode = 1;
13717       else
13718         {
13719           errmsg ("parse error '%U'", format_unformat_error, input);
13720           return -99;
13721         }
13722     }
13723
13724   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13725
13726   mp->mode = mode;
13727
13728   /* send */
13729   S;
13730
13731   /* wait for reply */
13732   W;
13733
13734   /* notreached */
13735   return 0;
13736 }
13737
13738 /**
13739  * Enable/disable LISP proxy ITR.
13740  *
13741  * @param vam vpp API test context
13742  * @return return code
13743  */
13744 static int
13745 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13746 {
13747   f64 timeout = ~0;
13748   u8 ls_name_set = 0;
13749   unformat_input_t *input = vam->input;
13750   vl_api_lisp_pitr_set_locator_set_t *mp;
13751   u8 is_add = 1;
13752   u8 *ls_name = 0;
13753
13754   /* Parse args required to build the message */
13755   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13756     {
13757       if (unformat (input, "del"))
13758         is_add = 0;
13759       else if (unformat (input, "locator-set %s", &ls_name))
13760         ls_name_set = 1;
13761       else
13762         {
13763           errmsg ("parse error '%U'", format_unformat_error, input);
13764           return -99;
13765         }
13766     }
13767
13768   if (!ls_name_set)
13769     {
13770       errmsg ("locator-set name not set!");
13771       return -99;
13772     }
13773
13774   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13775
13776   mp->is_add = is_add;
13777   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13778   vec_free (ls_name);
13779
13780   /* send */
13781   S;
13782
13783   /* wait for reply */
13784   W;
13785
13786   /* notreached */
13787   return 0;
13788 }
13789
13790 static int
13791 api_show_lisp_pitr (vat_main_t * vam)
13792 {
13793   vl_api_show_lisp_pitr_t *mp;
13794   f64 timeout = ~0;
13795
13796   if (!vam->json_output)
13797     {
13798       print (vam->ofp, "%=20s", "lisp status:");
13799     }
13800
13801   M (SHOW_LISP_PITR, show_lisp_pitr);
13802   /* send it... */
13803   S;
13804
13805   /* Wait for a reply... */
13806   W;
13807
13808   /* NOTREACHED */
13809   return 0;
13810 }
13811
13812 /**
13813  * Add/delete mapping between vni and vrf
13814  */
13815 static int
13816 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13817 {
13818   f64 timeout = ~0;
13819   unformat_input_t *input = vam->input;
13820   vl_api_lisp_eid_table_add_del_map_t *mp;
13821   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13822   u32 vni, vrf, bd_index;
13823
13824   /* Parse args required to build the message */
13825   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13826     {
13827       if (unformat (input, "del"))
13828         is_add = 0;
13829       else if (unformat (input, "vrf %d", &vrf))
13830         vrf_set = 1;
13831       else if (unformat (input, "bd_index %d", &bd_index))
13832         bd_index_set = 1;
13833       else if (unformat (input, "vni %d", &vni))
13834         vni_set = 1;
13835       else
13836         break;
13837     }
13838
13839   if (!vni_set || (!vrf_set && !bd_index_set))
13840     {
13841       errmsg ("missing arguments!");
13842       return -99;
13843     }
13844
13845   if (vrf_set && bd_index_set)
13846     {
13847       errmsg ("error: both vrf and bd entered!");
13848       return -99;
13849     }
13850
13851   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13852
13853   mp->is_add = is_add;
13854   mp->vni = htonl (vni);
13855   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13856   mp->is_l2 = bd_index_set;
13857
13858   /* send */
13859   S;
13860
13861   /* wait for reply */
13862   W;
13863
13864   /* notreached */
13865   return 0;
13866 }
13867
13868 uword
13869 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13870 {
13871   u32 *action = va_arg (*args, u32 *);
13872   u8 *s = 0;
13873
13874   if (unformat (input, "%s", &s))
13875     {
13876       if (!strcmp ((char *) s, "no-action"))
13877         action[0] = 0;
13878       else if (!strcmp ((char *) s, "natively-forward"))
13879         action[0] = 1;
13880       else if (!strcmp ((char *) s, "send-map-request"))
13881         action[0] = 2;
13882       else if (!strcmp ((char *) s, "drop"))
13883         action[0] = 3;
13884       else
13885         {
13886           clib_warning ("invalid action: '%s'", s);
13887           action[0] = 3;
13888         }
13889     }
13890   else
13891     return 0;
13892
13893   vec_free (s);
13894   return 1;
13895 }
13896
13897 /**
13898  * Add/del remote mapping to/from LISP control plane
13899  *
13900  * @param vam vpp API test context
13901  * @return return code
13902  */
13903 static int
13904 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13905 {
13906   unformat_input_t *input = vam->input;
13907   vl_api_lisp_add_del_remote_mapping_t *mp;
13908   f64 timeout = ~0;
13909   u32 vni = 0;
13910   lisp_eid_vat_t _eid, *eid = &_eid;
13911   lisp_eid_vat_t _seid, *seid = &_seid;
13912   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13913   u32 action = ~0, p, w, data_len;
13914   ip4_address_t rloc4;
13915   ip6_address_t rloc6;
13916   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13917
13918   memset (&rloc, 0, sizeof (rloc));
13919
13920   /* Parse args required to build the message */
13921   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13922     {
13923       if (unformat (input, "del-all"))
13924         {
13925           del_all = 1;
13926         }
13927       else if (unformat (input, "del"))
13928         {
13929           is_add = 0;
13930         }
13931       else if (unformat (input, "add"))
13932         {
13933           is_add = 1;
13934         }
13935       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13936         {
13937           eid_set = 1;
13938         }
13939       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13940         {
13941           seid_set = 1;
13942         }
13943       else if (unformat (input, "vni %d", &vni))
13944         {
13945           ;
13946         }
13947       else if (unformat (input, "p %d w %d", &p, &w))
13948         {
13949           if (!curr_rloc)
13950             {
13951               errmsg ("No RLOC configured for setting priority/weight!");
13952               return -99;
13953             }
13954           curr_rloc->priority = p;
13955           curr_rloc->weight = w;
13956         }
13957       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13958         {
13959           rloc.is_ip4 = 1;
13960           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13961           vec_add1 (rlocs, rloc);
13962           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13963         }
13964       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13965         {
13966           rloc.is_ip4 = 0;
13967           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13968           vec_add1 (rlocs, rloc);
13969           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13970         }
13971       else if (unformat (input, "action %U",
13972                          unformat_negative_mapping_action, &action))
13973         {
13974           ;
13975         }
13976       else
13977         {
13978           clib_warning ("parse error '%U'", format_unformat_error, input);
13979           return -99;
13980         }
13981     }
13982
13983   if (0 == eid_set)
13984     {
13985       errmsg ("missing params!");
13986       return -99;
13987     }
13988
13989   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13990     {
13991       errmsg ("no action set for negative map-reply!");
13992       return -99;
13993     }
13994
13995   data_len = vec_len (rlocs) * sizeof (rloc_t);
13996
13997   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13998   mp->is_add = is_add;
13999   mp->vni = htonl (vni);
14000   mp->action = (u8) action;
14001   mp->is_src_dst = seid_set;
14002   mp->eid_len = eid->len;
14003   mp->seid_len = seid->len;
14004   mp->del_all = del_all;
14005   mp->eid_type = eid->type;
14006   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14007   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14008
14009   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14010   clib_memcpy (mp->rlocs, rlocs, data_len);
14011   vec_free (rlocs);
14012
14013   /* send it... */
14014   S;
14015
14016   /* Wait for a reply... */
14017   W;
14018
14019   /* NOTREACHED */
14020   return 0;
14021 }
14022
14023 /**
14024  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14025  * forwarding entries in data-plane accordingly.
14026  *
14027  * @param vam vpp API test context
14028  * @return return code
14029  */
14030 static int
14031 api_lisp_add_del_adjacency (vat_main_t * vam)
14032 {
14033   unformat_input_t *input = vam->input;
14034   vl_api_lisp_add_del_adjacency_t *mp;
14035   f64 timeout = ~0;
14036   u32 vni = 0;
14037   ip4_address_t leid4, reid4;
14038   ip6_address_t leid6, reid6;
14039   u8 reid_mac[6] = { 0 };
14040   u8 leid_mac[6] = { 0 };
14041   u8 reid_type, leid_type;
14042   u32 leid_len = 0, reid_len = 0, len;
14043   u8 is_add = 1;
14044
14045   leid_type = reid_type = (u8) ~ 0;
14046
14047   /* Parse args required to build the message */
14048   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14049     {
14050       if (unformat (input, "del"))
14051         {
14052           is_add = 0;
14053         }
14054       else if (unformat (input, "add"))
14055         {
14056           is_add = 1;
14057         }
14058       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14059                          &reid4, &len))
14060         {
14061           reid_type = 0;        /* ipv4 */
14062           reid_len = len;
14063         }
14064       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14065                          &reid6, &len))
14066         {
14067           reid_type = 1;        /* ipv6 */
14068           reid_len = len;
14069         }
14070       else if (unformat (input, "reid %U", unformat_ethernet_address,
14071                          reid_mac))
14072         {
14073           reid_type = 2;        /* mac */
14074         }
14075       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14076                          &leid4, &len))
14077         {
14078           leid_type = 0;        /* ipv4 */
14079           leid_len = len;
14080         }
14081       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14082                          &leid6, &len))
14083         {
14084           leid_type = 1;        /* ipv6 */
14085           leid_len = len;
14086         }
14087       else if (unformat (input, "leid %U", unformat_ethernet_address,
14088                          leid_mac))
14089         {
14090           leid_type = 2;        /* mac */
14091         }
14092       else if (unformat (input, "vni %d", &vni))
14093         {
14094           ;
14095         }
14096       else
14097         {
14098           errmsg ("parse error '%U'", format_unformat_error, input);
14099           return -99;
14100         }
14101     }
14102
14103   if ((u8) ~ 0 == reid_type)
14104     {
14105       errmsg ("missing params!");
14106       return -99;
14107     }
14108
14109   if (leid_type != reid_type)
14110     {
14111       errmsg ("remote and local EIDs are of different types!");
14112       return -99;
14113     }
14114
14115   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
14116   mp->is_add = is_add;
14117   mp->vni = htonl (vni);
14118   mp->leid_len = leid_len;
14119   mp->reid_len = reid_len;
14120   mp->eid_type = reid_type;
14121
14122   switch (mp->eid_type)
14123     {
14124     case 0:
14125       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14126       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14127       break;
14128     case 1:
14129       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14130       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14131       break;
14132     case 2:
14133       clib_memcpy (mp->leid, leid_mac, 6);
14134       clib_memcpy (mp->reid, reid_mac, 6);
14135       break;
14136     default:
14137       errmsg ("unknown EID type %d!", mp->eid_type);
14138       return 0;
14139     }
14140
14141   /* send it... */
14142   S;
14143
14144   /* Wait for a reply... */
14145   W;
14146
14147   /* NOTREACHED */
14148   return 0;
14149 }
14150
14151 static int
14152 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14153 {
14154   unformat_input_t *input = vam->input;
14155   vl_api_lisp_gpe_add_del_iface_t *mp;
14156   f64 timeout = ~0;
14157   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14158   u32 dp_table = 0, vni = 0;
14159
14160   /* Parse args required to build the message */
14161   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14162     {
14163       if (unformat (input, "up"))
14164         {
14165           action_set = 1;
14166           is_add = 1;
14167         }
14168       else if (unformat (input, "down"))
14169         {
14170           action_set = 1;
14171           is_add = 0;
14172         }
14173       else if (unformat (input, "table_id %d", &dp_table))
14174         {
14175           dp_table_set = 1;
14176         }
14177       else if (unformat (input, "bd_id %d", &dp_table))
14178         {
14179           dp_table_set = 1;
14180           is_l2 = 1;
14181         }
14182       else if (unformat (input, "vni %d", &vni))
14183         {
14184           vni_set = 1;
14185         }
14186       else
14187         break;
14188     }
14189
14190   if (action_set == 0)
14191     {
14192       errmsg ("Action not set");
14193       return -99;
14194     }
14195   if (dp_table_set == 0 || vni_set == 0)
14196     {
14197       errmsg ("vni and dp_table must be set");
14198       return -99;
14199     }
14200
14201   /* Construct the API message */
14202   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
14203
14204   mp->is_add = is_add;
14205   mp->dp_table = dp_table;
14206   mp->is_l2 = is_l2;
14207   mp->vni = vni;
14208
14209   /* send it... */
14210   S;
14211
14212   /* Wait for a reply... */
14213   W;
14214
14215   /* NOTREACHED */
14216   return 0;
14217 }
14218
14219 /**
14220  * Add/del map request itr rlocs from LISP control plane and updates
14221  *
14222  * @param vam vpp API test context
14223  * @return return code
14224  */
14225 static int
14226 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14227 {
14228   unformat_input_t *input = vam->input;
14229   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14230   f64 timeout = ~0;
14231   u8 *locator_set_name = 0;
14232   u8 locator_set_name_set = 0;
14233   u8 is_add = 1;
14234
14235   /* Parse args required to build the message */
14236   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14237     {
14238       if (unformat (input, "del"))
14239         {
14240           is_add = 0;
14241         }
14242       else if (unformat (input, "%_%v%_", &locator_set_name))
14243         {
14244           locator_set_name_set = 1;
14245         }
14246       else
14247         {
14248           clib_warning ("parse error '%U'", format_unformat_error, input);
14249           return -99;
14250         }
14251     }
14252
14253   if (is_add && !locator_set_name_set)
14254     {
14255       errmsg ("itr-rloc is not set!");
14256       return -99;
14257     }
14258
14259   if (is_add && vec_len (locator_set_name) > 64)
14260     {
14261       errmsg ("itr-rloc locator-set name too long");
14262       vec_free (locator_set_name);
14263       return -99;
14264     }
14265
14266   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
14267   mp->is_add = is_add;
14268   if (is_add)
14269     {
14270       clib_memcpy (mp->locator_set_name, locator_set_name,
14271                    vec_len (locator_set_name));
14272     }
14273   else
14274     {
14275       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14276     }
14277   vec_free (locator_set_name);
14278
14279   /* send it... */
14280   S;
14281
14282   /* Wait for a reply... */
14283   W;
14284
14285   /* NOTREACHED */
14286   return 0;
14287 }
14288
14289 static int
14290 api_lisp_locator_dump (vat_main_t * vam)
14291 {
14292   unformat_input_t *input = vam->input;
14293   vl_api_lisp_locator_dump_t *mp;
14294   f64 timeout = ~0;
14295   u8 is_index_set = 0, is_name_set = 0;
14296   u8 *ls_name = 0;
14297   u32 ls_index = ~0;
14298
14299   /* Parse args required to build the message */
14300   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14301     {
14302       if (unformat (input, "ls_name %_%v%_", &ls_name))
14303         {
14304           is_name_set = 1;
14305         }
14306       else if (unformat (input, "ls_index %d", &ls_index))
14307         {
14308           is_index_set = 1;
14309         }
14310       else
14311         {
14312           errmsg ("parse error '%U'", format_unformat_error, input);
14313           return -99;
14314         }
14315     }
14316
14317   if (!is_index_set && !is_name_set)
14318     {
14319       errmsg ("error: expected one of index or name!");
14320       return -99;
14321     }
14322
14323   if (is_index_set && is_name_set)
14324     {
14325       errmsg ("error: only one param expected!");
14326       return -99;
14327     }
14328
14329   if (vec_len (ls_name) > 62)
14330     {
14331       errmsg ("error: locator set name too long!");
14332       return -99;
14333     }
14334
14335   if (!vam->json_output)
14336     {
14337       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14338     }
14339
14340   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
14341   mp->is_index_set = is_index_set;
14342
14343   if (is_index_set)
14344     mp->ls_index = clib_host_to_net_u32 (ls_index);
14345   else
14346     {
14347       vec_add1 (ls_name, 0);
14348       strncpy ((char *) mp->ls_name, (char *) ls_name,
14349                sizeof (mp->ls_name) - 1);
14350     }
14351
14352   /* send it... */
14353   S;
14354
14355   /* Use a control ping for synchronization */
14356   {
14357     vl_api_control_ping_t *mp;
14358     M (CONTROL_PING, control_ping);
14359     S;
14360   }
14361   /* Wait for a reply... */
14362   W;
14363
14364   /* NOTREACHED */
14365   return 0;
14366 }
14367
14368 static int
14369 api_lisp_locator_set_dump (vat_main_t * vam)
14370 {
14371   vl_api_lisp_locator_set_dump_t *mp;
14372   unformat_input_t *input = vam->input;
14373   f64 timeout = ~0;
14374   u8 filter = 0;
14375
14376   /* Parse args required to build the message */
14377   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14378     {
14379       if (unformat (input, "local"))
14380         {
14381           filter = 1;
14382         }
14383       else if (unformat (input, "remote"))
14384         {
14385           filter = 2;
14386         }
14387       else
14388         {
14389           errmsg ("parse error '%U'", format_unformat_error, input);
14390           return -99;
14391         }
14392     }
14393
14394   if (!vam->json_output)
14395     {
14396       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14397     }
14398
14399   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14400
14401   mp->filter = filter;
14402
14403   /* send it... */
14404   S;
14405
14406   /* Use a control ping for synchronization */
14407   {
14408     vl_api_control_ping_t *mp;
14409     M (CONTROL_PING, control_ping);
14410     S;
14411   }
14412   /* Wait for a reply... */
14413   W;
14414
14415   /* NOTREACHED */
14416   return 0;
14417 }
14418
14419 static int
14420 api_lisp_eid_table_map_dump (vat_main_t * vam)
14421 {
14422   u8 is_l2 = 0;
14423   u8 mode_set = 0;
14424   unformat_input_t *input = vam->input;
14425   vl_api_lisp_eid_table_map_dump_t *mp;
14426   f64 timeout = ~0;
14427
14428   /* Parse args required to build the message */
14429   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14430     {
14431       if (unformat (input, "l2"))
14432         {
14433           is_l2 = 1;
14434           mode_set = 1;
14435         }
14436       else if (unformat (input, "l3"))
14437         {
14438           is_l2 = 0;
14439           mode_set = 1;
14440         }
14441       else
14442         {
14443           errmsg ("parse error '%U'", format_unformat_error, input);
14444           return -99;
14445         }
14446     }
14447
14448   if (!mode_set)
14449     {
14450       errmsg ("expected one of 'l2' or 'l3' parameter!");
14451       return -99;
14452     }
14453
14454   if (!vam->json_output)
14455     {
14456       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
14457     }
14458
14459   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14460   mp->is_l2 = is_l2;
14461
14462   /* send it... */
14463   S;
14464
14465   /* Use a control ping for synchronization */
14466   {
14467     vl_api_control_ping_t *mp;
14468     M (CONTROL_PING, control_ping);
14469     S;
14470   }
14471   /* Wait for a reply... */
14472   W;
14473
14474   /* NOTREACHED */
14475   return 0;
14476 }
14477
14478 static int
14479 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14480 {
14481   vl_api_lisp_eid_table_vni_dump_t *mp;
14482   f64 timeout = ~0;
14483
14484   if (!vam->json_output)
14485     {
14486       print (vam->ofp, "VNI");
14487     }
14488
14489   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14490
14491   /* send it... */
14492   S;
14493
14494   /* Use a control ping for synchronization */
14495   {
14496     vl_api_control_ping_t *mp;
14497     M (CONTROL_PING, control_ping);
14498     S;
14499   }
14500   /* Wait for a reply... */
14501   W;
14502
14503   /* NOTREACHED */
14504   return 0;
14505 }
14506
14507 static int
14508 api_lisp_eid_table_dump (vat_main_t * vam)
14509 {
14510   unformat_input_t *i = vam->input;
14511   vl_api_lisp_eid_table_dump_t *mp;
14512   f64 timeout = ~0;
14513   struct in_addr ip4;
14514   struct in6_addr ip6;
14515   u8 mac[6];
14516   u8 eid_type = ~0, eid_set = 0;
14517   u32 prefix_length = ~0, t, vni = 0;
14518   u8 filter = 0;
14519
14520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14521     {
14522       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14523         {
14524           eid_set = 1;
14525           eid_type = 0;
14526           prefix_length = t;
14527         }
14528       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14529         {
14530           eid_set = 1;
14531           eid_type = 1;
14532           prefix_length = t;
14533         }
14534       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14535         {
14536           eid_set = 1;
14537           eid_type = 2;
14538         }
14539       else if (unformat (i, "vni %d", &t))
14540         {
14541           vni = t;
14542         }
14543       else if (unformat (i, "local"))
14544         {
14545           filter = 1;
14546         }
14547       else if (unformat (i, "remote"))
14548         {
14549           filter = 2;
14550         }
14551       else
14552         {
14553           errmsg ("parse error '%U'", format_unformat_error, i);
14554           return -99;
14555         }
14556     }
14557
14558   if (!vam->json_output)
14559     {
14560       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
14561              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14562     }
14563
14564   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14565
14566   mp->filter = filter;
14567   if (eid_set)
14568     {
14569       mp->eid_set = 1;
14570       mp->vni = htonl (vni);
14571       mp->eid_type = eid_type;
14572       switch (eid_type)
14573         {
14574         case 0:
14575           mp->prefix_length = prefix_length;
14576           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14577           break;
14578         case 1:
14579           mp->prefix_length = prefix_length;
14580           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14581           break;
14582         case 2:
14583           clib_memcpy (mp->eid, mac, sizeof (mac));
14584           break;
14585         default:
14586           errmsg ("unknown EID type %d!", eid_type);
14587           return -99;
14588         }
14589     }
14590
14591   /* send it... */
14592   S;
14593
14594   /* Use a control ping for synchronization */
14595   {
14596     vl_api_control_ping_t *mp;
14597     M (CONTROL_PING, control_ping);
14598     S;
14599   }
14600
14601   /* Wait for a reply... */
14602   W;
14603
14604   /* NOTREACHED */
14605   return 0;
14606 }
14607
14608 static int
14609 api_lisp_adjacencies_get (vat_main_t * vam)
14610 {
14611   unformat_input_t *i = vam->input;
14612   vl_api_lisp_adjacencies_get_t *mp;
14613   f64 timeout = ~0;
14614   u8 vni_set = 0;
14615   u32 vni = ~0;
14616
14617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14618     {
14619       if (unformat (i, "vni %d", &vni))
14620         {
14621           vni_set = 1;
14622         }
14623       else
14624         {
14625           errmsg ("parse error '%U'", format_unformat_error, i);
14626           return -99;
14627         }
14628     }
14629
14630   if (!vni_set)
14631     {
14632       errmsg ("vni not set!");
14633       return -99;
14634     }
14635
14636   if (!vam->json_output)
14637     {
14638       print (vam->ofp, "%s %40s", "leid", "reid");
14639     }
14640
14641   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14642   mp->vni = clib_host_to_net_u32 (vni);
14643
14644   /* send it... */
14645   S;
14646
14647   /* Wait for a reply... */
14648   W;
14649
14650   /* NOTREACHED */
14651   return 0;
14652 }
14653
14654 static int
14655 api_lisp_map_server_dump (vat_main_t * vam)
14656 {
14657   vl_api_lisp_map_server_dump_t *mp;
14658   f64 timeout = ~0;
14659
14660   if (!vam->json_output)
14661     {
14662       print (vam->ofp, "%=20s", "Map server");
14663     }
14664
14665   M (LISP_MAP_SERVER_DUMP, lisp_map_server_dump);
14666   /* send it... */
14667   S;
14668
14669   /* Use a control ping for synchronization */
14670   {
14671     vl_api_control_ping_t *mp;
14672     M (CONTROL_PING, control_ping);
14673     S;
14674   }
14675   /* Wait for a reply... */
14676   W;
14677
14678   /* NOTREACHED */
14679   return 0;
14680 }
14681
14682 static int
14683 api_lisp_map_resolver_dump (vat_main_t * vam)
14684 {
14685   vl_api_lisp_map_resolver_dump_t *mp;
14686   f64 timeout = ~0;
14687
14688   if (!vam->json_output)
14689     {
14690       print (vam->ofp, "%=20s", "Map resolver");
14691     }
14692
14693   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14694   /* send it... */
14695   S;
14696
14697   /* Use a control ping for synchronization */
14698   {
14699     vl_api_control_ping_t *mp;
14700     M (CONTROL_PING, control_ping);
14701     S;
14702   }
14703   /* Wait for a reply... */
14704   W;
14705
14706   /* NOTREACHED */
14707   return 0;
14708 }
14709
14710 static int
14711 api_show_lisp_status (vat_main_t * vam)
14712 {
14713   vl_api_show_lisp_status_t *mp;
14714   f64 timeout = ~0;
14715
14716   if (!vam->json_output)
14717     {
14718       print (vam->ofp, "%-20s%-16s", "lisp status", "locator-set");
14719     }
14720
14721   M (SHOW_LISP_STATUS, show_lisp_status);
14722   /* send it... */
14723   S;
14724   /* Wait for a reply... */
14725   W;
14726
14727   /* NOTREACHED */
14728   return 0;
14729 }
14730
14731 static int
14732 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14733 {
14734   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14735   f64 timeout = ~0;
14736
14737   if (!vam->json_output)
14738     {
14739       print (vam->ofp, "%=20s", "itr-rlocs:");
14740     }
14741
14742   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14743   /* send it... */
14744   S;
14745   /* Wait for a reply... */
14746   W;
14747
14748   /* NOTREACHED */
14749   return 0;
14750 }
14751
14752 static int
14753 api_af_packet_create (vat_main_t * vam)
14754 {
14755   unformat_input_t *i = vam->input;
14756   vl_api_af_packet_create_t *mp;
14757   f64 timeout;
14758   u8 *host_if_name = 0;
14759   u8 hw_addr[6];
14760   u8 random_hw_addr = 1;
14761
14762   memset (hw_addr, 0, sizeof (hw_addr));
14763
14764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14765     {
14766       if (unformat (i, "name %s", &host_if_name))
14767         vec_add1 (host_if_name, 0);
14768       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14769         random_hw_addr = 0;
14770       else
14771         break;
14772     }
14773
14774   if (!vec_len (host_if_name))
14775     {
14776       errmsg ("host-interface name must be specified");
14777       return -99;
14778     }
14779
14780   if (vec_len (host_if_name) > 64)
14781     {
14782       errmsg ("host-interface name too long");
14783       return -99;
14784     }
14785
14786   M (AF_PACKET_CREATE, af_packet_create);
14787
14788   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14789   clib_memcpy (mp->hw_addr, hw_addr, 6);
14790   mp->use_random_hw_addr = random_hw_addr;
14791   vec_free (host_if_name);
14792
14793   S;
14794   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14795   /* NOTREACHED */
14796   return 0;
14797 }
14798
14799 static int
14800 api_af_packet_delete (vat_main_t * vam)
14801 {
14802   unformat_input_t *i = vam->input;
14803   vl_api_af_packet_delete_t *mp;
14804   f64 timeout;
14805   u8 *host_if_name = 0;
14806
14807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14808     {
14809       if (unformat (i, "name %s", &host_if_name))
14810         vec_add1 (host_if_name, 0);
14811       else
14812         break;
14813     }
14814
14815   if (!vec_len (host_if_name))
14816     {
14817       errmsg ("host-interface name must be specified");
14818       return -99;
14819     }
14820
14821   if (vec_len (host_if_name) > 64)
14822     {
14823       errmsg ("host-interface name too long");
14824       return -99;
14825     }
14826
14827   M (AF_PACKET_DELETE, af_packet_delete);
14828
14829   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14830   vec_free (host_if_name);
14831
14832   S;
14833   W;
14834   /* NOTREACHED */
14835   return 0;
14836 }
14837
14838 static int
14839 api_policer_add_del (vat_main_t * vam)
14840 {
14841   unformat_input_t *i = vam->input;
14842   vl_api_policer_add_del_t *mp;
14843   f64 timeout;
14844   u8 is_add = 1;
14845   u8 *name = 0;
14846   u32 cir = 0;
14847   u32 eir = 0;
14848   u64 cb = 0;
14849   u64 eb = 0;
14850   u8 rate_type = 0;
14851   u8 round_type = 0;
14852   u8 type = 0;
14853   u8 color_aware = 0;
14854   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14855
14856   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14857   conform_action.dscp = 0;
14858   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14859   exceed_action.dscp = 0;
14860   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14861   violate_action.dscp = 0;
14862
14863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14864     {
14865       if (unformat (i, "del"))
14866         is_add = 0;
14867       else if (unformat (i, "name %s", &name))
14868         vec_add1 (name, 0);
14869       else if (unformat (i, "cir %u", &cir))
14870         ;
14871       else if (unformat (i, "eir %u", &eir))
14872         ;
14873       else if (unformat (i, "cb %u", &cb))
14874         ;
14875       else if (unformat (i, "eb %u", &eb))
14876         ;
14877       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14878                          &rate_type))
14879         ;
14880       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14881                          &round_type))
14882         ;
14883       else if (unformat (i, "type %U", unformat_policer_type, &type))
14884         ;
14885       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14886                          &conform_action))
14887         ;
14888       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14889                          &exceed_action))
14890         ;
14891       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14892                          &violate_action))
14893         ;
14894       else if (unformat (i, "color-aware"))
14895         color_aware = 1;
14896       else
14897         break;
14898     }
14899
14900   if (!vec_len (name))
14901     {
14902       errmsg ("policer name must be specified");
14903       return -99;
14904     }
14905
14906   if (vec_len (name) > 64)
14907     {
14908       errmsg ("policer name too long");
14909       return -99;
14910     }
14911
14912   M (POLICER_ADD_DEL, policer_add_del);
14913
14914   clib_memcpy (mp->name, name, vec_len (name));
14915   vec_free (name);
14916   mp->is_add = is_add;
14917   mp->cir = cir;
14918   mp->eir = eir;
14919   mp->cb = cb;
14920   mp->eb = eb;
14921   mp->rate_type = rate_type;
14922   mp->round_type = round_type;
14923   mp->type = type;
14924   mp->conform_action_type = conform_action.action_type;
14925   mp->conform_dscp = conform_action.dscp;
14926   mp->exceed_action_type = exceed_action.action_type;
14927   mp->exceed_dscp = exceed_action.dscp;
14928   mp->violate_action_type = violate_action.action_type;
14929   mp->violate_dscp = violate_action.dscp;
14930   mp->color_aware = color_aware;
14931
14932   S;
14933   W;
14934   /* NOTREACHED */
14935   return 0;
14936 }
14937
14938 static int
14939 api_policer_dump (vat_main_t * vam)
14940 {
14941   unformat_input_t *i = vam->input;
14942   vl_api_policer_dump_t *mp;
14943   f64 timeout = ~0;
14944   u8 *match_name = 0;
14945   u8 match_name_valid = 0;
14946
14947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14948     {
14949       if (unformat (i, "name %s", &match_name))
14950         {
14951           vec_add1 (match_name, 0);
14952           match_name_valid = 1;
14953         }
14954       else
14955         break;
14956     }
14957
14958   M (POLICER_DUMP, policer_dump);
14959   mp->match_name_valid = match_name_valid;
14960   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14961   vec_free (match_name);
14962   /* send it... */
14963   S;
14964
14965   /* Use a control ping for synchronization */
14966   {
14967     vl_api_control_ping_t *mp;
14968     M (CONTROL_PING, control_ping);
14969     S;
14970   }
14971   /* Wait for a reply... */
14972   W;
14973
14974   /* NOTREACHED */
14975   return 0;
14976 }
14977
14978 static int
14979 api_policer_classify_set_interface (vat_main_t * vam)
14980 {
14981   unformat_input_t *i = vam->input;
14982   vl_api_policer_classify_set_interface_t *mp;
14983   f64 timeout;
14984   u32 sw_if_index;
14985   int sw_if_index_set;
14986   u32 ip4_table_index = ~0;
14987   u32 ip6_table_index = ~0;
14988   u32 l2_table_index = ~0;
14989   u8 is_add = 1;
14990
14991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14992     {
14993       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14994         sw_if_index_set = 1;
14995       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14996         sw_if_index_set = 1;
14997       else if (unformat (i, "del"))
14998         is_add = 0;
14999       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15000         ;
15001       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15002         ;
15003       else if (unformat (i, "l2-table %d", &l2_table_index))
15004         ;
15005       else
15006         {
15007           clib_warning ("parse error '%U'", format_unformat_error, i);
15008           return -99;
15009         }
15010     }
15011
15012   if (sw_if_index_set == 0)
15013     {
15014       errmsg ("missing interface name or sw_if_index");
15015       return -99;
15016     }
15017
15018   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
15019
15020   mp->sw_if_index = ntohl (sw_if_index);
15021   mp->ip4_table_index = ntohl (ip4_table_index);
15022   mp->ip6_table_index = ntohl (ip6_table_index);
15023   mp->l2_table_index = ntohl (l2_table_index);
15024   mp->is_add = is_add;
15025
15026   S;
15027   W;
15028   /* NOTREACHED */
15029   return 0;
15030 }
15031
15032 static int
15033 api_policer_classify_dump (vat_main_t * vam)
15034 {
15035   unformat_input_t *i = vam->input;
15036   vl_api_policer_classify_dump_t *mp;
15037   f64 timeout = ~0;
15038   u8 type = POLICER_CLASSIFY_N_TABLES;
15039
15040   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15041     ;
15042   else
15043     {
15044       errmsg ("classify table type must be specified");
15045       return -99;
15046     }
15047
15048   if (!vam->json_output)
15049     {
15050       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15051     }
15052
15053   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
15054   mp->type = type;
15055   /* send it... */
15056   S;
15057
15058   /* Use a control ping for synchronization */
15059   {
15060     vl_api_control_ping_t *mp;
15061     M (CONTROL_PING, control_ping);
15062     S;
15063   }
15064   /* Wait for a reply... */
15065   W;
15066
15067   /* NOTREACHED */
15068   return 0;
15069 }
15070
15071 static int
15072 api_netmap_create (vat_main_t * vam)
15073 {
15074   unformat_input_t *i = vam->input;
15075   vl_api_netmap_create_t *mp;
15076   f64 timeout;
15077   u8 *if_name = 0;
15078   u8 hw_addr[6];
15079   u8 random_hw_addr = 1;
15080   u8 is_pipe = 0;
15081   u8 is_master = 0;
15082
15083   memset (hw_addr, 0, sizeof (hw_addr));
15084
15085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15086     {
15087       if (unformat (i, "name %s", &if_name))
15088         vec_add1 (if_name, 0);
15089       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15090         random_hw_addr = 0;
15091       else if (unformat (i, "pipe"))
15092         is_pipe = 1;
15093       else if (unformat (i, "master"))
15094         is_master = 1;
15095       else if (unformat (i, "slave"))
15096         is_master = 0;
15097       else
15098         break;
15099     }
15100
15101   if (!vec_len (if_name))
15102     {
15103       errmsg ("interface name must be specified");
15104       return -99;
15105     }
15106
15107   if (vec_len (if_name) > 64)
15108     {
15109       errmsg ("interface name too long");
15110       return -99;
15111     }
15112
15113   M (NETMAP_CREATE, netmap_create);
15114
15115   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15116   clib_memcpy (mp->hw_addr, hw_addr, 6);
15117   mp->use_random_hw_addr = random_hw_addr;
15118   mp->is_pipe = is_pipe;
15119   mp->is_master = is_master;
15120   vec_free (if_name);
15121
15122   S;
15123   W;
15124   /* NOTREACHED */
15125   return 0;
15126 }
15127
15128 static int
15129 api_netmap_delete (vat_main_t * vam)
15130 {
15131   unformat_input_t *i = vam->input;
15132   vl_api_netmap_delete_t *mp;
15133   f64 timeout;
15134   u8 *if_name = 0;
15135
15136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15137     {
15138       if (unformat (i, "name %s", &if_name))
15139         vec_add1 (if_name, 0);
15140       else
15141         break;
15142     }
15143
15144   if (!vec_len (if_name))
15145     {
15146       errmsg ("interface name must be specified");
15147       return -99;
15148     }
15149
15150   if (vec_len (if_name) > 64)
15151     {
15152       errmsg ("interface name too long");
15153       return -99;
15154     }
15155
15156   M (NETMAP_DELETE, netmap_delete);
15157
15158   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15159   vec_free (if_name);
15160
15161   S;
15162   W;
15163   /* NOTREACHED */
15164   return 0;
15165 }
15166
15167 static void vl_api_mpls_tunnel_details_t_handler
15168   (vl_api_mpls_tunnel_details_t * mp)
15169 {
15170   vat_main_t *vam = &vat_main;
15171   i32 len = mp->mt_next_hop_n_labels;
15172   i32 i;
15173
15174   print (vam->ofp, "[%d]: via %U %d labels ",
15175          mp->tunnel_index,
15176          format_ip4_address, mp->mt_next_hop,
15177          ntohl (mp->mt_next_hop_sw_if_index));
15178   for (i = 0; i < len; i++)
15179     {
15180       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15181     }
15182   print (vam->ofp, "");
15183 }
15184
15185 static void vl_api_mpls_tunnel_details_t_handler_json
15186   (vl_api_mpls_tunnel_details_t * mp)
15187 {
15188   vat_main_t *vam = &vat_main;
15189   vat_json_node_t *node = NULL;
15190   struct in_addr ip4;
15191   i32 i;
15192   i32 len = mp->mt_next_hop_n_labels;
15193
15194   if (VAT_JSON_ARRAY != vam->json_tree.type)
15195     {
15196       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15197       vat_json_init_array (&vam->json_tree);
15198     }
15199   node = vat_json_array_add (&vam->json_tree);
15200
15201   vat_json_init_object (node);
15202   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15203   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15204   vat_json_object_add_ip4 (node, "next_hop", ip4);
15205   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15206                             ntohl (mp->mt_next_hop_sw_if_index));
15207   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15208   vat_json_object_add_uint (node, "label_count", len);
15209   for (i = 0; i < len; i++)
15210     {
15211       vat_json_object_add_uint (node, "label",
15212                                 ntohl (mp->mt_next_hop_out_labels[i]));
15213     }
15214 }
15215
15216 static int
15217 api_mpls_tunnel_dump (vat_main_t * vam)
15218 {
15219   vl_api_mpls_tunnel_dump_t *mp;
15220   f64 timeout;
15221   i32 index = -1;
15222
15223   /* Parse args required to build the message */
15224   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15225     {
15226       if (!unformat (vam->input, "tunnel_index %d", &index))
15227         {
15228           index = -1;
15229           break;
15230         }
15231     }
15232
15233   print (vam->ofp, "  tunnel_index %d", index);
15234
15235   M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
15236   mp->tunnel_index = htonl (index);
15237   S;
15238
15239   /* Use a control ping for synchronization */
15240   {
15241     vl_api_control_ping_t *mp;
15242     M (CONTROL_PING, control_ping);
15243     S;
15244   }
15245   W;
15246 }
15247
15248 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15249 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15250
15251 static void
15252 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15253 {
15254   vat_main_t *vam = &vat_main;
15255   int count = ntohl (mp->count);
15256   vl_api_fib_path2_t *fp;
15257   int i;
15258
15259   print (vam->ofp,
15260          "table-id %d, label %u, ess_bit %u",
15261          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15262   fp = mp->path;
15263   for (i = 0; i < count; i++)
15264     {
15265       if (fp->afi == IP46_TYPE_IP6)
15266         print (vam->ofp,
15267                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15268                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15269                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15270                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15271                format_ip6_address, fp->next_hop);
15272       else if (fp->afi == IP46_TYPE_IP4)
15273         print (vam->ofp,
15274                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15275                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15276                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15277                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15278                format_ip4_address, fp->next_hop);
15279       fp++;
15280     }
15281 }
15282
15283 static void vl_api_mpls_fib_details_t_handler_json
15284   (vl_api_mpls_fib_details_t * mp)
15285 {
15286   vat_main_t *vam = &vat_main;
15287   int count = ntohl (mp->count);
15288   vat_json_node_t *node = NULL;
15289   struct in_addr ip4;
15290   struct in6_addr ip6;
15291   vl_api_fib_path2_t *fp;
15292   int i;
15293
15294   if (VAT_JSON_ARRAY != vam->json_tree.type)
15295     {
15296       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15297       vat_json_init_array (&vam->json_tree);
15298     }
15299   node = vat_json_array_add (&vam->json_tree);
15300
15301   vat_json_init_object (node);
15302   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15303   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15304   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15305   vat_json_object_add_uint (node, "path_count", count);
15306   fp = mp->path;
15307   for (i = 0; i < count; i++)
15308     {
15309       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15310       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15311       vat_json_object_add_uint (node, "is_local", fp->is_local);
15312       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15313       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15314       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15315       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15316       if (fp->afi == IP46_TYPE_IP4)
15317         {
15318           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15319           vat_json_object_add_ip4 (node, "next_hop", ip4);
15320         }
15321       else if (fp->afi == IP46_TYPE_IP6)
15322         {
15323           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15324           vat_json_object_add_ip6 (node, "next_hop", ip6);
15325         }
15326     }
15327 }
15328
15329 static int
15330 api_mpls_fib_dump (vat_main_t * vam)
15331 {
15332   vl_api_mpls_fib_dump_t *mp;
15333   f64 timeout;
15334
15335   M (MPLS_FIB_DUMP, mpls_fib_dump);
15336   S;
15337
15338   /* Use a control ping for synchronization */
15339   {
15340     vl_api_control_ping_t *mp;
15341     M (CONTROL_PING, control_ping);
15342     S;
15343   }
15344   W;
15345 }
15346
15347 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15348 #define vl_api_ip_fib_details_t_print vl_noop_handler
15349
15350 static void
15351 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15352 {
15353   vat_main_t *vam = &vat_main;
15354   int count = ntohl (mp->count);
15355   vl_api_fib_path_t *fp;
15356   int i;
15357
15358   print (vam->ofp,
15359          "table-id %d, prefix %U/%d",
15360          ntohl (mp->table_id), format_ip4_address, mp->address,
15361          mp->address_length);
15362   fp = mp->path;
15363   for (i = 0; i < count; i++)
15364     {
15365       if (fp->afi == IP46_TYPE_IP6)
15366         print (vam->ofp,
15367                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15368                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15369                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15370                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15371                format_ip6_address, fp->next_hop);
15372       else if (fp->afi == IP46_TYPE_IP4)
15373         print (vam->ofp,
15374                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15375                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15376                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15377                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15378                format_ip4_address, fp->next_hop);
15379       fp++;
15380     }
15381 }
15382
15383 static void vl_api_ip_fib_details_t_handler_json
15384   (vl_api_ip_fib_details_t * mp)
15385 {
15386   vat_main_t *vam = &vat_main;
15387   int count = ntohl (mp->count);
15388   vat_json_node_t *node = NULL;
15389   struct in_addr ip4;
15390   struct in6_addr ip6;
15391   vl_api_fib_path_t *fp;
15392   int i;
15393
15394   if (VAT_JSON_ARRAY != vam->json_tree.type)
15395     {
15396       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15397       vat_json_init_array (&vam->json_tree);
15398     }
15399   node = vat_json_array_add (&vam->json_tree);
15400
15401   vat_json_init_object (node);
15402   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15403   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15404   vat_json_object_add_ip4 (node, "prefix", ip4);
15405   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15406   vat_json_object_add_uint (node, "path_count", count);
15407   fp = mp->path;
15408   for (i = 0; i < count; i++)
15409     {
15410       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15411       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15412       vat_json_object_add_uint (node, "is_local", fp->is_local);
15413       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15414       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15415       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15416       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15417       if (fp->afi == IP46_TYPE_IP4)
15418         {
15419           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15420           vat_json_object_add_ip4 (node, "next_hop", ip4);
15421         }
15422       else if (fp->afi == IP46_TYPE_IP6)
15423         {
15424           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15425           vat_json_object_add_ip6 (node, "next_hop", ip6);
15426         }
15427     }
15428 }
15429
15430 static int
15431 api_ip_fib_dump (vat_main_t * vam)
15432 {
15433   vl_api_ip_fib_dump_t *mp;
15434   f64 timeout;
15435
15436   M (IP_FIB_DUMP, ip_fib_dump);
15437   S;
15438
15439   /* Use a control ping for synchronization */
15440   {
15441     vl_api_control_ping_t *mp;
15442     M (CONTROL_PING, control_ping);
15443     S;
15444   }
15445   W;
15446 }
15447
15448 static void vl_api_ip_neighbor_details_t_handler
15449   (vl_api_ip_neighbor_details_t * mp)
15450 {
15451   vat_main_t *vam = &vat_main;
15452
15453   print (vam->ofp, "%c %U %U",
15454          (mp->is_static) ? 'S' : 'D',
15455          format_ethernet_address, &mp->mac_address,
15456          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15457          &mp->ip_address);
15458 }
15459
15460 static void vl_api_ip_neighbor_details_t_handler_json
15461   (vl_api_ip_neighbor_details_t * mp)
15462 {
15463
15464   vat_main_t *vam = &vat_main;
15465   vat_json_node_t *node;
15466   struct in_addr ip4;
15467   struct in6_addr ip6;
15468
15469   if (VAT_JSON_ARRAY != vam->json_tree.type)
15470     {
15471       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15472       vat_json_init_array (&vam->json_tree);
15473     }
15474   node = vat_json_array_add (&vam->json_tree);
15475
15476   vat_json_init_object (node);
15477   vat_json_object_add_string_copy (node, "flag",
15478                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15479                                    "dynamic");
15480
15481   vat_json_object_add_string_copy (node, "link_layer",
15482                                    format (0, "%U", format_ethernet_address,
15483                                            &mp->mac_address));
15484
15485   if (mp->is_ipv6)
15486     {
15487       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15488       vat_json_object_add_ip6 (node, "ip_address", ip6);
15489     }
15490   else
15491     {
15492       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15493       vat_json_object_add_ip4 (node, "ip_address", ip4);
15494     }
15495 }
15496
15497 static int
15498 api_ip_neighbor_dump (vat_main_t * vam)
15499 {
15500   unformat_input_t *i = vam->input;
15501   vl_api_ip_neighbor_dump_t *mp;
15502   f64 timeout;
15503   u8 is_ipv6 = 0;
15504   u32 sw_if_index = ~0;
15505
15506   /* Parse args required to build the message */
15507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15508     {
15509       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15510         ;
15511       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15512         ;
15513       else if (unformat (i, "ip6"))
15514         is_ipv6 = 1;
15515       else
15516         break;
15517     }
15518
15519   if (sw_if_index == ~0)
15520     {
15521       errmsg ("missing interface name or sw_if_index");
15522       return -99;
15523     }
15524
15525   M (IP_NEIGHBOR_DUMP, ip_neighbor_dump);
15526   mp->is_ipv6 = (u8) is_ipv6;
15527   mp->sw_if_index = ntohl (sw_if_index);
15528   S;
15529
15530   /* Use a control ping for synchronization */
15531   {
15532     vl_api_control_ping_t *mp;
15533     M (CONTROL_PING, control_ping);
15534     S;
15535   }
15536   W;
15537 }
15538
15539 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15540 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15541
15542 static void
15543 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15544 {
15545   vat_main_t *vam = &vat_main;
15546   int count = ntohl (mp->count);
15547   vl_api_fib_path_t *fp;
15548   int i;
15549
15550   print (vam->ofp,
15551          "table-id %d, prefix %U/%d",
15552          ntohl (mp->table_id), format_ip6_address, mp->address,
15553          mp->address_length);
15554   fp = mp->path;
15555   for (i = 0; i < count; i++)
15556     {
15557       if (fp->afi == IP46_TYPE_IP6)
15558         print (vam->ofp,
15559                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15560                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15561                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15562                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15563                format_ip6_address, fp->next_hop);
15564       else if (fp->afi == IP46_TYPE_IP4)
15565         print (vam->ofp,
15566                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15567                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15568                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15569                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15570                format_ip4_address, fp->next_hop);
15571       fp++;
15572     }
15573 }
15574
15575 static void vl_api_ip6_fib_details_t_handler_json
15576   (vl_api_ip6_fib_details_t * mp)
15577 {
15578   vat_main_t *vam = &vat_main;
15579   int count = ntohl (mp->count);
15580   vat_json_node_t *node = NULL;
15581   struct in_addr ip4;
15582   struct in6_addr ip6;
15583   vl_api_fib_path_t *fp;
15584   int i;
15585
15586   if (VAT_JSON_ARRAY != vam->json_tree.type)
15587     {
15588       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15589       vat_json_init_array (&vam->json_tree);
15590     }
15591   node = vat_json_array_add (&vam->json_tree);
15592
15593   vat_json_init_object (node);
15594   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15595   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15596   vat_json_object_add_ip6 (node, "prefix", ip6);
15597   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15598   vat_json_object_add_uint (node, "path_count", count);
15599   fp = mp->path;
15600   for (i = 0; i < count; i++)
15601     {
15602       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15603       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15604       vat_json_object_add_uint (node, "is_local", fp->is_local);
15605       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15606       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15607       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15608       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15609       if (fp->afi == IP46_TYPE_IP4)
15610         {
15611           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15612           vat_json_object_add_ip4 (node, "next_hop", ip4);
15613         }
15614       else if (fp->afi == IP46_TYPE_IP6)
15615         {
15616           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15617           vat_json_object_add_ip6 (node, "next_hop", ip6);
15618         }
15619     }
15620 }
15621
15622 static int
15623 api_ip6_fib_dump (vat_main_t * vam)
15624 {
15625   vl_api_ip6_fib_dump_t *mp;
15626   f64 timeout;
15627
15628   M (IP6_FIB_DUMP, ip6_fib_dump);
15629   S;
15630
15631   /* Use a control ping for synchronization */
15632   {
15633     vl_api_control_ping_t *mp;
15634     M (CONTROL_PING, control_ping);
15635     S;
15636   }
15637   W;
15638 }
15639
15640 int
15641 api_classify_table_ids (vat_main_t * vam)
15642 {
15643   vl_api_classify_table_ids_t *mp;
15644   f64 timeout;
15645
15646   /* Construct the API message */
15647   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15648   mp->context = 0;
15649
15650   S;
15651   W;
15652   /* NOTREACHED */
15653   return 0;
15654 }
15655
15656 int
15657 api_classify_table_by_interface (vat_main_t * vam)
15658 {
15659   unformat_input_t *input = vam->input;
15660   vl_api_classify_table_by_interface_t *mp;
15661   f64 timeout;
15662
15663   u32 sw_if_index = ~0;
15664   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15665     {
15666       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15667         ;
15668       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15669         ;
15670       else
15671         break;
15672     }
15673   if (sw_if_index == ~0)
15674     {
15675       errmsg ("missing interface name or sw_if_index");
15676       return -99;
15677     }
15678
15679   /* Construct the API message */
15680   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15681   mp->context = 0;
15682   mp->sw_if_index = ntohl (sw_if_index);
15683
15684   S;
15685   W;
15686   /* NOTREACHED */
15687   return 0;
15688 }
15689
15690 int
15691 api_classify_table_info (vat_main_t * vam)
15692 {
15693   unformat_input_t *input = vam->input;
15694   vl_api_classify_table_info_t *mp;
15695   f64 timeout;
15696
15697   u32 table_id = ~0;
15698   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15699     {
15700       if (unformat (input, "table_id %d", &table_id))
15701         ;
15702       else
15703         break;
15704     }
15705   if (table_id == ~0)
15706     {
15707       errmsg ("missing table id");
15708       return -99;
15709     }
15710
15711   /* Construct the API message */
15712   M (CLASSIFY_TABLE_INFO, classify_table_info);
15713   mp->context = 0;
15714   mp->table_id = ntohl (table_id);
15715
15716   S;
15717   W;
15718   /* NOTREACHED */
15719   return 0;
15720 }
15721
15722 int
15723 api_classify_session_dump (vat_main_t * vam)
15724 {
15725   unformat_input_t *input = vam->input;
15726   vl_api_classify_session_dump_t *mp;
15727   f64 timeout;
15728
15729   u32 table_id = ~0;
15730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15731     {
15732       if (unformat (input, "table_id %d", &table_id))
15733         ;
15734       else
15735         break;
15736     }
15737   if (table_id == ~0)
15738     {
15739       errmsg ("missing table id");
15740       return -99;
15741     }
15742
15743   /* Construct the API message */
15744   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15745   mp->context = 0;
15746   mp->table_id = ntohl (table_id);
15747   S;
15748
15749   /* Use a control ping for synchronization */
15750   {
15751     vl_api_control_ping_t *mp;
15752     M (CONTROL_PING, control_ping);
15753     S;
15754   }
15755   W;
15756   /* NOTREACHED */
15757   return 0;
15758 }
15759
15760 static void
15761 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15762 {
15763   vat_main_t *vam = &vat_main;
15764
15765   print (vam->ofp, "collector_address %U, collector_port %d, "
15766          "src_address %U, vrf_id %d, path_mtu %u, "
15767          "template_interval %u, udp_checksum %d",
15768          format_ip4_address, mp->collector_address,
15769          ntohs (mp->collector_port),
15770          format_ip4_address, mp->src_address,
15771          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15772          ntohl (mp->template_interval), mp->udp_checksum);
15773
15774   vam->retval = 0;
15775   vam->result_ready = 1;
15776 }
15777
15778 static void
15779   vl_api_ipfix_exporter_details_t_handler_json
15780   (vl_api_ipfix_exporter_details_t * mp)
15781 {
15782   vat_main_t *vam = &vat_main;
15783   vat_json_node_t node;
15784   struct in_addr collector_address;
15785   struct in_addr src_address;
15786
15787   vat_json_init_object (&node);
15788   clib_memcpy (&collector_address, &mp->collector_address,
15789                sizeof (collector_address));
15790   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15791   vat_json_object_add_uint (&node, "collector_port",
15792                             ntohs (mp->collector_port));
15793   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15794   vat_json_object_add_ip4 (&node, "src_address", src_address);
15795   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15796   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15797   vat_json_object_add_uint (&node, "template_interval",
15798                             ntohl (mp->template_interval));
15799   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15800
15801   vat_json_print (vam->ofp, &node);
15802   vat_json_free (&node);
15803   vam->retval = 0;
15804   vam->result_ready = 1;
15805 }
15806
15807 int
15808 api_ipfix_exporter_dump (vat_main_t * vam)
15809 {
15810   vl_api_ipfix_exporter_dump_t *mp;
15811   f64 timeout;
15812
15813   /* Construct the API message */
15814   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15815   mp->context = 0;
15816
15817   S;
15818   W;
15819   /* NOTREACHED */
15820   return 0;
15821 }
15822
15823 static int
15824 api_ipfix_classify_stream_dump (vat_main_t * vam)
15825 {
15826   vl_api_ipfix_classify_stream_dump_t *mp;
15827   f64 timeout;
15828
15829   /* Construct the API message */
15830   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15831   mp->context = 0;
15832
15833   S;
15834   W;
15835   /* NOTREACHED */
15836   return 0;
15837 }
15838
15839 static void
15840   vl_api_ipfix_classify_stream_details_t_handler
15841   (vl_api_ipfix_classify_stream_details_t * mp)
15842 {
15843   vat_main_t *vam = &vat_main;
15844   print (vam->ofp, "domain_id %d, src_port %d",
15845          ntohl (mp->domain_id), ntohs (mp->src_port));
15846   vam->retval = 0;
15847   vam->result_ready = 1;
15848 }
15849
15850 static void
15851   vl_api_ipfix_classify_stream_details_t_handler_json
15852   (vl_api_ipfix_classify_stream_details_t * mp)
15853 {
15854   vat_main_t *vam = &vat_main;
15855   vat_json_node_t node;
15856
15857   vat_json_init_object (&node);
15858   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15859   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15860
15861   vat_json_print (vam->ofp, &node);
15862   vat_json_free (&node);
15863   vam->retval = 0;
15864   vam->result_ready = 1;
15865 }
15866
15867 static int
15868 api_ipfix_classify_table_dump (vat_main_t * vam)
15869 {
15870   vl_api_ipfix_classify_table_dump_t *mp;
15871   f64 timeout;
15872
15873   if (!vam->json_output)
15874     {
15875       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
15876              "transport_protocol");
15877     }
15878
15879   /* Construct the API message */
15880   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15881
15882   /* send it... */
15883   S;
15884
15885   /* Use a control ping for synchronization */
15886   {
15887     vl_api_control_ping_t *mp;
15888     M (CONTROL_PING, control_ping);
15889     S;
15890   }
15891   W;
15892 }
15893
15894 static void
15895   vl_api_ipfix_classify_table_details_t_handler
15896   (vl_api_ipfix_classify_table_details_t * mp)
15897 {
15898   vat_main_t *vam = &vat_main;
15899   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
15900          mp->transport_protocol);
15901 }
15902
15903 static void
15904   vl_api_ipfix_classify_table_details_t_handler_json
15905   (vl_api_ipfix_classify_table_details_t * mp)
15906 {
15907   vat_json_node_t *node = NULL;
15908   vat_main_t *vam = &vat_main;
15909
15910   if (VAT_JSON_ARRAY != vam->json_tree.type)
15911     {
15912       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15913       vat_json_init_array (&vam->json_tree);
15914     }
15915
15916   node = vat_json_array_add (&vam->json_tree);
15917   vat_json_init_object (node);
15918
15919   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15920   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15921   vat_json_object_add_uint (node, "transport_protocol",
15922                             mp->transport_protocol);
15923 }
15924
15925 static int
15926 api_sw_interface_span_enable_disable (vat_main_t * vam)
15927 {
15928   unformat_input_t *i = vam->input;
15929   vl_api_sw_interface_span_enable_disable_t *mp;
15930   f64 timeout;
15931   u32 src_sw_if_index = ~0;
15932   u32 dst_sw_if_index = ~0;
15933   u8 state = 3;
15934
15935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15936     {
15937       if (unformat
15938           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
15939         ;
15940       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15941         ;
15942       else
15943         if (unformat
15944             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
15945         ;
15946       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15947         ;
15948       else if (unformat (i, "disable"))
15949         state = 0;
15950       else if (unformat (i, "rx"))
15951         state = 1;
15952       else if (unformat (i, "tx"))
15953         state = 2;
15954       else if (unformat (i, "both"))
15955         state = 3;
15956       else
15957         break;
15958     }
15959
15960   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
15961
15962   mp->sw_if_index_from = htonl (src_sw_if_index);
15963   mp->sw_if_index_to = htonl (dst_sw_if_index);
15964   mp->state = state;
15965
15966   S;
15967   W;
15968   /* NOTREACHED */
15969   return 0;
15970 }
15971
15972 static void
15973 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
15974                                             * mp)
15975 {
15976   vat_main_t *vam = &vat_main;
15977   u8 *sw_if_from_name = 0;
15978   u8 *sw_if_to_name = 0;
15979   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
15980   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
15981   char *states[] = { "none", "rx", "tx", "both" };
15982   hash_pair_t *p;
15983
15984   /* *INDENT-OFF* */
15985   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
15986   ({
15987     if ((u32) p->value[0] == sw_if_index_from)
15988       {
15989         sw_if_from_name = (u8 *)(p->key);
15990         if (sw_if_to_name)
15991           break;
15992       }
15993     if ((u32) p->value[0] == sw_if_index_to)
15994       {
15995         sw_if_to_name = (u8 *)(p->key);
15996         if (sw_if_from_name)
15997           break;
15998       }
15999   }));
16000   /* *INDENT-ON* */
16001   print (vam->ofp, "%20s => %20s (%s)",
16002          sw_if_from_name, sw_if_to_name, states[mp->state]);
16003 }
16004
16005 static void
16006   vl_api_sw_interface_span_details_t_handler_json
16007   (vl_api_sw_interface_span_details_t * mp)
16008 {
16009   vat_main_t *vam = &vat_main;
16010   vat_json_node_t *node = NULL;
16011   u8 *sw_if_from_name = 0;
16012   u8 *sw_if_to_name = 0;
16013   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16014   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16015   hash_pair_t *p;
16016
16017   /* *INDENT-OFF* */
16018   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16019   ({
16020     if ((u32) p->value[0] == sw_if_index_from)
16021       {
16022         sw_if_from_name = (u8 *)(p->key);
16023         if (sw_if_to_name)
16024           break;
16025       }
16026     if ((u32) p->value[0] == sw_if_index_to)
16027       {
16028         sw_if_to_name = (u8 *)(p->key);
16029         if (sw_if_from_name)
16030           break;
16031       }
16032   }));
16033   /* *INDENT-ON* */
16034
16035   if (VAT_JSON_ARRAY != vam->json_tree.type)
16036     {
16037       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16038       vat_json_init_array (&vam->json_tree);
16039     }
16040   node = vat_json_array_add (&vam->json_tree);
16041
16042   vat_json_init_object (node);
16043   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16044   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16045   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16046   vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16047   vat_json_object_add_uint (node, "state", mp->state);
16048 }
16049
16050 static int
16051 api_sw_interface_span_dump (vat_main_t * vam)
16052 {
16053   vl_api_sw_interface_span_dump_t *mp;
16054   f64 timeout;
16055
16056   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
16057   S;
16058
16059   /* Use a control ping for synchronization */
16060   {
16061     vl_api_control_ping_t *mp;
16062     M (CONTROL_PING, control_ping);
16063     S;
16064   }
16065   W;
16066 }
16067
16068 int
16069 api_pg_create_interface (vat_main_t * vam)
16070 {
16071   unformat_input_t *input = vam->input;
16072   vl_api_pg_create_interface_t *mp;
16073   f64 timeout;
16074
16075   u32 if_id = ~0;
16076   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16077     {
16078       if (unformat (input, "if_id %d", &if_id))
16079         ;
16080       else
16081         break;
16082     }
16083   if (if_id == ~0)
16084     {
16085       errmsg ("missing pg interface index");
16086       return -99;
16087     }
16088
16089   /* Construct the API message */
16090   M (PG_CREATE_INTERFACE, pg_create_interface);
16091   mp->context = 0;
16092   mp->interface_id = ntohl (if_id);
16093
16094   S;
16095   W;
16096   /* NOTREACHED */
16097   return 0;
16098 }
16099
16100 int
16101 api_pg_capture (vat_main_t * vam)
16102 {
16103   unformat_input_t *input = vam->input;
16104   vl_api_pg_capture_t *mp;
16105   f64 timeout;
16106
16107   u32 if_id = ~0;
16108   u8 enable = 1;
16109   u32 count = 1;
16110   u8 pcap_file_set = 0;
16111   u8 *pcap_file = 0;
16112   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16113     {
16114       if (unformat (input, "if_id %d", &if_id))
16115         ;
16116       else if (unformat (input, "pcap %s", &pcap_file))
16117         pcap_file_set = 1;
16118       else if (unformat (input, "count %d", &count))
16119         ;
16120       else if (unformat (input, "disable"))
16121         enable = 0;
16122       else
16123         break;
16124     }
16125   if (if_id == ~0)
16126     {
16127       errmsg ("missing pg interface index");
16128       return -99;
16129     }
16130   if (pcap_file_set > 0)
16131     {
16132       if (vec_len (pcap_file) > 255)
16133         {
16134           errmsg ("pcap file name is too long");
16135           return -99;
16136         }
16137     }
16138
16139   u32 name_len = vec_len (pcap_file);
16140   /* Construct the API message */
16141   M (PG_CAPTURE, pg_capture);
16142   mp->context = 0;
16143   mp->interface_id = ntohl (if_id);
16144   mp->is_enabled = enable;
16145   mp->count = ntohl (count);
16146   mp->pcap_name_length = ntohl (name_len);
16147   if (pcap_file_set != 0)
16148     {
16149       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16150     }
16151   vec_free (pcap_file);
16152
16153   S;
16154   W;
16155   /* NOTREACHED */
16156   return 0;
16157 }
16158
16159 int
16160 api_pg_enable_disable (vat_main_t * vam)
16161 {
16162   unformat_input_t *input = vam->input;
16163   vl_api_pg_enable_disable_t *mp;
16164   f64 timeout;
16165
16166   u8 enable = 1;
16167   u8 stream_name_set = 0;
16168   u8 *stream_name = 0;
16169   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16170     {
16171       if (unformat (input, "stream %s", &stream_name))
16172         stream_name_set = 1;
16173       else if (unformat (input, "disable"))
16174         enable = 0;
16175       else
16176         break;
16177     }
16178
16179   if (stream_name_set > 0)
16180     {
16181       if (vec_len (stream_name) > 255)
16182         {
16183           errmsg ("stream name too long");
16184           return -99;
16185         }
16186     }
16187
16188   u32 name_len = vec_len (stream_name);
16189   /* Construct the API message */
16190   M (PG_ENABLE_DISABLE, pg_enable_disable);
16191   mp->context = 0;
16192   mp->is_enabled = enable;
16193   if (stream_name_set != 0)
16194     {
16195       mp->stream_name_length = ntohl (name_len);
16196       clib_memcpy (mp->stream_name, stream_name, name_len);
16197     }
16198   vec_free (stream_name);
16199
16200   S;
16201   W;
16202   /* NOTREACHED */
16203   return 0;
16204 }
16205
16206 int
16207 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16208 {
16209   unformat_input_t *input = vam->input;
16210   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16211   f64 timeout;
16212
16213   u16 *low_ports = 0;
16214   u16 *high_ports = 0;
16215   u16 this_low;
16216   u16 this_hi;
16217   ip4_address_t ip4_addr;
16218   ip6_address_t ip6_addr;
16219   u32 length;
16220   u32 tmp, tmp2;
16221   u8 prefix_set = 0;
16222   u32 vrf_id = ~0;
16223   u8 is_add = 1;
16224   u8 is_ipv6 = 0;
16225
16226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16227     {
16228       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16229         {
16230           prefix_set = 1;
16231         }
16232       else
16233         if (unformat
16234             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16235         {
16236           prefix_set = 1;
16237           is_ipv6 = 1;
16238         }
16239       else if (unformat (input, "vrf %d", &vrf_id))
16240         ;
16241       else if (unformat (input, "del"))
16242         is_add = 0;
16243       else if (unformat (input, "port %d", &tmp))
16244         {
16245           if (tmp == 0 || tmp > 65535)
16246             {
16247               errmsg ("port %d out of range", tmp);
16248               return -99;
16249             }
16250           this_low = tmp;
16251           this_hi = this_low + 1;
16252           vec_add1 (low_ports, this_low);
16253           vec_add1 (high_ports, this_hi);
16254         }
16255       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16256         {
16257           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16258             {
16259               errmsg ("incorrect range parameters");
16260               return -99;
16261             }
16262           this_low = tmp;
16263           /* Note: in debug CLI +1 is added to high before
16264              passing to real fn that does "the work"
16265              (ip_source_and_port_range_check_add_del).
16266              This fn is a wrapper around the binary API fn a
16267              control plane will call, which expects this increment
16268              to have occurred. Hence letting the binary API control
16269              plane fn do the increment for consistency between VAT
16270              and other control planes.
16271            */
16272           this_hi = tmp2;
16273           vec_add1 (low_ports, this_low);
16274           vec_add1 (high_ports, this_hi);
16275         }
16276       else
16277         break;
16278     }
16279
16280   if (prefix_set == 0)
16281     {
16282       errmsg ("<address>/<mask> not specified");
16283       return -99;
16284     }
16285
16286   if (vrf_id == ~0)
16287     {
16288       errmsg ("VRF ID required, not specified");
16289       return -99;
16290     }
16291
16292   if (vrf_id == 0)
16293     {
16294       errmsg
16295         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16296       return -99;
16297     }
16298
16299   if (vec_len (low_ports) == 0)
16300     {
16301       errmsg ("At least one port or port range required");
16302       return -99;
16303     }
16304
16305   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
16306      ip_source_and_port_range_check_add_del);
16307
16308   mp->is_add = is_add;
16309
16310   if (is_ipv6)
16311     {
16312       mp->is_ipv6 = 1;
16313       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16314     }
16315   else
16316     {
16317       mp->is_ipv6 = 0;
16318       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16319     }
16320
16321   mp->mask_length = length;
16322   mp->number_of_ranges = vec_len (low_ports);
16323
16324   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16325   vec_free (low_ports);
16326
16327   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16328   vec_free (high_ports);
16329
16330   mp->vrf_id = ntohl (vrf_id);
16331
16332   S;
16333   W;
16334   /* NOTREACHED */
16335   return 0;
16336 }
16337
16338 int
16339 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16340 {
16341   unformat_input_t *input = vam->input;
16342   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16343   f64 timeout;
16344   u32 sw_if_index = ~0;
16345   int vrf_set = 0;
16346   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16347   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16348   u8 is_add = 1;
16349
16350   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16351     {
16352       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16353         ;
16354       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16355         ;
16356       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16357         vrf_set = 1;
16358       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16359         vrf_set = 1;
16360       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16361         vrf_set = 1;
16362       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16363         vrf_set = 1;
16364       else if (unformat (input, "del"))
16365         is_add = 0;
16366       else
16367         break;
16368     }
16369
16370   if (sw_if_index == ~0)
16371     {
16372       errmsg ("Interface required but not specified");
16373       return -99;
16374     }
16375
16376   if (vrf_set == 0)
16377     {
16378       errmsg ("VRF ID required but not specified");
16379       return -99;
16380     }
16381
16382   if (tcp_out_vrf_id == 0
16383       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16384     {
16385       errmsg
16386         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16387       return -99;
16388     }
16389
16390   /* Construct the API message */
16391   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
16392      ip_source_and_port_range_check_interface_add_del);
16393
16394   mp->sw_if_index = ntohl (sw_if_index);
16395   mp->is_add = is_add;
16396   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16397   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16398   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16399   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16400
16401   /* send it... */
16402   S;
16403
16404   /* Wait for a reply... */
16405   W;
16406 }
16407
16408 static int
16409 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16410 {
16411   unformat_input_t *i = vam->input;
16412   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16413   f64 timeout;
16414   u32 local_sa_id = 0;
16415   u32 remote_sa_id = 0;
16416   ip4_address_t src_address;
16417   ip4_address_t dst_address;
16418   u8 is_add = 1;
16419
16420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16421     {
16422       if (unformat (i, "local_sa %d", &local_sa_id))
16423         ;
16424       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16425         ;
16426       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16427         ;
16428       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16429         ;
16430       else if (unformat (i, "del"))
16431         is_add = 0;
16432       else
16433         {
16434           clib_warning ("parse error '%U'", format_unformat_error, i);
16435           return -99;
16436         }
16437     }
16438
16439   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
16440
16441   mp->local_sa_id = ntohl (local_sa_id);
16442   mp->remote_sa_id = ntohl (remote_sa_id);
16443   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16444   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16445   mp->is_add = is_add;
16446
16447   S;
16448   W;
16449   /* NOTREACHED */
16450   return 0;
16451 }
16452
16453 static int
16454 api_punt (vat_main_t * vam)
16455 {
16456   unformat_input_t *i = vam->input;
16457   vl_api_punt_t *mp;
16458   f64 timeout;
16459   u32 ipv = ~0;
16460   u32 protocol = ~0;
16461   u32 port = ~0;
16462   int is_add = 1;
16463
16464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16465     {
16466       if (unformat (i, "ip %d", &ipv))
16467         ;
16468       else if (unformat (i, "protocol %d", &protocol))
16469         ;
16470       else if (unformat (i, "port %d", &port))
16471         ;
16472       else if (unformat (i, "del"))
16473         is_add = 0;
16474       else
16475         {
16476           clib_warning ("parse error '%U'", format_unformat_error, i);
16477           return -99;
16478         }
16479     }
16480
16481   M (PUNT, punt);
16482
16483   mp->is_add = (u8) is_add;
16484   mp->ipv = (u8) ipv;
16485   mp->l4_protocol = (u8) protocol;
16486   mp->l4_port = htons ((u16) port);
16487
16488   S;
16489   W;
16490   /* NOTREACHED */
16491   return 0;
16492 }
16493
16494 static void vl_api_ipsec_gre_tunnel_details_t_handler
16495   (vl_api_ipsec_gre_tunnel_details_t * mp)
16496 {
16497   vat_main_t *vam = &vat_main;
16498
16499   print (vam->ofp, "%11d%15U%15U%14d%14d",
16500          ntohl (mp->sw_if_index),
16501          format_ip4_address, &mp->src_address,
16502          format_ip4_address, &mp->dst_address,
16503          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16504 }
16505
16506 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16507   (vl_api_ipsec_gre_tunnel_details_t * mp)
16508 {
16509   vat_main_t *vam = &vat_main;
16510   vat_json_node_t *node = NULL;
16511   struct in_addr ip4;
16512
16513   if (VAT_JSON_ARRAY != vam->json_tree.type)
16514     {
16515       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16516       vat_json_init_array (&vam->json_tree);
16517     }
16518   node = vat_json_array_add (&vam->json_tree);
16519
16520   vat_json_init_object (node);
16521   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16522   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16523   vat_json_object_add_ip4 (node, "src_address", ip4);
16524   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16525   vat_json_object_add_ip4 (node, "dst_address", ip4);
16526   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16527   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16528 }
16529
16530 static int
16531 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16532 {
16533   unformat_input_t *i = vam->input;
16534   vl_api_ipsec_gre_tunnel_dump_t *mp;
16535   f64 timeout;
16536   u32 sw_if_index;
16537   u8 sw_if_index_set = 0;
16538
16539   /* Parse args required to build the message */
16540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16541     {
16542       if (unformat (i, "sw_if_index %d", &sw_if_index))
16543         sw_if_index_set = 1;
16544       else
16545         break;
16546     }
16547
16548   if (sw_if_index_set == 0)
16549     {
16550       sw_if_index = ~0;
16551     }
16552
16553   if (!vam->json_output)
16554     {
16555       print (vam->ofp, "%11s%15s%15s%14s%14s",
16556              "sw_if_index", "src_address", "dst_address",
16557              "local_sa_id", "remote_sa_id");
16558     }
16559
16560   /* Get list of gre-tunnel interfaces */
16561   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16562
16563   mp->sw_if_index = htonl (sw_if_index);
16564
16565   S;
16566
16567   /* Use a control ping for synchronization */
16568   {
16569     vl_api_control_ping_t *mp;
16570     M (CONTROL_PING, control_ping);
16571     S;
16572   }
16573   W;
16574 }
16575
16576 static int
16577 api_delete_subif (vat_main_t * vam)
16578 {
16579   unformat_input_t *i = vam->input;
16580   vl_api_delete_subif_t *mp;
16581   f64 timeout;
16582   u32 sw_if_index = ~0;
16583
16584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16585     {
16586       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16587         ;
16588       if (unformat (i, "sw_if_index %d", &sw_if_index))
16589         ;
16590       else
16591         break;
16592     }
16593
16594   if (sw_if_index == ~0)
16595     {
16596       errmsg ("missing sw_if_index");
16597       return -99;
16598     }
16599
16600   /* Construct the API message */
16601   M (DELETE_SUBIF, delete_subif);
16602   mp->sw_if_index = ntohl (sw_if_index);
16603
16604   S;
16605   W;
16606 }
16607
16608 #define foreach_pbb_vtr_op      \
16609 _("disable",  L2_VTR_DISABLED)  \
16610 _("pop",  L2_VTR_POP_2)         \
16611 _("push",  L2_VTR_PUSH_2)
16612
16613 static int
16614 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16615 {
16616   unformat_input_t *i = vam->input;
16617   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16618   f64 timeout;
16619   u32 sw_if_index = ~0, vtr_op = ~0;
16620   u16 outer_tag = ~0;
16621   u8 dmac[6], smac[6];
16622   u8 dmac_set = 0, smac_set = 0;
16623   u16 vlanid = 0;
16624   u32 sid = ~0;
16625   u32 tmp;
16626
16627   /* Shut up coverity */
16628   memset (dmac, 0, sizeof (dmac));
16629   memset (smac, 0, sizeof (smac));
16630
16631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16632     {
16633       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16634         ;
16635       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16636         ;
16637       else if (unformat (i, "vtr_op %d", &vtr_op))
16638         ;
16639 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16640       foreach_pbb_vtr_op
16641 #undef _
16642         else if (unformat (i, "translate_pbb_stag"))
16643         {
16644           if (unformat (i, "%d", &tmp))
16645             {
16646               vtr_op = L2_VTR_TRANSLATE_2_1;
16647               outer_tag = tmp;
16648             }
16649           else
16650             {
16651               errmsg
16652                 ("translate_pbb_stag operation requires outer tag definition");
16653               return -99;
16654             }
16655         }
16656       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16657         dmac_set++;
16658       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16659         smac_set++;
16660       else if (unformat (i, "sid %d", &sid))
16661         ;
16662       else if (unformat (i, "vlanid %d", &tmp))
16663         vlanid = tmp;
16664       else
16665         {
16666           clib_warning ("parse error '%U'", format_unformat_error, i);
16667           return -99;
16668         }
16669     }
16670
16671   if ((sw_if_index == ~0) || (vtr_op == ~0))
16672     {
16673       errmsg ("missing sw_if_index or vtr operation");
16674       return -99;
16675     }
16676   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16677       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16678     {
16679       errmsg
16680         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
16681       return -99;
16682     }
16683
16684   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16685   mp->sw_if_index = ntohl (sw_if_index);
16686   mp->vtr_op = ntohl (vtr_op);
16687   mp->outer_tag = ntohs (outer_tag);
16688   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16689   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16690   mp->b_vlanid = ntohs (vlanid);
16691   mp->i_sid = ntohl (sid);
16692
16693   S;
16694   W;
16695   /* NOTREACHED */
16696   return 0;
16697 }
16698
16699 static int
16700 api_flow_classify_set_interface (vat_main_t * vam)
16701 {
16702   unformat_input_t *i = vam->input;
16703   vl_api_flow_classify_set_interface_t *mp;
16704   f64 timeout;
16705   u32 sw_if_index;
16706   int sw_if_index_set;
16707   u32 ip4_table_index = ~0;
16708   u32 ip6_table_index = ~0;
16709   u8 is_add = 1;
16710
16711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16712     {
16713       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16714         sw_if_index_set = 1;
16715       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16716         sw_if_index_set = 1;
16717       else if (unformat (i, "del"))
16718         is_add = 0;
16719       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16720         ;
16721       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16722         ;
16723       else
16724         {
16725           clib_warning ("parse error '%U'", format_unformat_error, i);
16726           return -99;
16727         }
16728     }
16729
16730   if (sw_if_index_set == 0)
16731     {
16732       errmsg ("missing interface name or sw_if_index");
16733       return -99;
16734     }
16735
16736   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16737
16738   mp->sw_if_index = ntohl (sw_if_index);
16739   mp->ip4_table_index = ntohl (ip4_table_index);
16740   mp->ip6_table_index = ntohl (ip6_table_index);
16741   mp->is_add = is_add;
16742
16743   S;
16744   W;
16745   /* NOTREACHED */
16746   return 0;
16747 }
16748
16749 static int
16750 api_flow_classify_dump (vat_main_t * vam)
16751 {
16752   unformat_input_t *i = vam->input;
16753   vl_api_flow_classify_dump_t *mp;
16754   f64 timeout = ~0;
16755   u8 type = FLOW_CLASSIFY_N_TABLES;
16756
16757   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16758     ;
16759   else
16760     {
16761       errmsg ("classify table type must be specified");
16762       return -99;
16763     }
16764
16765   if (!vam->json_output)
16766     {
16767       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16768     }
16769
16770   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16771   mp->type = type;
16772   /* send it... */
16773   S;
16774
16775   /* Use a control ping for synchronization */
16776   {
16777     vl_api_control_ping_t *mp;
16778     M (CONTROL_PING, control_ping);
16779     S;
16780   }
16781   /* Wait for a reply... */
16782   W;
16783
16784   /* NOTREACHED */
16785   return 0;
16786 }
16787
16788 static int
16789 api_feature_enable_disable (vat_main_t * vam)
16790 {
16791   unformat_input_t *i = vam->input;
16792   vl_api_feature_enable_disable_t *mp;
16793   f64 timeout;
16794   u8 *arc_name = 0;
16795   u8 *feature_name = 0;
16796   u32 sw_if_index = ~0;
16797   u8 enable = 1;
16798
16799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16800     {
16801       if (unformat (i, "arc_name %s", &arc_name))
16802         ;
16803       else if (unformat (i, "feature_name %s", &feature_name))
16804         ;
16805       else
16806         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16807         ;
16808       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16809         ;
16810       else if (unformat (i, "disable"))
16811         enable = 0;
16812       else
16813         break;
16814     }
16815
16816   if (arc_name == 0)
16817     {
16818       errmsg ("missing arc name");
16819       return -99;
16820     }
16821   if (vec_len (arc_name) > 63)
16822     {
16823       errmsg ("arc name too long");
16824     }
16825
16826   if (feature_name == 0)
16827     {
16828       errmsg ("missing feature name");
16829       return -99;
16830     }
16831   if (vec_len (feature_name) > 63)
16832     {
16833       errmsg ("feature name too long");
16834     }
16835
16836   if (sw_if_index == ~0)
16837     {
16838       errmsg ("missing interface name or sw_if_index");
16839       return -99;
16840     }
16841
16842   /* Construct the API message */
16843   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16844   mp->sw_if_index = ntohl (sw_if_index);
16845   mp->enable = enable;
16846   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16847   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16848   vec_free (arc_name);
16849   vec_free (feature_name);
16850
16851   S;
16852   W;
16853 }
16854
16855 static int
16856 api_sw_interface_tag_add_del (vat_main_t * vam)
16857 {
16858   unformat_input_t *i = vam->input;
16859   vl_api_sw_interface_tag_add_del_t *mp;
16860   f64 timeout;
16861   u32 sw_if_index = ~0;
16862   u8 *tag = 0;
16863   u8 enable = 1;
16864
16865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16866     {
16867       if (unformat (i, "tag %s", &tag))
16868         ;
16869       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16870         ;
16871       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16872         ;
16873       else if (unformat (i, "del"))
16874         enable = 0;
16875       else
16876         break;
16877     }
16878
16879   if (sw_if_index == ~0)
16880     {
16881       errmsg ("missing interface name or sw_if_index");
16882       return -99;
16883     }
16884
16885   if (enable && (tag == 0))
16886     {
16887       errmsg ("no tag specified");
16888       return -99;
16889     }
16890
16891   /* Construct the API message */
16892   M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
16893   mp->sw_if_index = ntohl (sw_if_index);
16894   mp->is_add = enable;
16895   if (enable)
16896     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
16897   vec_free (tag);
16898
16899   S;
16900   W;
16901 }
16902
16903 static void vl_api_l2_xconnect_details_t_handler
16904   (vl_api_l2_xconnect_details_t * mp)
16905 {
16906   vat_main_t *vam = &vat_main;
16907
16908   print (vam->ofp, "%15d%15d",
16909          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
16910 }
16911
16912 static void vl_api_l2_xconnect_details_t_handler_json
16913   (vl_api_l2_xconnect_details_t * mp)
16914 {
16915   vat_main_t *vam = &vat_main;
16916   vat_json_node_t *node = NULL;
16917
16918   if (VAT_JSON_ARRAY != vam->json_tree.type)
16919     {
16920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16921       vat_json_init_array (&vam->json_tree);
16922     }
16923   node = vat_json_array_add (&vam->json_tree);
16924
16925   vat_json_init_object (node);
16926   vat_json_object_add_uint (node, "rx_sw_if_index",
16927                             ntohl (mp->rx_sw_if_index));
16928   vat_json_object_add_uint (node, "tx_sw_if_index",
16929                             ntohl (mp->tx_sw_if_index));
16930 }
16931
16932 static int
16933 api_l2_xconnect_dump (vat_main_t * vam)
16934 {
16935   vl_api_l2_xconnect_dump_t *mp;
16936   f64 timeout;
16937
16938   if (!vam->json_output)
16939     {
16940       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
16941     }
16942
16943   M (L2_XCONNECT_DUMP, l2_xconnect_dump);
16944
16945   S;
16946
16947   /* Use a control ping for synchronization */
16948   {
16949     vl_api_control_ping_t *mp;
16950     M (CONTROL_PING, control_ping);
16951     S;
16952   }
16953   W;
16954 }
16955
16956 static int
16957 api_sw_interface_set_mtu (vat_main_t * vam)
16958 {
16959   unformat_input_t *i = vam->input;
16960   vl_api_sw_interface_set_mtu_t *mp;
16961   f64 timeout;
16962   u32 sw_if_index = ~0;
16963   u32 mtu = 0;
16964
16965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16966     {
16967       if (unformat (i, "mtu %d", &mtu))
16968         ;
16969       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16970         ;
16971       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16972         ;
16973       else
16974         break;
16975     }
16976
16977   if (sw_if_index == ~0)
16978     {
16979       errmsg ("missing interface name or sw_if_index");
16980       return -99;
16981     }
16982
16983   if (mtu == 0)
16984     {
16985       errmsg ("no mtu specified");
16986       return -99;
16987     }
16988
16989   /* Construct the API message */
16990   M (SW_INTERFACE_SET_MTU, sw_interface_set_mtu);
16991   mp->sw_if_index = ntohl (sw_if_index);
16992   mp->mtu = ntohs ((u16) mtu);
16993
16994   S;
16995   W;
16996 }
16997
16998
16999 static int
17000 q_or_quit (vat_main_t * vam)
17001 {
17002   longjmp (vam->jump_buf, 1);
17003   return 0;                     /* not so much */
17004 }
17005
17006 static int
17007 q (vat_main_t * vam)
17008 {
17009   return q_or_quit (vam);
17010 }
17011
17012 static int
17013 quit (vat_main_t * vam)
17014 {
17015   return q_or_quit (vam);
17016 }
17017
17018 static int
17019 comment (vat_main_t * vam)
17020 {
17021   return 0;
17022 }
17023
17024 static int
17025 cmd_cmp (void *a1, void *a2)
17026 {
17027   u8 **c1 = a1;
17028   u8 **c2 = a2;
17029
17030   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17031 }
17032
17033 static int
17034 help (vat_main_t * vam)
17035 {
17036   u8 **cmds = 0;
17037   u8 *name = 0;
17038   hash_pair_t *p;
17039   unformat_input_t *i = vam->input;
17040   int j;
17041
17042   if (unformat (i, "%s", &name))
17043     {
17044       uword *hs;
17045
17046       vec_add1 (name, 0);
17047
17048       hs = hash_get_mem (vam->help_by_name, name);
17049       if (hs)
17050         print (vam->ofp, "usage: %s %s", name, hs[0]);
17051       else
17052         print (vam->ofp, "No such msg / command '%s'", name);
17053       vec_free (name);
17054       return 0;
17055     }
17056
17057   print (vam->ofp, "Help is available for the following:");
17058
17059     /* *INDENT-OFF* */
17060     hash_foreach_pair (p, vam->function_by_name,
17061     ({
17062       vec_add1 (cmds, (u8 *)(p->key));
17063     }));
17064     /* *INDENT-ON* */
17065
17066   vec_sort_with_function (cmds, cmd_cmp);
17067
17068   for (j = 0; j < vec_len (cmds); j++)
17069     print (vam->ofp, "%s", cmds[j]);
17070
17071   vec_free (cmds);
17072   return 0;
17073 }
17074
17075 static int
17076 set (vat_main_t * vam)
17077 {
17078   u8 *name = 0, *value = 0;
17079   unformat_input_t *i = vam->input;
17080
17081   if (unformat (i, "%s", &name))
17082     {
17083       /* The input buffer is a vector, not a string. */
17084       value = vec_dup (i->buffer);
17085       vec_delete (value, i->index, 0);
17086       /* Almost certainly has a trailing newline */
17087       if (value[vec_len (value) - 1] == '\n')
17088         value[vec_len (value) - 1] = 0;
17089       /* Make sure it's a proper string, one way or the other */
17090       vec_add1 (value, 0);
17091       (void) clib_macro_set_value (&vam->macro_main,
17092                                    (char *) name, (char *) value);
17093     }
17094   else
17095     errmsg ("usage: set <name> <value>");
17096
17097   vec_free (name);
17098   vec_free (value);
17099   return 0;
17100 }
17101
17102 static int
17103 unset (vat_main_t * vam)
17104 {
17105   u8 *name = 0;
17106
17107   if (unformat (vam->input, "%s", &name))
17108     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17109       errmsg ("unset: %s wasn't set", name);
17110   vec_free (name);
17111   return 0;
17112 }
17113
17114 typedef struct
17115 {
17116   u8 *name;
17117   u8 *value;
17118 } macro_sort_t;
17119
17120
17121 static int
17122 macro_sort_cmp (void *a1, void *a2)
17123 {
17124   macro_sort_t *s1 = a1;
17125   macro_sort_t *s2 = a2;
17126
17127   return strcmp ((char *) (s1->name), (char *) (s2->name));
17128 }
17129
17130 static int
17131 dump_macro_table (vat_main_t * vam)
17132 {
17133   macro_sort_t *sort_me = 0, *sm;
17134   int i;
17135   hash_pair_t *p;
17136
17137     /* *INDENT-OFF* */
17138     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17139     ({
17140       vec_add2 (sort_me, sm, 1);
17141       sm->name = (u8 *)(p->key);
17142       sm->value = (u8 *) (p->value[0]);
17143     }));
17144     /* *INDENT-ON* */
17145
17146   vec_sort_with_function (sort_me, macro_sort_cmp);
17147
17148   if (vec_len (sort_me))
17149     print (vam->ofp, "%-15s%s", "Name", "Value");
17150   else
17151     print (vam->ofp, "The macro table is empty...");
17152
17153   for (i = 0; i < vec_len (sort_me); i++)
17154     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17155   return 0;
17156 }
17157
17158 static int
17159 dump_node_table (vat_main_t * vam)
17160 {
17161   int i, j;
17162   vlib_node_t *node, *next_node;
17163
17164   if (vec_len (vam->graph_nodes) == 0)
17165     {
17166       print (vam->ofp, "Node table empty, issue get_node_graph...");
17167       return 0;
17168     }
17169
17170   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17171     {
17172       node = vam->graph_nodes[i];
17173       print (vam->ofp, "[%d] %s", i, node->name);
17174       for (j = 0; j < vec_len (node->next_nodes); j++)
17175         {
17176           if (node->next_nodes[j] != ~0)
17177             {
17178               next_node = vam->graph_nodes[node->next_nodes[j]];
17179               print (vam->ofp, "  [%d] %s", j, next_node->name);
17180             }
17181         }
17182     }
17183   return 0;
17184 }
17185
17186 static int
17187 value_sort_cmp (void *a1, void *a2)
17188 {
17189   name_sort_t *n1 = a1;
17190   name_sort_t *n2 = a2;
17191
17192   if (n1->value < n2->value)
17193     return -1;
17194   if (n1->value > n2->value)
17195     return 1;
17196   return 0;
17197 }
17198
17199
17200 static int
17201 dump_msg_api_table (vat_main_t * vam)
17202 {
17203   api_main_t *am = &api_main;
17204   name_sort_t *nses = 0, *ns;
17205   hash_pair_t *hp;
17206   int i;
17207
17208   /* *INDENT-OFF* */
17209   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17210   ({
17211     vec_add2 (nses, ns, 1);
17212     ns->name = (u8 *)(hp->key);
17213     ns->value = (u32) hp->value[0];
17214   }));
17215   /* *INDENT-ON* */
17216
17217   vec_sort_with_function (nses, value_sort_cmp);
17218
17219   for (i = 0; i < vec_len (nses); i++)
17220     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17221   vec_free (nses);
17222   return 0;
17223 }
17224
17225 static int
17226 get_msg_id (vat_main_t * vam)
17227 {
17228   u8 *name_and_crc;
17229   u32 message_index;
17230
17231   if (unformat (vam->input, "%s", &name_and_crc))
17232     {
17233       message_index = vl_api_get_msg_index (name_and_crc);
17234       if (message_index == ~0)
17235         {
17236           print (vam->ofp, " '%s' not found", name_and_crc);
17237           return 0;
17238         }
17239       print (vam->ofp, " '%s' has message index %d",
17240              name_and_crc, message_index);
17241       return 0;
17242     }
17243   errmsg ("name_and_crc required...");
17244   return 0;
17245 }
17246
17247 static int
17248 search_node_table (vat_main_t * vam)
17249 {
17250   unformat_input_t *line_input = vam->input;
17251   u8 *node_to_find;
17252   int j;
17253   vlib_node_t *node, *next_node;
17254   uword *p;
17255
17256   if (vam->graph_node_index_by_name == 0)
17257     {
17258       print (vam->ofp, "Node table empty, issue get_node_graph...");
17259       return 0;
17260     }
17261
17262   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17263     {
17264       if (unformat (line_input, "%s", &node_to_find))
17265         {
17266           vec_add1 (node_to_find, 0);
17267           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17268           if (p == 0)
17269             {
17270               print (vam->ofp, "%s not found...", node_to_find);
17271               goto out;
17272             }
17273           node = vam->graph_nodes[p[0]];
17274           print (vam->ofp, "[%d] %s", p[0], node->name);
17275           for (j = 0; j < vec_len (node->next_nodes); j++)
17276             {
17277               if (node->next_nodes[j] != ~0)
17278                 {
17279                   next_node = vam->graph_nodes[node->next_nodes[j]];
17280                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17281                 }
17282             }
17283         }
17284
17285       else
17286         {
17287           clib_warning ("parse error '%U'", format_unformat_error,
17288                         line_input);
17289           return -99;
17290         }
17291
17292     out:
17293       vec_free (node_to_find);
17294
17295     }
17296
17297   return 0;
17298 }
17299
17300
17301 static int
17302 script (vat_main_t * vam)
17303 {
17304 #if (VPP_API_TEST_BUILTIN==0)
17305   u8 *s = 0;
17306   char *save_current_file;
17307   unformat_input_t save_input;
17308   jmp_buf save_jump_buf;
17309   u32 save_line_number;
17310
17311   FILE *new_fp, *save_ifp;
17312
17313   if (unformat (vam->input, "%s", &s))
17314     {
17315       new_fp = fopen ((char *) s, "r");
17316       if (new_fp == 0)
17317         {
17318           errmsg ("Couldn't open script file %s", s);
17319           vec_free (s);
17320           return -99;
17321         }
17322     }
17323   else
17324     {
17325       errmsg ("Missing script name");
17326       return -99;
17327     }
17328
17329   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17330   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17331   save_ifp = vam->ifp;
17332   save_line_number = vam->input_line_number;
17333   save_current_file = (char *) vam->current_file;
17334
17335   vam->input_line_number = 0;
17336   vam->ifp = new_fp;
17337   vam->current_file = s;
17338   do_one_file (vam);
17339
17340   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17341   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17342   vam->ifp = save_ifp;
17343   vam->input_line_number = save_line_number;
17344   vam->current_file = (u8 *) save_current_file;
17345   vec_free (s);
17346
17347   return 0;
17348 #else
17349   clib_warning ("use the exec command...");
17350   return -99;
17351 #endif
17352 }
17353
17354 static int
17355 echo (vat_main_t * vam)
17356 {
17357   print (vam->ofp, "%v", vam->input->buffer);
17358   return 0;
17359 }
17360
17361 /* List of API message constructors, CLI names map to api_xxx */
17362 #define foreach_vpe_api_msg                                             \
17363 _(create_loopback,"[mac <mac-addr>]")                                   \
17364 _(sw_interface_dump,"")                                                 \
17365 _(sw_interface_set_flags,                                               \
17366   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17367 _(sw_interface_add_del_address,                                         \
17368   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17369 _(sw_interface_set_table,                                               \
17370   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17371 _(sw_interface_set_mpls_enable,                                         \
17372   "<intfc> | sw_if_index [disable | dis]")                              \
17373 _(sw_interface_set_vpath,                                               \
17374   "<intfc> | sw_if_index <id> enable | disable")                        \
17375 _(sw_interface_set_vxlan_bypass,                                        \
17376   "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable")            \
17377 _(sw_interface_set_l2_xconnect,                                         \
17378   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17379   "enable | disable")                                                   \
17380 _(sw_interface_set_l2_bridge,                                           \
17381   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
17382   "[shg <split-horizon-group>] [bvi]\n"                                 \
17383   "enable | disable")                                                   \
17384 _(bridge_domain_add_del,                                                \
17385   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
17386 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
17387 _(l2fib_add_del,                                                        \
17388   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17389 _(l2_flags,                                                             \
17390   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
17391 _(bridge_flags,                                                         \
17392   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17393 _(tap_connect,                                                          \
17394   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17395 _(tap_modify,                                                           \
17396   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17397 _(tap_delete,                                                           \
17398   "<vpp-if-name> | sw_if_index <id>")                                   \
17399 _(sw_interface_tap_dump, "")                                            \
17400 _(ip_add_del_route,                                                     \
17401   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17402   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17403   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17404   "[multipath] [count <n>]")                                            \
17405 _(mpls_route_add_del,                                                   \
17406   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17407   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17408   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17409   "[multipath] [count <n>]")                                            \
17410 _(mpls_ip_bind_unbind,                                                  \
17411   "<label> <addr/len>")                                                 \
17412 _(mpls_tunnel_add_del,                                                  \
17413   " via <addr> [table-id <n>]\n"                                        \
17414   "sw_if_index <id>] [l2]  [del]")                                      \
17415 _(proxy_arp_add_del,                                                    \
17416   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17417 _(proxy_arp_intfc_enable_disable,                                       \
17418   "<intfc> | sw_if_index <id> enable | disable")                        \
17419 _(sw_interface_set_unnumbered,                                          \
17420   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17421 _(ip_neighbor_add_del,                                                  \
17422   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17423   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17424 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17425 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17426 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17427   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17428   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17429   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17430 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17431 _(reset_fib, "vrf <n> [ipv6]")                                          \
17432 _(dhcp_proxy_config,                                                    \
17433   "svr <v46-address> src <v46-address>\n"                               \
17434    "insert-cid <n> [del]")                                              \
17435 _(dhcp_proxy_config_2,                                                  \
17436   "svr <v46-address> src <v46-address>\n"                               \
17437    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
17438 _(dhcp_proxy_set_vss,                                                   \
17439   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17440 _(dhcp_client_config,                                                   \
17441   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17442 _(set_ip_flow_hash,                                                     \
17443   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17444 _(sw_interface_ip6_enable_disable,                                      \
17445   "<intfc> | sw_if_index <id> enable | disable")                        \
17446 _(sw_interface_ip6_set_link_local_address,                              \
17447   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17448 _(sw_interface_ip6nd_ra_prefix,                                         \
17449   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17450   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17451   "[nolink] [isno]")                                                    \
17452 _(sw_interface_ip6nd_ra_config,                                         \
17453   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17454   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17455   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17456 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17457 _(l2_patch_add_del,                                                     \
17458   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17459   "enable | disable")                                                   \
17460 _(sr_tunnel_add_del,                                                    \
17461   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
17462   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
17463   "[policy <policy_name>]")                                             \
17464 _(sr_policy_add_del,                                                    \
17465   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
17466 _(sr_multicast_map_add_del,                                             \
17467   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
17468 _(classify_add_del_table,                                               \
17469   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17470   " [del] [del-chain] mask <mask-value>\n"                              \
17471   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17472   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17473 _(classify_add_del_session,                                             \
17474   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17475   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17476   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17477   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17478 _(classify_set_interface_ip_table,                                      \
17479   "<intfc> | sw_if_index <nn> table <nn>")                              \
17480 _(classify_set_interface_l2_tables,                                     \
17481   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17482   "  [other-table <nn>]")                                               \
17483 _(get_node_index, "node <node-name")                                    \
17484 _(add_node_next, "node <node-name> next <next-node-name>")              \
17485 _(l2tpv3_create_tunnel,                                                 \
17486   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17487   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
17488   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17489 _(l2tpv3_set_tunnel_cookies,                                            \
17490   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17491   "[new_remote_cookie <nn>]\n")                                         \
17492 _(l2tpv3_interface_enable_disable,                                      \
17493   "<intfc> | sw_if_index <nn> enable | disable")                        \
17494 _(l2tpv3_set_lookup_key,                                                \
17495   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
17496 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
17497 _(vxlan_add_del_tunnel,                                                 \
17498   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
17499   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
17500   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
17501 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
17502 _(gre_add_del_tunnel,                                                   \
17503   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
17504 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
17505 _(l2_fib_clear_table, "")                                               \
17506 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
17507 _(l2_interface_vlan_tag_rewrite,                                        \
17508   "<intfc> | sw_if_index <nn> \n"                                       \
17509   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
17510   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
17511 _(create_vhost_user_if,                                                 \
17512         "socket <filename> [server] [renumber <dev_instance>] "         \
17513         "[mac <mac_address>]")                                          \
17514 _(modify_vhost_user_if,                                                 \
17515         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
17516         "[server] [renumber <dev_instance>]")                           \
17517 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
17518 _(sw_interface_vhost_user_dump, "")                                     \
17519 _(show_version, "")                                                     \
17520 _(vxlan_gpe_add_del_tunnel,                                             \
17521   "local <addr> remote <addr> vni <nn>\n"                               \
17522     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
17523   "[next-ethernet] [next-nsh]\n")                                       \
17524 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
17525 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
17526 _(interface_name_renumber,                                              \
17527   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
17528 _(input_acl_set_interface,                                              \
17529   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17530   "  [l2-table <nn>] [del]")                                            \
17531 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
17532 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
17533 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
17534 _(ip_dump, "ipv4 | ipv6")                                               \
17535 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
17536 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
17537   "  spid_id <n> ")                                                     \
17538 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
17539   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
17540   "  integ_alg <alg> integ_key <hex>")                                  \
17541 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
17542   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
17543   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
17544   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
17545 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
17546 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
17547 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
17548   "(auth_data 0x<data> | auth_data <data>)")                            \
17549 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
17550   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
17551 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
17552   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
17553   "(local|remote)")                                                     \
17554 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
17555 _(delete_loopback,"sw_if_index <nn>")                                   \
17556 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
17557 _(map_add_domain,                                                       \
17558   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
17559   "ip6-src <ip6addr> "                                                  \
17560   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
17561 _(map_del_domain, "index <n>")                                          \
17562 _(map_add_del_rule,                                                     \
17563   "index <n> psid <n> dst <ip6addr> [del]")                             \
17564 _(map_domain_dump, "")                                                  \
17565 _(map_rule_dump, "index <map-domain>")                                  \
17566 _(want_interface_events,  "enable|disable")                             \
17567 _(want_stats,"enable|disable")                                          \
17568 _(get_first_msg_id, "client <name>")                                    \
17569 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
17570 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
17571   "fib-id <nn> [ip4][ip6][default]")                                    \
17572 _(get_node_graph, " ")                                                  \
17573 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
17574 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
17575 _(ioam_disable, "")                                                     \
17576 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
17577                             " sw_if_index <sw_if_index> p <priority> "  \
17578                             "w <weight>] [del]")                        \
17579 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
17580                         "iface <intf> | sw_if_index <sw_if_index> "     \
17581                         "p <priority> w <weight> [del]")                \
17582 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
17583                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
17584                          "locator-set <locator_name> [del]"             \
17585                          "[key-id sha1|sha256 secret-key <secret-key>]") \
17586 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
17587   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
17588 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
17589 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
17590 _(lisp_gpe_enable_disable, "enable|disable")                            \
17591 _(lisp_enable_disable, "enable|disable")                                \
17592 _(lisp_map_register_enable_disable, "enable|disable")                   \
17593 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
17594 _(lisp_gpe_add_del_iface, "up|down")                                    \
17595 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
17596                                "[seid <seid>] "                         \
17597                                "rloc <locator> p <prio> "               \
17598                                "w <weight> [rloc <loc> ... ] "          \
17599                                "action <action> [del-all]")             \
17600 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
17601                           "<local-eid>")                                \
17602 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
17603 _(lisp_map_request_mode, "src-dst|dst-only")                            \
17604 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
17605 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
17606 _(lisp_locator_set_dump, "[local | remote]")                            \
17607 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
17608 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
17609                        "[local] | [remote]")                            \
17610 _(lisp_eid_table_vni_dump, "")                                          \
17611 _(lisp_eid_table_map_dump, "l2|l3")                                     \
17612 _(lisp_map_resolver_dump, "")                                           \
17613 _(lisp_map_server_dump, "")                                             \
17614 _(lisp_adjacencies_get, "vni <vni>")                                    \
17615 _(show_lisp_rloc_probe_state, "")                                       \
17616 _(show_lisp_map_register_state, "")                                     \
17617 _(show_lisp_status, "")                                                 \
17618 _(lisp_get_map_request_itr_rlocs, "")                                   \
17619 _(show_lisp_pitr, "")                                                   \
17620 _(show_lisp_map_request_mode, "")                                       \
17621 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
17622 _(af_packet_delete, "name <host interface name>")                       \
17623 _(policer_add_del, "name <policer name> <params> [del]")                \
17624 _(policer_dump, "[name <policer name>]")                                \
17625 _(policer_classify_set_interface,                                       \
17626   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17627   "  [l2-table <nn>] [del]")                                            \
17628 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
17629 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
17630     "[master|slave]")                                                   \
17631 _(netmap_delete, "name <interface name>")                               \
17632 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
17633 _(mpls_fib_dump, "")                                                    \
17634 _(classify_table_ids, "")                                               \
17635 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
17636 _(classify_table_info, "table_id <nn>")                                 \
17637 _(classify_session_dump, "table_id <nn>")                               \
17638 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
17639     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
17640     "[template_interval <nn>] [udp_checksum]")                          \
17641 _(ipfix_exporter_dump, "")                                              \
17642 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17643 _(ipfix_classify_stream_dump, "")                                       \
17644 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
17645 _(ipfix_classify_table_dump, "")                                        \
17646 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
17647 _(sw_interface_span_dump, "")                                           \
17648 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
17649 _(pg_create_interface, "if_id <nn>")                                    \
17650 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
17651 _(pg_enable_disable, "[stream <id>] disable")                           \
17652 _(ip_source_and_port_range_check_add_del,                               \
17653   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
17654 _(ip_source_and_port_range_check_interface_add_del,                     \
17655   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
17656   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
17657 _(ipsec_gre_add_del_tunnel,                                             \
17658   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
17659 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
17660 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
17661 _(l2_interface_pbb_tag_rewrite,                                         \
17662   "<intfc> | sw_if_index <nn> \n"                                       \
17663   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
17664   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
17665 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
17666 _(flow_classify_set_interface,                                          \
17667   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17668 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17669 _(ip_fib_dump, "")                                                      \
17670 _(ip6_fib_dump, "")                                                     \
17671 _(feature_enable_disable, "arc_name <arc_name> "                        \
17672   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
17673 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
17674 "[disable]")                                                            \
17675 _(l2_xconnect_dump, "")                                                 \
17676 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
17677 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
17678 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
17679
17680 #if DPDK > 0
17681 #define foreach_vpe_dpdk_api_msg                                        \
17682 _(sw_interface_set_dpdk_hqos_pipe,                                      \
17683   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
17684   "profile <profile-id>\n")                                             \
17685 _(sw_interface_set_dpdk_hqos_subport,                                   \
17686   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
17687   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
17688 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
17689   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")
17690 #endif
17691
17692 /* List of command functions, CLI names map directly to functions */
17693 #define foreach_cli_function                                    \
17694 _(comment, "usage: comment <ignore-rest-of-line>")              \
17695 _(dump_interface_table, "usage: dump_interface_table")          \
17696 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17697 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17698 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17699 _(dump_stats_table, "usage: dump_stats_table")                  \
17700 _(dump_macro_table, "usage: dump_macro_table ")                 \
17701 _(dump_node_table, "usage: dump_node_table")                    \
17702 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17703 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17704 _(echo, "usage: echo <message>")                                \
17705 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17706 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17707 _(help, "usage: help")                                          \
17708 _(q, "usage: quit")                                             \
17709 _(quit, "usage: quit")                                          \
17710 _(search_node_table, "usage: search_node_table <name>...")      \
17711 _(set, "usage: set <variable-name> <value>")                    \
17712 _(script, "usage: script <file-name>")                          \
17713 _(unset, "usage: unset <variable-name>")
17714
17715 #define _(N,n)                                  \
17716     static void vl_api_##n##_t_handler_uni      \
17717     (vl_api_##n##_t * mp)                       \
17718     {                                           \
17719         vat_main_t * vam = &vat_main;           \
17720         if (vam->json_output) {                 \
17721             vl_api_##n##_t_handler_json(mp);    \
17722         } else {                                \
17723             vl_api_##n##_t_handler(mp);         \
17724         }                                       \
17725     }
17726 foreach_vpe_api_reply_msg;
17727 #undef _
17728
17729 #if DPDK > 0
17730 #define _(N,n)                                  \
17731     static void vl_api_##n##_t_handler_uni      \
17732     (vl_api_##n##_t * mp)                       \
17733     {                                           \
17734         vat_main_t * vam = &vat_main;           \
17735         if (vam->json_output) {                 \
17736             vl_api_##n##_t_handler_json(mp);    \
17737         } else {                                \
17738             vl_api_##n##_t_handler(mp);         \
17739         }                                       \
17740     }
17741 foreach_vpe_dpdk_api_reply_msg;
17742 #undef _
17743 #endif
17744
17745 void
17746 vat_api_hookup (vat_main_t * vam)
17747 {
17748 #define _(N,n)                                                  \
17749     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17750                            vl_api_##n##_t_handler_uni,          \
17751                            vl_noop_handler,                     \
17752                            vl_api_##n##_t_endian,               \
17753                            vl_api_##n##_t_print,                \
17754                            sizeof(vl_api_##n##_t), 1);
17755   foreach_vpe_api_reply_msg;
17756 #undef _
17757
17758 #if DPDK > 0
17759 #define _(N,n)                                                  \
17760     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17761                            vl_api_##n##_t_handler_uni,          \
17762                            vl_noop_handler,                     \
17763                            vl_api_##n##_t_endian,               \
17764                            vl_api_##n##_t_print,                \
17765                            sizeof(vl_api_##n##_t), 1);
17766   foreach_vpe_dpdk_api_reply_msg;
17767 #undef _
17768 #endif
17769
17770 #if (VPP_API_TEST_BUILTIN==0)
17771   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17772 #endif
17773
17774   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17775
17776   vam->function_by_name = hash_create_string (0, sizeof (uword));
17777
17778   vam->help_by_name = hash_create_string (0, sizeof (uword));
17779
17780   /* API messages we can send */
17781 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17782   foreach_vpe_api_msg;
17783 #undef _
17784 #if DPDK >0
17785 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17786   foreach_vpe_dpdk_api_msg;
17787 #undef _
17788 #endif
17789
17790   /* Help strings */
17791 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17792   foreach_vpe_api_msg;
17793 #undef _
17794 #if DPDK >0
17795 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17796   foreach_vpe_dpdk_api_msg;
17797 #undef _
17798 #endif
17799
17800   /* CLI functions */
17801 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17802   foreach_cli_function;
17803 #undef _
17804
17805   /* Help strings */
17806 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17807   foreach_cli_function;
17808 #undef _
17809 }
17810
17811 /*
17812  * fd.io coding-style-patch-verification: ON
17813  *
17814  * Local Variables:
17815  * eval: (c-set-style "gnu")
17816  * End:
17817  */