API refactoring : dpdk
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp/api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp/api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 static uword
74 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 void vat_suspend (vlib_main_t * vm, f64 interval);
92
93 #if VPP_API_TEST_BUILTIN == 0
94 /* Parse an IP4 address %d.%d.%d.%d. */
95 uword
96 unformat_ip4_address (unformat_input_t * input, va_list * args)
97 {
98   u8 *result = va_arg (*args, u8 *);
99   unsigned a[4];
100
101   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
102     return 0;
103
104   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
105     return 0;
106
107   result[0] = a[0];
108   result[1] = a[1];
109   result[2] = a[2];
110   result[3] = a[3];
111
112   return 1;
113 }
114
115 uword
116 unformat_ethernet_address (unformat_input_t * input, va_list * args)
117 {
118   u8 *result = va_arg (*args, u8 *);
119   u32 i, a[6];
120
121   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
122                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
123     return 0;
124
125   /* Check range. */
126   for (i = 0; i < 6; i++)
127     if (a[i] >= (1 << 8))
128       return 0;
129
130   for (i = 0; i < 6; i++)
131     result[i] = a[i];
132
133   return 1;
134 }
135
136 /* Returns ethernet type as an int in host byte order. */
137 uword
138 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
139                                         va_list * args)
140 {
141   u16 *result = va_arg (*args, u16 *);
142   int type;
143
144   /* Numeric type. */
145   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
146     {
147       if (type >= (1 << 16))
148         return 0;
149       *result = type;
150       return 1;
151     }
152   return 0;
153 }
154
155 /* Parse an IP6 address. */
156 uword
157 unformat_ip6_address (unformat_input_t * input, va_list * args)
158 {
159   ip6_address_t *result = va_arg (*args, ip6_address_t *);
160   u16 hex_quads[8];
161   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
162   uword c, n_colon, double_colon_index;
163
164   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
165   double_colon_index = ARRAY_LEN (hex_quads);
166   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
167     {
168       hex_digit = 16;
169       if (c >= '0' && c <= '9')
170         hex_digit = c - '0';
171       else if (c >= 'a' && c <= 'f')
172         hex_digit = c + 10 - 'a';
173       else if (c >= 'A' && c <= 'F')
174         hex_digit = c + 10 - 'A';
175       else if (c == ':' && n_colon < 2)
176         n_colon++;
177       else
178         {
179           unformat_put_input (input);
180           break;
181         }
182
183       /* Too many hex quads. */
184       if (n_hex_quads >= ARRAY_LEN (hex_quads))
185         return 0;
186
187       if (hex_digit < 16)
188         {
189           hex_quad = (hex_quad << 4) | hex_digit;
190
191           /* Hex quad must fit in 16 bits. */
192           if (n_hex_digits >= 4)
193             return 0;
194
195           n_colon = 0;
196           n_hex_digits++;
197         }
198
199       /* Save position of :: */
200       if (n_colon == 2)
201         {
202           /* More than one :: ? */
203           if (double_colon_index < ARRAY_LEN (hex_quads))
204             return 0;
205           double_colon_index = n_hex_quads;
206         }
207
208       if (n_colon > 0 && n_hex_digits > 0)
209         {
210           hex_quads[n_hex_quads++] = hex_quad;
211           hex_quad = 0;
212           n_hex_digits = 0;
213         }
214     }
215
216   if (n_hex_digits > 0)
217     hex_quads[n_hex_quads++] = hex_quad;
218
219   {
220     word i;
221
222     /* Expand :: to appropriate number of zero hex quads. */
223     if (double_colon_index < ARRAY_LEN (hex_quads))
224       {
225         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
226
227         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
228           hex_quads[n_zero + i] = hex_quads[i];
229
230         for (i = 0; i < n_zero; i++)
231           hex_quads[double_colon_index + i] = 0;
232
233         n_hex_quads = ARRAY_LEN (hex_quads);
234       }
235
236     /* Too few hex quads given. */
237     if (n_hex_quads < ARRAY_LEN (hex_quads))
238       return 0;
239
240     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
241       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
242
243     return 1;
244   }
245 }
246
247 uword
248 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
249 {
250   u32 *r = va_arg (*args, u32 *);
251
252   if (0);
253 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
254   foreach_ipsec_policy_action
255 #undef _
256     else
257     return 0;
258   return 1;
259 }
260
261 uword
262 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
263 {
264   u32 *r = va_arg (*args, u32 *);
265
266   if (0);
267 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
268   foreach_ipsec_crypto_alg
269 #undef _
270     else
271     return 0;
272   return 1;
273 }
274
275 u8 *
276 format_ipsec_crypto_alg (u8 * s, va_list * args)
277 {
278   u32 i = va_arg (*args, u32);
279   u8 *t = 0;
280
281   switch (i)
282     {
283 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
284       foreach_ipsec_crypto_alg
285 #undef _
286     default:
287       return format (s, "unknown");
288     }
289   return format (s, "%s", t);
290 }
291
292 uword
293 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
294 {
295   u32 *r = va_arg (*args, u32 *);
296
297   if (0);
298 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
299   foreach_ipsec_integ_alg
300 #undef _
301     else
302     return 0;
303   return 1;
304 }
305
306 u8 *
307 format_ipsec_integ_alg (u8 * s, va_list * args)
308 {
309   u32 i = va_arg (*args, u32);
310   u8 *t = 0;
311
312   switch (i)
313     {
314 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
315       foreach_ipsec_integ_alg
316 #undef _
317     default:
318       return format (s, "unknown");
319     }
320   return format (s, "%s", t);
321 }
322
323 uword
324 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
325 {
326   u32 *r = va_arg (*args, u32 *);
327
328   if (0);
329 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
330   foreach_ikev2_auth_method
331 #undef _
332     else
333     return 0;
334   return 1;
335 }
336
337 uword
338 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
339 {
340   u32 *r = va_arg (*args, u32 *);
341
342   if (0);
343 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
344   foreach_ikev2_id_type
345 #undef _
346     else
347     return 0;
348   return 1;
349 }
350 #endif /* VPP_API_TEST_BUILTIN */
351
352 static uword
353 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
354 {
355   u8 *r = va_arg (*args, u8 *);
356
357   if (unformat (input, "kbps"))
358     *r = SSE2_QOS_RATE_KBPS;
359   else if (unformat (input, "pps"))
360     *r = SSE2_QOS_RATE_PPS;
361   else
362     return 0;
363   return 1;
364 }
365
366 static uword
367 unformat_policer_round_type (unformat_input_t * input, va_list * args)
368 {
369   u8 *r = va_arg (*args, u8 *);
370
371   if (unformat (input, "closest"))
372     *r = SSE2_QOS_ROUND_TO_CLOSEST;
373   else if (unformat (input, "up"))
374     *r = SSE2_QOS_ROUND_TO_UP;
375   else if (unformat (input, "down"))
376     *r = SSE2_QOS_ROUND_TO_DOWN;
377   else
378     return 0;
379   return 1;
380 }
381
382 static uword
383 unformat_policer_type (unformat_input_t * input, va_list * args)
384 {
385   u8 *r = va_arg (*args, u8 *);
386
387   if (unformat (input, "1r2c"))
388     *r = SSE2_QOS_POLICER_TYPE_1R2C;
389   else if (unformat (input, "1r3c"))
390     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
391   else if (unformat (input, "2r3c-2698"))
392     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
393   else if (unformat (input, "2r3c-4115"))
394     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
395   else if (unformat (input, "2r3c-mef5cf1"))
396     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
397   else
398     return 0;
399   return 1;
400 }
401
402 static uword
403 unformat_dscp (unformat_input_t * input, va_list * va)
404 {
405   u8 *r = va_arg (*va, u8 *);
406
407   if (0);
408 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
409   foreach_vnet_dscp
410 #undef _
411     else
412     return 0;
413   return 1;
414 }
415
416 static uword
417 unformat_policer_action_type (unformat_input_t * input, va_list * va)
418 {
419   sse2_qos_pol_action_params_st *a
420     = va_arg (*va, sse2_qos_pol_action_params_st *);
421
422   if (unformat (input, "drop"))
423     a->action_type = SSE2_QOS_ACTION_DROP;
424   else if (unformat (input, "transmit"))
425     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
426   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
427     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
428   else
429     return 0;
430   return 1;
431 }
432
433 static uword
434 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
435 {
436   u32 *r = va_arg (*va, u32 *);
437   u32 tid;
438
439   if (unformat (input, "ip4"))
440     tid = POLICER_CLASSIFY_TABLE_IP4;
441   else if (unformat (input, "ip6"))
442     tid = POLICER_CLASSIFY_TABLE_IP6;
443   else if (unformat (input, "l2"))
444     tid = POLICER_CLASSIFY_TABLE_L2;
445   else
446     return 0;
447
448   *r = tid;
449   return 1;
450 }
451
452 static uword
453 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
454 {
455   u32 *r = va_arg (*va, u32 *);
456   u32 tid;
457
458   if (unformat (input, "ip4"))
459     tid = FLOW_CLASSIFY_TABLE_IP4;
460   else if (unformat (input, "ip6"))
461     tid = FLOW_CLASSIFY_TABLE_IP6;
462   else
463     return 0;
464
465   *r = tid;
466   return 1;
467 }
468
469 #if (VPP_API_TEST_BUILTIN==0)
470 u8 *
471 format_ip4_address (u8 * s, va_list * args)
472 {
473   u8 *a = va_arg (*args, u8 *);
474   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
475 }
476
477 u8 *
478 format_ip6_address (u8 * s, va_list * args)
479 {
480   ip6_address_t *a = va_arg (*args, ip6_address_t *);
481   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
482
483   i_max_n_zero = ARRAY_LEN (a->as_u16);
484   max_n_zeros = 0;
485   i_first_zero = i_max_n_zero;
486   n_zeros = 0;
487   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
488     {
489       u32 is_zero = a->as_u16[i] == 0;
490       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
491         {
492           i_first_zero = i;
493           n_zeros = 0;
494         }
495       n_zeros += is_zero;
496       if ((!is_zero && n_zeros > max_n_zeros)
497           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
498         {
499           i_max_n_zero = i_first_zero;
500           max_n_zeros = n_zeros;
501           i_first_zero = ARRAY_LEN (a->as_u16);
502           n_zeros = 0;
503         }
504     }
505
506   last_double_colon = 0;
507   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
508     {
509       if (i == i_max_n_zero && max_n_zeros > 1)
510         {
511           s = format (s, "::");
512           i += max_n_zeros - 1;
513           last_double_colon = 1;
514         }
515       else
516         {
517           s = format (s, "%s%x",
518                       (last_double_colon || i == 0) ? "" : ":",
519                       clib_net_to_host_u16 (a->as_u16[i]));
520           last_double_colon = 0;
521         }
522     }
523
524   return s;
525 }
526
527 /* Format an IP46 address. */
528 u8 *
529 format_ip46_address (u8 * s, va_list * args)
530 {
531   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
532   ip46_type_t type = va_arg (*args, ip46_type_t);
533   int is_ip4 = 1;
534
535   switch (type)
536     {
537     case IP46_TYPE_ANY:
538       is_ip4 = ip46_address_is_ip4 (ip46);
539       break;
540     case IP46_TYPE_IP4:
541       is_ip4 = 1;
542       break;
543     case IP46_TYPE_IP6:
544       is_ip4 = 0;
545       break;
546     }
547
548   return is_ip4 ?
549     format (s, "%U", format_ip4_address, &ip46->ip4) :
550     format (s, "%U", format_ip6_address, &ip46->ip6);
551 }
552
553 u8 *
554 format_ethernet_address (u8 * s, va_list * args)
555 {
556   u8 *a = va_arg (*args, u8 *);
557
558   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
559                  a[0], a[1], a[2], a[3], a[4], a[5]);
560 }
561 #endif
562
563 static void
564 increment_v4_address (ip4_address_t * a)
565 {
566   u32 v;
567
568   v = ntohl (a->as_u32) + 1;
569   a->as_u32 = ntohl (v);
570 }
571
572 static void
573 increment_v6_address (ip6_address_t * a)
574 {
575   u64 v0, v1;
576
577   v0 = clib_net_to_host_u64 (a->as_u64[0]);
578   v1 = clib_net_to_host_u64 (a->as_u64[1]);
579
580   v1 += 1;
581   if (v1 == 0)
582     v0 += 1;
583   a->as_u64[0] = clib_net_to_host_u64 (v0);
584   a->as_u64[1] = clib_net_to_host_u64 (v1);
585 }
586
587 static void
588 increment_mac_address (u64 * mac)
589 {
590   u64 tmp = *mac;
591
592   tmp = clib_net_to_host_u64 (tmp);
593   tmp += 1 << 16;               /* skip unused (least significant) octets */
594   tmp = clib_host_to_net_u64 (tmp);
595   *mac = tmp;
596 }
597
598 static void vl_api_create_loopback_reply_t_handler
599   (vl_api_create_loopback_reply_t * mp)
600 {
601   vat_main_t *vam = &vat_main;
602   i32 retval = ntohl (mp->retval);
603
604   vam->retval = retval;
605   vam->regenerate_interface_table = 1;
606   vam->sw_if_index = ntohl (mp->sw_if_index);
607   vam->result_ready = 1;
608 }
609
610 static void vl_api_create_loopback_reply_t_handler_json
611   (vl_api_create_loopback_reply_t * mp)
612 {
613   vat_main_t *vam = &vat_main;
614   vat_json_node_t node;
615
616   vat_json_init_object (&node);
617   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
618   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
619
620   vat_json_print (vam->ofp, &node);
621   vat_json_free (&node);
622   vam->retval = ntohl (mp->retval);
623   vam->result_ready = 1;
624 }
625
626 static void vl_api_af_packet_create_reply_t_handler
627   (vl_api_af_packet_create_reply_t * mp)
628 {
629   vat_main_t *vam = &vat_main;
630   i32 retval = ntohl (mp->retval);
631
632   vam->retval = retval;
633   vam->regenerate_interface_table = 1;
634   vam->sw_if_index = ntohl (mp->sw_if_index);
635   vam->result_ready = 1;
636 }
637
638 static void vl_api_af_packet_create_reply_t_handler_json
639   (vl_api_af_packet_create_reply_t * mp)
640 {
641   vat_main_t *vam = &vat_main;
642   vat_json_node_t node;
643
644   vat_json_init_object (&node);
645   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
646   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
647
648   vat_json_print (vam->ofp, &node);
649   vat_json_free (&node);
650
651   vam->retval = ntohl (mp->retval);
652   vam->result_ready = 1;
653 }
654
655 static void vl_api_create_vlan_subif_reply_t_handler
656   (vl_api_create_vlan_subif_reply_t * mp)
657 {
658   vat_main_t *vam = &vat_main;
659   i32 retval = ntohl (mp->retval);
660
661   vam->retval = retval;
662   vam->regenerate_interface_table = 1;
663   vam->sw_if_index = ntohl (mp->sw_if_index);
664   vam->result_ready = 1;
665 }
666
667 static void vl_api_create_vlan_subif_reply_t_handler_json
668   (vl_api_create_vlan_subif_reply_t * mp)
669 {
670   vat_main_t *vam = &vat_main;
671   vat_json_node_t node;
672
673   vat_json_init_object (&node);
674   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
675   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
676
677   vat_json_print (vam->ofp, &node);
678   vat_json_free (&node);
679
680   vam->retval = ntohl (mp->retval);
681   vam->result_ready = 1;
682 }
683
684 static void vl_api_create_subif_reply_t_handler
685   (vl_api_create_subif_reply_t * mp)
686 {
687   vat_main_t *vam = &vat_main;
688   i32 retval = ntohl (mp->retval);
689
690   vam->retval = retval;
691   vam->regenerate_interface_table = 1;
692   vam->sw_if_index = ntohl (mp->sw_if_index);
693   vam->result_ready = 1;
694 }
695
696 static void vl_api_create_subif_reply_t_handler_json
697   (vl_api_create_subif_reply_t * mp)
698 {
699   vat_main_t *vam = &vat_main;
700   vat_json_node_t node;
701
702   vat_json_init_object (&node);
703   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
704   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
705
706   vat_json_print (vam->ofp, &node);
707   vat_json_free (&node);
708
709   vam->retval = ntohl (mp->retval);
710   vam->result_ready = 1;
711 }
712
713 static void vl_api_interface_name_renumber_reply_t_handler
714   (vl_api_interface_name_renumber_reply_t * mp)
715 {
716   vat_main_t *vam = &vat_main;
717   i32 retval = ntohl (mp->retval);
718
719   vam->retval = retval;
720   vam->regenerate_interface_table = 1;
721   vam->result_ready = 1;
722 }
723
724 static void vl_api_interface_name_renumber_reply_t_handler_json
725   (vl_api_interface_name_renumber_reply_t * mp)
726 {
727   vat_main_t *vam = &vat_main;
728   vat_json_node_t node;
729
730   vat_json_init_object (&node);
731   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
732
733   vat_json_print (vam->ofp, &node);
734   vat_json_free (&node);
735
736   vam->retval = ntohl (mp->retval);
737   vam->result_ready = 1;
738 }
739
740 /*
741  * Special-case: build the interface table, maintain
742  * the next loopback sw_if_index vbl.
743  */
744 static void vl_api_sw_interface_details_t_handler
745   (vl_api_sw_interface_details_t * mp)
746 {
747   vat_main_t *vam = &vat_main;
748   u8 *s = format (0, "%s%c", mp->interface_name, 0);
749
750   hash_set_mem (vam->sw_if_index_by_interface_name, s,
751                 ntohl (mp->sw_if_index));
752
753   /* In sub interface case, fill the sub interface table entry */
754   if (mp->sw_if_index != mp->sup_sw_if_index)
755     {
756       sw_interface_subif_t *sub = NULL;
757
758       vec_add2 (vam->sw_if_subif_table, sub, 1);
759
760       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
761       strncpy ((char *) sub->interface_name, (char *) s,
762                vec_len (sub->interface_name));
763       sub->sw_if_index = ntohl (mp->sw_if_index);
764       sub->sub_id = ntohl (mp->sub_id);
765
766       sub->sub_dot1ad = mp->sub_dot1ad;
767       sub->sub_number_of_tags = mp->sub_number_of_tags;
768       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
769       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
770       sub->sub_exact_match = mp->sub_exact_match;
771       sub->sub_default = mp->sub_default;
772       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
773       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
774
775       /* vlan tag rewrite */
776       sub->vtr_op = ntohl (mp->vtr_op);
777       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
778       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
779       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
780     }
781 }
782
783 static void vl_api_sw_interface_details_t_handler_json
784   (vl_api_sw_interface_details_t * mp)
785 {
786   vat_main_t *vam = &vat_main;
787   vat_json_node_t *node = NULL;
788
789   if (VAT_JSON_ARRAY != vam->json_tree.type)
790     {
791       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
792       vat_json_init_array (&vam->json_tree);
793     }
794   node = vat_json_array_add (&vam->json_tree);
795
796   vat_json_init_object (node);
797   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
798   vat_json_object_add_uint (node, "sup_sw_if_index",
799                             ntohl (mp->sup_sw_if_index));
800   vat_json_object_add_uint (node, "l2_address_length",
801                             ntohl (mp->l2_address_length));
802   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
803                              sizeof (mp->l2_address));
804   vat_json_object_add_string_copy (node, "interface_name",
805                                    mp->interface_name);
806   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
807   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
808   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
809   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
810   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
811   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
812   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
813   vat_json_object_add_uint (node, "sub_number_of_tags",
814                             mp->sub_number_of_tags);
815   vat_json_object_add_uint (node, "sub_outer_vlan_id",
816                             ntohs (mp->sub_outer_vlan_id));
817   vat_json_object_add_uint (node, "sub_inner_vlan_id",
818                             ntohs (mp->sub_inner_vlan_id));
819   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
820   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
821   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
822                             mp->sub_outer_vlan_id_any);
823   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
824                             mp->sub_inner_vlan_id_any);
825   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
826   vat_json_object_add_uint (node, "vtr_push_dot1q",
827                             ntohl (mp->vtr_push_dot1q));
828   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
829   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
830 }
831
832 static void vl_api_sw_interface_set_flags_t_handler
833   (vl_api_sw_interface_set_flags_t * mp)
834 {
835   vat_main_t *vam = &vat_main;
836   if (vam->interface_event_display)
837     errmsg ("interface flags: sw_if_index %d %s %s",
838             ntohl (mp->sw_if_index),
839             mp->admin_up_down ? "admin-up" : "admin-down",
840             mp->link_up_down ? "link-up" : "link-down");
841 }
842
843 static void vl_api_sw_interface_set_flags_t_handler_json
844   (vl_api_sw_interface_set_flags_t * mp)
845 {
846   /* JSON output not supported */
847 }
848
849 static void
850 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
851 {
852   vat_main_t *vam = &vat_main;
853   i32 retval = ntohl (mp->retval);
854
855   vam->retval = retval;
856   vam->shmem_result = (u8 *) mp->reply_in_shmem;
857   vam->result_ready = 1;
858 }
859
860 static void
861 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
862 {
863   vat_main_t *vam = &vat_main;
864   vat_json_node_t node;
865   api_main_t *am = &api_main;
866   void *oldheap;
867   u8 *reply;
868
869   vat_json_init_object (&node);
870   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
871   vat_json_object_add_uint (&node, "reply_in_shmem",
872                             ntohl (mp->reply_in_shmem));
873   /* Toss the shared-memory original... */
874   pthread_mutex_lock (&am->vlib_rp->mutex);
875   oldheap = svm_push_data_heap (am->vlib_rp);
876
877   reply = (u8 *) (mp->reply_in_shmem);
878   vec_free (reply);
879
880   svm_pop_heap (oldheap);
881   pthread_mutex_unlock (&am->vlib_rp->mutex);
882
883   vat_json_print (vam->ofp, &node);
884   vat_json_free (&node);
885
886   vam->retval = ntohl (mp->retval);
887   vam->result_ready = 1;
888 }
889
890 static void
891 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
892 {
893   vat_main_t *vam = &vat_main;
894   i32 retval = ntohl (mp->retval);
895
896   vam->retval = retval;
897   vam->cmd_reply = mp->reply;
898   vam->result_ready = 1;
899 }
900
901 static void
902 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
903 {
904   vat_main_t *vam = &vat_main;
905   vat_json_node_t node;
906
907   vat_json_init_object (&node);
908   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
909   vat_json_object_add_string_copy (&node, "reply", mp->reply);
910
911   vat_json_print (vam->ofp, &node);
912   vat_json_free (&node);
913
914   vam->retval = ntohl (mp->retval);
915   vam->result_ready = 1;
916 }
917
918 static void vl_api_classify_add_del_table_reply_t_handler
919   (vl_api_classify_add_del_table_reply_t * mp)
920 {
921   vat_main_t *vam = &vat_main;
922   i32 retval = ntohl (mp->retval);
923   if (vam->async_mode)
924     {
925       vam->async_errors += (retval < 0);
926     }
927   else
928     {
929       vam->retval = retval;
930       if (retval == 0 &&
931           ((mp->new_table_index != 0xFFFFFFFF) ||
932            (mp->skip_n_vectors != 0xFFFFFFFF) ||
933            (mp->match_n_vectors != 0xFFFFFFFF)))
934         /*
935          * Note: this is just barely thread-safe, depends on
936          * the main thread spinning waiting for an answer...
937          */
938         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
939                 ntohl (mp->new_table_index),
940                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
941       vam->result_ready = 1;
942     }
943 }
944
945 static void vl_api_classify_add_del_table_reply_t_handler_json
946   (vl_api_classify_add_del_table_reply_t * mp)
947 {
948   vat_main_t *vam = &vat_main;
949   vat_json_node_t node;
950
951   vat_json_init_object (&node);
952   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
953   vat_json_object_add_uint (&node, "new_table_index",
954                             ntohl (mp->new_table_index));
955   vat_json_object_add_uint (&node, "skip_n_vectors",
956                             ntohl (mp->skip_n_vectors));
957   vat_json_object_add_uint (&node, "match_n_vectors",
958                             ntohl (mp->match_n_vectors));
959
960   vat_json_print (vam->ofp, &node);
961   vat_json_free (&node);
962
963   vam->retval = ntohl (mp->retval);
964   vam->result_ready = 1;
965 }
966
967 static void vl_api_get_node_index_reply_t_handler
968   (vl_api_get_node_index_reply_t * mp)
969 {
970   vat_main_t *vam = &vat_main;
971   i32 retval = ntohl (mp->retval);
972   if (vam->async_mode)
973     {
974       vam->async_errors += (retval < 0);
975     }
976   else
977     {
978       vam->retval = retval;
979       if (retval == 0)
980         errmsg ("node index %d", ntohl (mp->node_index));
981       vam->result_ready = 1;
982     }
983 }
984
985 static void vl_api_get_node_index_reply_t_handler_json
986   (vl_api_get_node_index_reply_t * mp)
987 {
988   vat_main_t *vam = &vat_main;
989   vat_json_node_t node;
990
991   vat_json_init_object (&node);
992   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
993   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
994
995   vat_json_print (vam->ofp, &node);
996   vat_json_free (&node);
997
998   vam->retval = ntohl (mp->retval);
999   vam->result_ready = 1;
1000 }
1001
1002 static void vl_api_get_next_index_reply_t_handler
1003   (vl_api_get_next_index_reply_t * mp)
1004 {
1005   vat_main_t *vam = &vat_main;
1006   i32 retval = ntohl (mp->retval);
1007   if (vam->async_mode)
1008     {
1009       vam->async_errors += (retval < 0);
1010     }
1011   else
1012     {
1013       vam->retval = retval;
1014       if (retval == 0)
1015         errmsg ("next node index %d", ntohl (mp->next_index));
1016       vam->result_ready = 1;
1017     }
1018 }
1019
1020 static void vl_api_get_next_index_reply_t_handler_json
1021   (vl_api_get_next_index_reply_t * mp)
1022 {
1023   vat_main_t *vam = &vat_main;
1024   vat_json_node_t node;
1025
1026   vat_json_init_object (&node);
1027   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1028   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1029
1030   vat_json_print (vam->ofp, &node);
1031   vat_json_free (&node);
1032
1033   vam->retval = ntohl (mp->retval);
1034   vam->result_ready = 1;
1035 }
1036
1037 static void vl_api_add_node_next_reply_t_handler
1038   (vl_api_add_node_next_reply_t * mp)
1039 {
1040   vat_main_t *vam = &vat_main;
1041   i32 retval = ntohl (mp->retval);
1042   if (vam->async_mode)
1043     {
1044       vam->async_errors += (retval < 0);
1045     }
1046   else
1047     {
1048       vam->retval = retval;
1049       if (retval == 0)
1050         errmsg ("next index %d", ntohl (mp->next_index));
1051       vam->result_ready = 1;
1052     }
1053 }
1054
1055 static void vl_api_add_node_next_reply_t_handler_json
1056   (vl_api_add_node_next_reply_t * mp)
1057 {
1058   vat_main_t *vam = &vat_main;
1059   vat_json_node_t node;
1060
1061   vat_json_init_object (&node);
1062   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1063   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1064
1065   vat_json_print (vam->ofp, &node);
1066   vat_json_free (&node);
1067
1068   vam->retval = ntohl (mp->retval);
1069   vam->result_ready = 1;
1070 }
1071
1072 static void vl_api_show_version_reply_t_handler
1073   (vl_api_show_version_reply_t * mp)
1074 {
1075   vat_main_t *vam = &vat_main;
1076   i32 retval = ntohl (mp->retval);
1077
1078   if (retval >= 0)
1079     {
1080       errmsg ("        program: %s", mp->program);
1081       errmsg ("        version: %s", mp->version);
1082       errmsg ("     build date: %s", mp->build_date);
1083       errmsg ("build directory: %s", mp->build_directory);
1084     }
1085   vam->retval = retval;
1086   vam->result_ready = 1;
1087 }
1088
1089 static void vl_api_show_version_reply_t_handler_json
1090   (vl_api_show_version_reply_t * mp)
1091 {
1092   vat_main_t *vam = &vat_main;
1093   vat_json_node_t node;
1094
1095   vat_json_init_object (&node);
1096   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1097   vat_json_object_add_string_copy (&node, "program", mp->program);
1098   vat_json_object_add_string_copy (&node, "version", mp->version);
1099   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1100   vat_json_object_add_string_copy (&node, "build_directory",
1101                                    mp->build_directory);
1102
1103   vat_json_print (vam->ofp, &node);
1104   vat_json_free (&node);
1105
1106   vam->retval = ntohl (mp->retval);
1107   vam->result_ready = 1;
1108 }
1109
1110 static void
1111 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1112 {
1113   errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1114           mp->mac_ip ? "mac/ip binding" : "address resolution",
1115           format_ip4_address, &mp->address,
1116           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1117 }
1118
1119 static void
1120 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1121 {
1122   /* JSON output not supported */
1123 }
1124
1125 static void
1126 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1127 {
1128   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1129           mp->mac_ip ? "mac/ip binding" : "address resolution",
1130           format_ip6_address, mp->address,
1131           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1132 }
1133
1134 static void
1135 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1136 {
1137   /* JSON output not supported */
1138 }
1139
1140 /*
1141  * Special-case: build the bridge domain table, maintain
1142  * the next bd id vbl.
1143  */
1144 static void vl_api_bridge_domain_details_t_handler
1145   (vl_api_bridge_domain_details_t * mp)
1146 {
1147   vat_main_t *vam = &vat_main;
1148   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1149
1150   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1151          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1152
1153   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1154          ntohl (mp->bd_id), mp->learn, mp->forward,
1155          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1156
1157   if (n_sw_ifs)
1158     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1159 }
1160
1161 static void vl_api_bridge_domain_details_t_handler_json
1162   (vl_api_bridge_domain_details_t * mp)
1163 {
1164   vat_main_t *vam = &vat_main;
1165   vat_json_node_t *node, *array = NULL;
1166
1167   if (VAT_JSON_ARRAY != vam->json_tree.type)
1168     {
1169       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1170       vat_json_init_array (&vam->json_tree);
1171     }
1172   node = vat_json_array_add (&vam->json_tree);
1173
1174   vat_json_init_object (node);
1175   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1176   vat_json_object_add_uint (node, "flood", mp->flood);
1177   vat_json_object_add_uint (node, "forward", mp->forward);
1178   vat_json_object_add_uint (node, "learn", mp->learn);
1179   vat_json_object_add_uint (node, "bvi_sw_if_index",
1180                             ntohl (mp->bvi_sw_if_index));
1181   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1182   array = vat_json_object_add (node, "sw_if");
1183   vat_json_init_array (array);
1184 }
1185
1186 /*
1187  * Special-case: build the bridge domain sw if table.
1188  */
1189 static void vl_api_bridge_domain_sw_if_details_t_handler
1190   (vl_api_bridge_domain_sw_if_details_t * mp)
1191 {
1192   vat_main_t *vam = &vat_main;
1193   hash_pair_t *p;
1194   u8 *sw_if_name = 0;
1195   u32 sw_if_index;
1196
1197   sw_if_index = ntohl (mp->sw_if_index);
1198   /* *INDENT-OFF* */
1199   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1200   ({
1201     if ((u32) p->value[0] == sw_if_index)
1202       {
1203         sw_if_name = (u8 *)(p->key);
1204         break;
1205       }
1206   }));
1207   /* *INDENT-ON* */
1208
1209   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1210          mp->shg, sw_if_name ? (char *) sw_if_name :
1211          "sw_if_index not found!");
1212 }
1213
1214 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1215   (vl_api_bridge_domain_sw_if_details_t * mp)
1216 {
1217   vat_main_t *vam = &vat_main;
1218   vat_json_node_t *node = NULL;
1219   uword last_index = 0;
1220
1221   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1222   ASSERT (vec_len (vam->json_tree.array) >= 1);
1223   last_index = vec_len (vam->json_tree.array) - 1;
1224   node = &vam->json_tree.array[last_index];
1225   node = vat_json_object_get_element (node, "sw_if");
1226   ASSERT (NULL != node);
1227   node = vat_json_array_add (node);
1228
1229   vat_json_init_object (node);
1230   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1231   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1232   vat_json_object_add_uint (node, "shg", mp->shg);
1233 }
1234
1235 static void vl_api_control_ping_reply_t_handler
1236   (vl_api_control_ping_reply_t * mp)
1237 {
1238   vat_main_t *vam = &vat_main;
1239   i32 retval = ntohl (mp->retval);
1240   if (vam->async_mode)
1241     {
1242       vam->async_errors += (retval < 0);
1243     }
1244   else
1245     {
1246       vam->retval = retval;
1247       vam->result_ready = 1;
1248     }
1249 }
1250
1251 static void vl_api_control_ping_reply_t_handler_json
1252   (vl_api_control_ping_reply_t * mp)
1253 {
1254   vat_main_t *vam = &vat_main;
1255   i32 retval = ntohl (mp->retval);
1256
1257   if (VAT_JSON_NONE != vam->json_tree.type)
1258     {
1259       vat_json_print (vam->ofp, &vam->json_tree);
1260       vat_json_free (&vam->json_tree);
1261       vam->json_tree.type = VAT_JSON_NONE;
1262     }
1263   else
1264     {
1265       /* just print [] */
1266       vat_json_init_array (&vam->json_tree);
1267       vat_json_print (vam->ofp, &vam->json_tree);
1268       vam->json_tree.type = VAT_JSON_NONE;
1269     }
1270
1271   vam->retval = retval;
1272   vam->result_ready = 1;
1273 }
1274
1275 static void
1276 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1277 {
1278   vat_main_t *vam = &vat_main;
1279   i32 retval = ntohl (mp->retval);
1280   if (vam->async_mode)
1281     {
1282       vam->async_errors += (retval < 0);
1283     }
1284   else
1285     {
1286       vam->retval = retval;
1287       vam->result_ready = 1;
1288     }
1289 }
1290
1291 static void vl_api_l2_flags_reply_t_handler_json
1292   (vl_api_l2_flags_reply_t * mp)
1293 {
1294   vat_main_t *vam = &vat_main;
1295   vat_json_node_t node;
1296
1297   vat_json_init_object (&node);
1298   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1299   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1300                             ntohl (mp->resulting_feature_bitmap));
1301
1302   vat_json_print (vam->ofp, &node);
1303   vat_json_free (&node);
1304
1305   vam->retval = ntohl (mp->retval);
1306   vam->result_ready = 1;
1307 }
1308
1309 static void vl_api_bridge_flags_reply_t_handler
1310   (vl_api_bridge_flags_reply_t * mp)
1311 {
1312   vat_main_t *vam = &vat_main;
1313   i32 retval = ntohl (mp->retval);
1314   if (vam->async_mode)
1315     {
1316       vam->async_errors += (retval < 0);
1317     }
1318   else
1319     {
1320       vam->retval = retval;
1321       vam->result_ready = 1;
1322     }
1323 }
1324
1325 static void vl_api_bridge_flags_reply_t_handler_json
1326   (vl_api_bridge_flags_reply_t * mp)
1327 {
1328   vat_main_t *vam = &vat_main;
1329   vat_json_node_t node;
1330
1331   vat_json_init_object (&node);
1332   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1333   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1334                             ntohl (mp->resulting_feature_bitmap));
1335
1336   vat_json_print (vam->ofp, &node);
1337   vat_json_free (&node);
1338
1339   vam->retval = ntohl (mp->retval);
1340   vam->result_ready = 1;
1341 }
1342
1343 static void vl_api_tap_connect_reply_t_handler
1344   (vl_api_tap_connect_reply_t * mp)
1345 {
1346   vat_main_t *vam = &vat_main;
1347   i32 retval = ntohl (mp->retval);
1348   if (vam->async_mode)
1349     {
1350       vam->async_errors += (retval < 0);
1351     }
1352   else
1353     {
1354       vam->retval = retval;
1355       vam->sw_if_index = ntohl (mp->sw_if_index);
1356       vam->result_ready = 1;
1357     }
1358
1359 }
1360
1361 static void vl_api_tap_connect_reply_t_handler_json
1362   (vl_api_tap_connect_reply_t * mp)
1363 {
1364   vat_main_t *vam = &vat_main;
1365   vat_json_node_t node;
1366
1367   vat_json_init_object (&node);
1368   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1369   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1370
1371   vat_json_print (vam->ofp, &node);
1372   vat_json_free (&node);
1373
1374   vam->retval = ntohl (mp->retval);
1375   vam->result_ready = 1;
1376
1377 }
1378
1379 static void
1380 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1381 {
1382   vat_main_t *vam = &vat_main;
1383   i32 retval = ntohl (mp->retval);
1384   if (vam->async_mode)
1385     {
1386       vam->async_errors += (retval < 0);
1387     }
1388   else
1389     {
1390       vam->retval = retval;
1391       vam->sw_if_index = ntohl (mp->sw_if_index);
1392       vam->result_ready = 1;
1393     }
1394 }
1395
1396 static void vl_api_tap_modify_reply_t_handler_json
1397   (vl_api_tap_modify_reply_t * mp)
1398 {
1399   vat_main_t *vam = &vat_main;
1400   vat_json_node_t node;
1401
1402   vat_json_init_object (&node);
1403   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1404   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1405
1406   vat_json_print (vam->ofp, &node);
1407   vat_json_free (&node);
1408
1409   vam->retval = ntohl (mp->retval);
1410   vam->result_ready = 1;
1411 }
1412
1413 static void
1414 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1415 {
1416   vat_main_t *vam = &vat_main;
1417   i32 retval = ntohl (mp->retval);
1418   if (vam->async_mode)
1419     {
1420       vam->async_errors += (retval < 0);
1421     }
1422   else
1423     {
1424       vam->retval = retval;
1425       vam->result_ready = 1;
1426     }
1427 }
1428
1429 static void vl_api_tap_delete_reply_t_handler_json
1430   (vl_api_tap_delete_reply_t * mp)
1431 {
1432   vat_main_t *vam = &vat_main;
1433   vat_json_node_t node;
1434
1435   vat_json_init_object (&node);
1436   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1437
1438   vat_json_print (vam->ofp, &node);
1439   vat_json_free (&node);
1440
1441   vam->retval = ntohl (mp->retval);
1442   vam->result_ready = 1;
1443 }
1444
1445 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1446   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1447 {
1448   vat_main_t *vam = &vat_main;
1449   i32 retval = ntohl (mp->retval);
1450   if (vam->async_mode)
1451     {
1452       vam->async_errors += (retval < 0);
1453     }
1454   else
1455     {
1456       vam->retval = retval;
1457       vam->result_ready = 1;
1458     }
1459 }
1460
1461 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1462   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1463 {
1464   vat_main_t *vam = &vat_main;
1465   vat_json_node_t node;
1466
1467   vat_json_init_object (&node);
1468   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1469   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1470                             ntohl (mp->sw_if_index));
1471
1472   vat_json_print (vam->ofp, &node);
1473   vat_json_free (&node);
1474
1475   vam->retval = ntohl (mp->retval);
1476   vam->result_ready = 1;
1477 }
1478
1479 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1480   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1481 {
1482   vat_main_t *vam = &vat_main;
1483   i32 retval = ntohl (mp->retval);
1484   if (vam->async_mode)
1485     {
1486       vam->async_errors += (retval < 0);
1487     }
1488   else
1489     {
1490       vam->retval = retval;
1491       vam->sw_if_index = ntohl (mp->sw_if_index);
1492       vam->result_ready = 1;
1493     }
1494 }
1495
1496 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1497   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1498 {
1499   vat_main_t *vam = &vat_main;
1500   vat_json_node_t node;
1501
1502   vat_json_init_object (&node);
1503   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1504   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1505
1506   vat_json_print (vam->ofp, &node);
1507   vat_json_free (&node);
1508
1509   vam->retval = ntohl (mp->retval);
1510   vam->result_ready = 1;
1511 }
1512
1513
1514 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1515   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1516 {
1517   vat_main_t *vam = &vat_main;
1518   i32 retval = ntohl (mp->retval);
1519   if (vam->async_mode)
1520     {
1521       vam->async_errors += (retval < 0);
1522     }
1523   else
1524     {
1525       vam->retval = retval;
1526       vam->result_ready = 1;
1527     }
1528 }
1529
1530 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1531   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1532 {
1533   vat_main_t *vam = &vat_main;
1534   vat_json_node_t node;
1535
1536   vat_json_init_object (&node);
1537   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1538   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1539
1540   vat_json_print (vam->ofp, &node);
1541   vat_json_free (&node);
1542
1543   vam->retval = ntohl (mp->retval);
1544   vam->result_ready = 1;
1545 }
1546
1547 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1548   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1549 {
1550   vat_main_t *vam = &vat_main;
1551   i32 retval = ntohl (mp->retval);
1552   if (vam->async_mode)
1553     {
1554       vam->async_errors += (retval < 0);
1555     }
1556   else
1557     {
1558       vam->retval = retval;
1559       vam->sw_if_index = ntohl (mp->sw_if_index);
1560       vam->result_ready = 1;
1561     }
1562 }
1563
1564 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1565   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1566 {
1567   vat_main_t *vam = &vat_main;
1568   vat_json_node_t node;
1569
1570   vat_json_init_object (&node);
1571   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1572   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1573
1574   vat_json_print (vam->ofp, &node);
1575   vat_json_free (&node);
1576
1577   vam->retval = ntohl (mp->retval);
1578   vam->result_ready = 1;
1579 }
1580
1581 static void vl_api_gre_add_del_tunnel_reply_t_handler
1582   (vl_api_gre_add_del_tunnel_reply_t * mp)
1583 {
1584   vat_main_t *vam = &vat_main;
1585   i32 retval = ntohl (mp->retval);
1586   if (vam->async_mode)
1587     {
1588       vam->async_errors += (retval < 0);
1589     }
1590   else
1591     {
1592       vam->retval = retval;
1593       vam->sw_if_index = ntohl (mp->sw_if_index);
1594       vam->result_ready = 1;
1595     }
1596 }
1597
1598 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1599   (vl_api_gre_add_del_tunnel_reply_t * mp)
1600 {
1601   vat_main_t *vam = &vat_main;
1602   vat_json_node_t node;
1603
1604   vat_json_init_object (&node);
1605   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1606   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1607
1608   vat_json_print (vam->ofp, &node);
1609   vat_json_free (&node);
1610
1611   vam->retval = ntohl (mp->retval);
1612   vam->result_ready = 1;
1613 }
1614
1615 static void vl_api_create_vhost_user_if_reply_t_handler
1616   (vl_api_create_vhost_user_if_reply_t * mp)
1617 {
1618   vat_main_t *vam = &vat_main;
1619   i32 retval = ntohl (mp->retval);
1620   if (vam->async_mode)
1621     {
1622       vam->async_errors += (retval < 0);
1623     }
1624   else
1625     {
1626       vam->retval = retval;
1627       vam->sw_if_index = ntohl (mp->sw_if_index);
1628       vam->result_ready = 1;
1629     }
1630 }
1631
1632 static void vl_api_create_vhost_user_if_reply_t_handler_json
1633   (vl_api_create_vhost_user_if_reply_t * mp)
1634 {
1635   vat_main_t *vam = &vat_main;
1636   vat_json_node_t node;
1637
1638   vat_json_init_object (&node);
1639   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1640   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1641
1642   vat_json_print (vam->ofp, &node);
1643   vat_json_free (&node);
1644
1645   vam->retval = ntohl (mp->retval);
1646   vam->result_ready = 1;
1647 }
1648
1649 static void vl_api_ip_address_details_t_handler
1650   (vl_api_ip_address_details_t * mp)
1651 {
1652   vat_main_t *vam = &vat_main;
1653   static ip_address_details_t empty_ip_address_details = { {0} };
1654   ip_address_details_t *address = NULL;
1655   ip_details_t *current_ip_details = NULL;
1656   ip_details_t *details = NULL;
1657
1658   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1659
1660   if (!details || vam->current_sw_if_index >= vec_len (details)
1661       || !details[vam->current_sw_if_index].present)
1662     {
1663       errmsg ("ip address details arrived but not stored");
1664       errmsg ("ip_dump should be called first");
1665       return;
1666     }
1667
1668   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1669
1670 #define addresses (current_ip_details->addr)
1671
1672   vec_validate_init_empty (addresses, vec_len (addresses),
1673                            empty_ip_address_details);
1674
1675   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1676
1677   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1678   address->prefix_length = mp->prefix_length;
1679 #undef addresses
1680 }
1681
1682 static void vl_api_ip_address_details_t_handler_json
1683   (vl_api_ip_address_details_t * mp)
1684 {
1685   vat_main_t *vam = &vat_main;
1686   vat_json_node_t *node = NULL;
1687   struct in6_addr ip6;
1688   struct in_addr ip4;
1689
1690   if (VAT_JSON_ARRAY != vam->json_tree.type)
1691     {
1692       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1693       vat_json_init_array (&vam->json_tree);
1694     }
1695   node = vat_json_array_add (&vam->json_tree);
1696
1697   vat_json_init_object (node);
1698   if (vam->is_ipv6)
1699     {
1700       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1701       vat_json_object_add_ip6 (node, "ip", ip6);
1702     }
1703   else
1704     {
1705       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1706       vat_json_object_add_ip4 (node, "ip", ip4);
1707     }
1708   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1709 }
1710
1711 static void
1712 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1713 {
1714   vat_main_t *vam = &vat_main;
1715   static ip_details_t empty_ip_details = { 0 };
1716   ip_details_t *ip = NULL;
1717   u32 sw_if_index = ~0;
1718
1719   sw_if_index = ntohl (mp->sw_if_index);
1720
1721   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1722                            sw_if_index, empty_ip_details);
1723
1724   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1725                          sw_if_index);
1726
1727   ip->present = 1;
1728 }
1729
1730 static void
1731 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1732 {
1733   vat_main_t *vam = &vat_main;
1734
1735   if (VAT_JSON_ARRAY != vam->json_tree.type)
1736     {
1737       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1738       vat_json_init_array (&vam->json_tree);
1739     }
1740   vat_json_array_add_uint (&vam->json_tree,
1741                            clib_net_to_host_u32 (mp->sw_if_index));
1742 }
1743
1744 static void vl_api_map_domain_details_t_handler_json
1745   (vl_api_map_domain_details_t * mp)
1746 {
1747   vat_json_node_t *node = NULL;
1748   vat_main_t *vam = &vat_main;
1749   struct in6_addr ip6;
1750   struct in_addr ip4;
1751
1752   if (VAT_JSON_ARRAY != vam->json_tree.type)
1753     {
1754       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1755       vat_json_init_array (&vam->json_tree);
1756     }
1757
1758   node = vat_json_array_add (&vam->json_tree);
1759   vat_json_init_object (node);
1760
1761   vat_json_object_add_uint (node, "domain_index",
1762                             clib_net_to_host_u32 (mp->domain_index));
1763   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1764   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1765   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1766   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1767   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1768   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1769   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1770   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1771   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1772   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1773   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1774   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1775   vat_json_object_add_uint (node, "flags", mp->flags);
1776   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1777   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1778 }
1779
1780 static void vl_api_map_domain_details_t_handler
1781   (vl_api_map_domain_details_t * mp)
1782 {
1783   vat_main_t *vam = &vat_main;
1784
1785   if (mp->is_translation)
1786     {
1787       print (vam->ofp,
1788              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1789              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1790              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1791              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1792              clib_net_to_host_u32 (mp->domain_index));
1793     }
1794   else
1795     {
1796       print (vam->ofp,
1797              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1798              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1799              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1800              format_ip6_address, mp->ip6_src,
1801              clib_net_to_host_u32 (mp->domain_index));
1802     }
1803   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1804          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1805          mp->is_translation ? "map-t" : "");
1806 }
1807
1808 static void vl_api_map_rule_details_t_handler_json
1809   (vl_api_map_rule_details_t * mp)
1810 {
1811   struct in6_addr ip6;
1812   vat_json_node_t *node = NULL;
1813   vat_main_t *vam = &vat_main;
1814
1815   if (VAT_JSON_ARRAY != vam->json_tree.type)
1816     {
1817       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1818       vat_json_init_array (&vam->json_tree);
1819     }
1820
1821   node = vat_json_array_add (&vam->json_tree);
1822   vat_json_init_object (node);
1823
1824   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1825   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1826   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1827 }
1828
1829 static void
1830 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1831 {
1832   vat_main_t *vam = &vat_main;
1833   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1834          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1835 }
1836
1837 static void
1838 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1839 {
1840   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1841           "router_addr %U host_mac %U",
1842           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1843           format_ip4_address, &mp->host_address,
1844           format_ip4_address, &mp->router_address,
1845           format_ethernet_address, mp->host_mac);
1846 }
1847
1848 static void vl_api_dhcp_compl_event_t_handler_json
1849   (vl_api_dhcp_compl_event_t * mp)
1850 {
1851   /* JSON output not supported */
1852 }
1853
1854 static void
1855 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1856                               u32 counter)
1857 {
1858   vat_main_t *vam = &vat_main;
1859   static u64 default_counter = 0;
1860
1861   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1862                            NULL);
1863   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1864                            sw_if_index, default_counter);
1865   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1866 }
1867
1868 static void
1869 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1870                                 interface_counter_t counter)
1871 {
1872   vat_main_t *vam = &vat_main;
1873   static interface_counter_t default_counter = { 0, };
1874
1875   vec_validate_init_empty (vam->combined_interface_counters,
1876                            vnet_counter_type, NULL);
1877   vec_validate_init_empty (vam->combined_interface_counters
1878                            [vnet_counter_type], sw_if_index, default_counter);
1879   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1880 }
1881
1882 static void vl_api_vnet_interface_counters_t_handler
1883   (vl_api_vnet_interface_counters_t * mp)
1884 {
1885   /* not supported */
1886 }
1887
1888 static void vl_api_vnet_interface_counters_t_handler_json
1889   (vl_api_vnet_interface_counters_t * mp)
1890 {
1891   interface_counter_t counter;
1892   vlib_counter_t *v;
1893   u64 *v_packets;
1894   u64 packets;
1895   u32 count;
1896   u32 first_sw_if_index;
1897   int i;
1898
1899   count = ntohl (mp->count);
1900   first_sw_if_index = ntohl (mp->first_sw_if_index);
1901
1902   if (!mp->is_combined)
1903     {
1904       v_packets = (u64 *) & mp->data;
1905       for (i = 0; i < count; i++)
1906         {
1907           packets =
1908             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1909           set_simple_interface_counter (mp->vnet_counter_type,
1910                                         first_sw_if_index + i, packets);
1911           v_packets++;
1912         }
1913     }
1914   else
1915     {
1916       v = (vlib_counter_t *) & mp->data;
1917       for (i = 0; i < count; i++)
1918         {
1919           counter.packets =
1920             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1921           counter.bytes =
1922             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1923           set_combined_interface_counter (mp->vnet_counter_type,
1924                                           first_sw_if_index + i, counter);
1925           v++;
1926         }
1927     }
1928 }
1929
1930 static u32
1931 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1932 {
1933   vat_main_t *vam = &vat_main;
1934   u32 i;
1935
1936   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1937     {
1938       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1939         {
1940           return i;
1941         }
1942     }
1943   return ~0;
1944 }
1945
1946 static u32
1947 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1948 {
1949   vat_main_t *vam = &vat_main;
1950   u32 i;
1951
1952   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1953     {
1954       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1955         {
1956           return i;
1957         }
1958     }
1959   return ~0;
1960 }
1961
1962 static void vl_api_vnet_ip4_fib_counters_t_handler
1963   (vl_api_vnet_ip4_fib_counters_t * mp)
1964 {
1965   /* not supported */
1966 }
1967
1968 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1969   (vl_api_vnet_ip4_fib_counters_t * mp)
1970 {
1971   vat_main_t *vam = &vat_main;
1972   vl_api_ip4_fib_counter_t *v;
1973   ip4_fib_counter_t *counter;
1974   struct in_addr ip4;
1975   u32 vrf_id;
1976   u32 vrf_index;
1977   u32 count;
1978   int i;
1979
1980   vrf_id = ntohl (mp->vrf_id);
1981   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
1982   if (~0 == vrf_index)
1983     {
1984       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
1985       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1986       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1987       vec_validate (vam->ip4_fib_counters, vrf_index);
1988       vam->ip4_fib_counters[vrf_index] = NULL;
1989     }
1990
1991   vec_free (vam->ip4_fib_counters[vrf_index]);
1992   v = (vl_api_ip4_fib_counter_t *) & mp->c;
1993   count = ntohl (mp->count);
1994   for (i = 0; i < count; i++)
1995     {
1996       vec_validate (vam->ip4_fib_counters[vrf_index], i);
1997       counter = &vam->ip4_fib_counters[vrf_index][i];
1998       clib_memcpy (&ip4, &v->address, sizeof (ip4));
1999       counter->address = ip4;
2000       counter->address_length = v->address_length;
2001       counter->packets = clib_net_to_host_u64 (v->packets);
2002       counter->bytes = clib_net_to_host_u64 (v->bytes);
2003       v++;
2004     }
2005 }
2006
2007 static void vl_api_vnet_ip6_fib_counters_t_handler
2008   (vl_api_vnet_ip6_fib_counters_t * mp)
2009 {
2010   /* not supported */
2011 }
2012
2013 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2014   (vl_api_vnet_ip6_fib_counters_t * mp)
2015 {
2016   vat_main_t *vam = &vat_main;
2017   vl_api_ip6_fib_counter_t *v;
2018   ip6_fib_counter_t *counter;
2019   struct in6_addr ip6;
2020   u32 vrf_id;
2021   u32 vrf_index;
2022   u32 count;
2023   int i;
2024
2025   vrf_id = ntohl (mp->vrf_id);
2026   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2027   if (~0 == vrf_index)
2028     {
2029       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2030       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2031       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2032       vec_validate (vam->ip6_fib_counters, vrf_index);
2033       vam->ip6_fib_counters[vrf_index] = NULL;
2034     }
2035
2036   vec_free (vam->ip6_fib_counters[vrf_index]);
2037   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2038   count = ntohl (mp->count);
2039   for (i = 0; i < count; i++)
2040     {
2041       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2042       counter = &vam->ip6_fib_counters[vrf_index][i];
2043       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2044       counter->address = ip6;
2045       counter->address_length = v->address_length;
2046       counter->packets = clib_net_to_host_u64 (v->packets);
2047       counter->bytes = clib_net_to_host_u64 (v->bytes);
2048       v++;
2049     }
2050 }
2051
2052 static void vl_api_get_first_msg_id_reply_t_handler
2053   (vl_api_get_first_msg_id_reply_t * mp)
2054 {
2055   vat_main_t *vam = &vat_main;
2056   i32 retval = ntohl (mp->retval);
2057
2058   if (vam->async_mode)
2059     {
2060       vam->async_errors += (retval < 0);
2061     }
2062   else
2063     {
2064       vam->retval = retval;
2065       vam->result_ready = 1;
2066     }
2067   if (retval >= 0)
2068     {
2069       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2070     }
2071 }
2072
2073 static void vl_api_get_first_msg_id_reply_t_handler_json
2074   (vl_api_get_first_msg_id_reply_t * mp)
2075 {
2076   vat_main_t *vam = &vat_main;
2077   vat_json_node_t node;
2078
2079   vat_json_init_object (&node);
2080   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2081   vat_json_object_add_uint (&node, "first_msg_id",
2082                             (uint) ntohs (mp->first_msg_id));
2083
2084   vat_json_print (vam->ofp, &node);
2085   vat_json_free (&node);
2086
2087   vam->retval = ntohl (mp->retval);
2088   vam->result_ready = 1;
2089 }
2090
2091 static void vl_api_get_node_graph_reply_t_handler
2092   (vl_api_get_node_graph_reply_t * mp)
2093 {
2094   vat_main_t *vam = &vat_main;
2095   api_main_t *am = &api_main;
2096   i32 retval = ntohl (mp->retval);
2097   u8 *pvt_copy, *reply;
2098   void *oldheap;
2099   vlib_node_t *node;
2100   int i;
2101
2102   if (vam->async_mode)
2103     {
2104       vam->async_errors += (retval < 0);
2105     }
2106   else
2107     {
2108       vam->retval = retval;
2109       vam->result_ready = 1;
2110     }
2111
2112   /* "Should never happen..." */
2113   if (retval != 0)
2114     return;
2115
2116   reply = (u8 *) (mp->reply_in_shmem);
2117   pvt_copy = vec_dup (reply);
2118
2119   /* Toss the shared-memory original... */
2120   pthread_mutex_lock (&am->vlib_rp->mutex);
2121   oldheap = svm_push_data_heap (am->vlib_rp);
2122
2123   vec_free (reply);
2124
2125   svm_pop_heap (oldheap);
2126   pthread_mutex_unlock (&am->vlib_rp->mutex);
2127
2128   if (vam->graph_nodes)
2129     {
2130       hash_free (vam->graph_node_index_by_name);
2131
2132       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2133         {
2134           node = vam->graph_nodes[i];
2135           vec_free (node->name);
2136           vec_free (node->next_nodes);
2137           vec_free (node);
2138         }
2139       vec_free (vam->graph_nodes);
2140     }
2141
2142   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2143   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2144   vec_free (pvt_copy);
2145
2146   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2147     {
2148       node = vam->graph_nodes[i];
2149       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2150     }
2151 }
2152
2153 static void vl_api_get_node_graph_reply_t_handler_json
2154   (vl_api_get_node_graph_reply_t * mp)
2155 {
2156   vat_main_t *vam = &vat_main;
2157   api_main_t *am = &api_main;
2158   void *oldheap;
2159   vat_json_node_t node;
2160   u8 *reply;
2161
2162   /* $$$$ make this real? */
2163   vat_json_init_object (&node);
2164   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2165   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2166
2167   reply = (u8 *) (mp->reply_in_shmem);
2168
2169   /* Toss the shared-memory original... */
2170   pthread_mutex_lock (&am->vlib_rp->mutex);
2171   oldheap = svm_push_data_heap (am->vlib_rp);
2172
2173   vec_free (reply);
2174
2175   svm_pop_heap (oldheap);
2176   pthread_mutex_unlock (&am->vlib_rp->mutex);
2177
2178   vat_json_print (vam->ofp, &node);
2179   vat_json_free (&node);
2180
2181   vam->retval = ntohl (mp->retval);
2182   vam->result_ready = 1;
2183 }
2184
2185 static void
2186 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2187 {
2188   vat_main_t *vam = &vat_main;
2189   u8 *s = 0;
2190
2191   if (mp->local)
2192     {
2193       s = format (s, "%=16d%=16d%=16d",
2194                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2195     }
2196   else
2197     {
2198       s = format (s, "%=16U%=16d%=16d",
2199                   mp->is_ipv6 ? format_ip6_address :
2200                   format_ip4_address,
2201                   mp->ip_address, mp->priority, mp->weight);
2202     }
2203
2204   print (vam->ofp, "%v", s);
2205   vec_free (s);
2206 }
2207
2208 static void
2209 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2210                                             mp)
2211 {
2212   vat_main_t *vam = &vat_main;
2213   vat_json_node_t *node = NULL;
2214   struct in6_addr ip6;
2215   struct in_addr ip4;
2216
2217   if (VAT_JSON_ARRAY != vam->json_tree.type)
2218     {
2219       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2220       vat_json_init_array (&vam->json_tree);
2221     }
2222   node = vat_json_array_add (&vam->json_tree);
2223   vat_json_init_object (node);
2224
2225   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2226   vat_json_object_add_uint (node, "priority", mp->priority);
2227   vat_json_object_add_uint (node, "weight", mp->weight);
2228
2229   if (mp->local)
2230     vat_json_object_add_uint (node, "sw_if_index",
2231                               clib_net_to_host_u32 (mp->sw_if_index));
2232   else
2233     {
2234       if (mp->is_ipv6)
2235         {
2236           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2237           vat_json_object_add_ip6 (node, "address", ip6);
2238         }
2239       else
2240         {
2241           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2242           vat_json_object_add_ip4 (node, "address", ip4);
2243         }
2244     }
2245 }
2246
2247 static void
2248 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2249                                            mp)
2250 {
2251   vat_main_t *vam = &vat_main;
2252   u8 *ls_name = 0;
2253
2254   ls_name = format (0, "%s", mp->ls_name);
2255
2256   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2257          ls_name);
2258   vec_free (ls_name);
2259 }
2260
2261 static void
2262   vl_api_lisp_locator_set_details_t_handler_json
2263   (vl_api_lisp_locator_set_details_t * mp)
2264 {
2265   vat_main_t *vam = &vat_main;
2266   vat_json_node_t *node = 0;
2267   u8 *ls_name = 0;
2268
2269   ls_name = format (0, "%s", mp->ls_name);
2270   vec_add1 (ls_name, 0);
2271
2272   if (VAT_JSON_ARRAY != vam->json_tree.type)
2273     {
2274       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2275       vat_json_init_array (&vam->json_tree);
2276     }
2277   node = vat_json_array_add (&vam->json_tree);
2278
2279   vat_json_init_object (node);
2280   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2281   vat_json_object_add_uint (node, "ls_index",
2282                             clib_net_to_host_u32 (mp->ls_index));
2283   vec_free (ls_name);
2284 }
2285
2286 static u8 *
2287 format_lisp_flat_eid (u8 * s, va_list * args)
2288 {
2289   u32 type = va_arg (*args, u32);
2290   u8 *eid = va_arg (*args, u8 *);
2291   u32 eid_len = va_arg (*args, u32);
2292
2293   switch (type)
2294     {
2295     case 0:
2296       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2297     case 1:
2298       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2299     case 2:
2300       return format (s, "%U", format_ethernet_address, eid);
2301     }
2302   return 0;
2303 }
2304
2305 static u8 *
2306 format_lisp_eid_vat (u8 * s, va_list * args)
2307 {
2308   u32 type = va_arg (*args, u32);
2309   u8 *eid = va_arg (*args, u8 *);
2310   u32 eid_len = va_arg (*args, u32);
2311   u8 *seid = va_arg (*args, u8 *);
2312   u32 seid_len = va_arg (*args, u32);
2313   u32 is_src_dst = va_arg (*args, u32);
2314
2315   if (is_src_dst)
2316     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2317
2318   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2319
2320   return s;
2321 }
2322
2323 static void
2324 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2325 {
2326   vat_main_t *vam = &vat_main;
2327   u8 *s = 0, *eid = 0;
2328
2329   if (~0 == mp->locator_set_index)
2330     s = format (0, "action: %d", mp->action);
2331   else
2332     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2333
2334   eid = format (0, "%U", format_lisp_eid_vat,
2335                 mp->eid_type,
2336                 mp->eid,
2337                 mp->eid_prefix_len,
2338                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2339   vec_add1 (eid, 0);
2340
2341   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2342          clib_net_to_host_u32 (mp->vni),
2343          eid,
2344          mp->is_local ? "local" : "remote",
2345          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2346          clib_net_to_host_u16 (mp->key_id), mp->key);
2347
2348   vec_free (s);
2349   vec_free (eid);
2350 }
2351
2352 static void
2353 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2354                                               * mp)
2355 {
2356   vat_main_t *vam = &vat_main;
2357   vat_json_node_t *node = 0;
2358   u8 *eid = 0;
2359
2360   if (VAT_JSON_ARRAY != vam->json_tree.type)
2361     {
2362       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2363       vat_json_init_array (&vam->json_tree);
2364     }
2365   node = vat_json_array_add (&vam->json_tree);
2366
2367   vat_json_init_object (node);
2368   if (~0 == mp->locator_set_index)
2369     vat_json_object_add_uint (node, "action", mp->action);
2370   else
2371     vat_json_object_add_uint (node, "locator_set_index",
2372                               clib_net_to_host_u32 (mp->locator_set_index));
2373
2374   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2375   eid = format (0, "%U", format_lisp_eid_vat,
2376                 mp->eid_type,
2377                 mp->eid,
2378                 mp->eid_prefix_len,
2379                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2380   vec_add1 (eid, 0);
2381   vat_json_object_add_string_copy (node, "eid", eid);
2382   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2383   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2384   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2385
2386   if (mp->key_id)
2387     {
2388       vat_json_object_add_uint (node, "key_id",
2389                                 clib_net_to_host_u16 (mp->key_id));
2390       vat_json_object_add_string_copy (node, "key", mp->key);
2391     }
2392   vec_free (eid);
2393 }
2394
2395 static void
2396   vl_api_lisp_eid_table_map_details_t_handler
2397   (vl_api_lisp_eid_table_map_details_t * mp)
2398 {
2399   vat_main_t *vam = &vat_main;
2400
2401   u8 *line = format (0, "%=10d%=10d",
2402                      clib_net_to_host_u32 (mp->vni),
2403                      clib_net_to_host_u32 (mp->dp_table));
2404   print (vam->ofp, "%v", line);
2405   vec_free (line);
2406 }
2407
2408 static void
2409   vl_api_lisp_eid_table_map_details_t_handler_json
2410   (vl_api_lisp_eid_table_map_details_t * mp)
2411 {
2412   vat_main_t *vam = &vat_main;
2413   vat_json_node_t *node = NULL;
2414
2415   if (VAT_JSON_ARRAY != vam->json_tree.type)
2416     {
2417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2418       vat_json_init_array (&vam->json_tree);
2419     }
2420   node = vat_json_array_add (&vam->json_tree);
2421   vat_json_init_object (node);
2422   vat_json_object_add_uint (node, "dp_table",
2423                             clib_net_to_host_u32 (mp->dp_table));
2424   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2425 }
2426
2427 static void
2428   vl_api_lisp_eid_table_vni_details_t_handler
2429   (vl_api_lisp_eid_table_vni_details_t * mp)
2430 {
2431   vat_main_t *vam = &vat_main;
2432
2433   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2434   print (vam->ofp, "%v", line);
2435   vec_free (line);
2436 }
2437
2438 static void
2439   vl_api_lisp_eid_table_vni_details_t_handler_json
2440   (vl_api_lisp_eid_table_vni_details_t * mp)
2441 {
2442   vat_main_t *vam = &vat_main;
2443   vat_json_node_t *node = NULL;
2444
2445   if (VAT_JSON_ARRAY != vam->json_tree.type)
2446     {
2447       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2448       vat_json_init_array (&vam->json_tree);
2449     }
2450   node = vat_json_array_add (&vam->json_tree);
2451   vat_json_init_object (node);
2452   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2453 }
2454
2455 static u8 *
2456 format_decap_next (u8 * s, va_list * args)
2457 {
2458   u32 next_index = va_arg (*args, u32);
2459
2460   switch (next_index)
2461     {
2462     case LISP_GPE_INPUT_NEXT_DROP:
2463       return format (s, "drop");
2464     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2465       return format (s, "ip4");
2466     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2467       return format (s, "ip6");
2468     default:
2469       return format (s, "unknown %d", next_index);
2470     }
2471   return s;
2472 }
2473
2474 static void
2475 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2476                                           mp)
2477 {
2478   vat_main_t *vam = &vat_main;
2479   u8 *iid_str;
2480   u8 *flag_str = NULL;
2481
2482   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2483
2484 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2485   foreach_lisp_gpe_flag_bit;
2486 #undef _
2487
2488   print (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2489          "%=16d%=16d%=16sd=16d%=16s%=16s",
2490          mp->tunnels,
2491          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2492          mp->source_ip,
2493          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2494          mp->destination_ip,
2495          ntohl (mp->encap_fib_id),
2496          ntohl (mp->decap_fib_id),
2497          format_decap_next, ntohl (mp->dcap_next),
2498          mp->ver_res >> 6,
2499          flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2500
2501   vec_free (iid_str);
2502 }
2503
2504 static void
2505   vl_api_lisp_gpe_tunnel_details_t_handler_json
2506   (vl_api_lisp_gpe_tunnel_details_t * mp)
2507 {
2508   vat_main_t *vam = &vat_main;
2509   vat_json_node_t *node = NULL;
2510   struct in6_addr ip6;
2511   struct in_addr ip4;
2512   u8 *next_decap_str;
2513
2514   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2515
2516   if (VAT_JSON_ARRAY != vam->json_tree.type)
2517     {
2518       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2519       vat_json_init_array (&vam->json_tree);
2520     }
2521   node = vat_json_array_add (&vam->json_tree);
2522
2523   vat_json_init_object (node);
2524   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2525   if (mp->is_ipv6)
2526     {
2527       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2528       vat_json_object_add_ip6 (node, "source address", ip6);
2529       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2530       vat_json_object_add_ip6 (node, "destination address", ip6);
2531     }
2532   else
2533     {
2534       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2535       vat_json_object_add_ip4 (node, "source address", ip4);
2536       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2537       vat_json_object_add_ip4 (node, "destination address", ip4);
2538     }
2539   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2540   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2541   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2542   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2543   vat_json_object_add_uint (node, "flags", mp->flags);
2544   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2545   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2546   vat_json_object_add_uint (node, "res", mp->res);
2547   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2548
2549   vec_free (next_decap_str);
2550 }
2551
2552 static void
2553   vl_api_show_lisp_map_register_state_reply_t_handler
2554   (vl_api_show_lisp_map_register_state_reply_t * mp)
2555 {
2556   vat_main_t *vam = &vat_main;
2557   int retval = clib_net_to_host_u32 (mp->retval);
2558
2559   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2560
2561   vam->retval = retval;
2562   vam->result_ready = 1;
2563 }
2564
2565 static void
2566   vl_api_show_lisp_map_register_state_reply_t_handler_json
2567   (vl_api_show_lisp_map_register_state_reply_t * mp)
2568 {
2569   vat_main_t *vam = &vat_main;
2570   vat_json_node_t _node, *node = &_node;
2571   int retval = clib_net_to_host_u32 (mp->retval);
2572
2573   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2574
2575   vat_json_init_object (node);
2576   vat_json_object_add_string_copy (node, "state", s);
2577
2578   vat_json_print (vam->ofp, node);
2579   vat_json_free (node);
2580
2581   vam->retval = retval;
2582   vam->result_ready = 1;
2583   vec_free (s);
2584 }
2585
2586 static void
2587   vl_api_show_lisp_rloc_probe_state_reply_t_handler
2588   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2589 {
2590   vat_main_t *vam = &vat_main;
2591   int retval = clib_net_to_host_u32 (mp->retval);
2592
2593   if (retval)
2594     goto end;
2595
2596   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2597 end:
2598   vam->retval = retval;
2599   vam->result_ready = 1;
2600 }
2601
2602 static void
2603   vl_api_show_lisp_rloc_probe_state_reply_t_handler_json
2604   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2605 {
2606   vat_main_t *vam = &vat_main;
2607   vat_json_node_t _node, *node = &_node;
2608   int retval = clib_net_to_host_u32 (mp->retval);
2609
2610   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2611   vat_json_init_object (node);
2612   vat_json_object_add_string_copy (node, "state", s);
2613
2614   vat_json_print (vam->ofp, node);
2615   vat_json_free (node);
2616
2617   vam->retval = retval;
2618   vam->result_ready = 1;
2619   vec_free (s);
2620 }
2621
2622 static void
2623   vl_api_lisp_adjacencies_get_reply_t_handler
2624   (vl_api_lisp_adjacencies_get_reply_t * mp)
2625 {
2626   vat_main_t *vam = &vat_main;
2627   u32 i, n;
2628   int retval = clib_net_to_host_u32 (mp->retval);
2629   vl_api_lisp_adjacency_t *a;
2630
2631   if (retval)
2632     goto end;
2633
2634   n = clib_net_to_host_u32 (mp->count);
2635
2636   for (i = 0; i < n; i++)
2637     {
2638       a = &mp->adjacencies[i];
2639       print (vam->ofp, "%U %40U",
2640              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2641              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2642     }
2643
2644 end:
2645   vam->retval = retval;
2646   vam->result_ready = 1;
2647 }
2648
2649 static void
2650   vl_api_lisp_adjacencies_get_reply_t_handler_json
2651   (vl_api_lisp_adjacencies_get_reply_t * mp)
2652 {
2653   u8 *s = 0;
2654   vat_main_t *vam = &vat_main;
2655   vat_json_node_t *e = 0, root;
2656   u32 i, n;
2657   int retval = clib_net_to_host_u32 (mp->retval);
2658   vl_api_lisp_adjacency_t *a;
2659
2660   if (retval)
2661     goto end;
2662
2663   n = clib_net_to_host_u32 (mp->count);
2664   vat_json_init_array (&root);
2665
2666   for (i = 0; i < n; i++)
2667     {
2668       e = vat_json_array_add (&root);
2669       a = &mp->adjacencies[i];
2670
2671       vat_json_init_object (e);
2672       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2673                   a->leid_prefix_len);
2674       vec_add1 (s, 0);
2675       vat_json_object_add_string_copy (e, "leid", s);
2676       vec_free (s);
2677
2678       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2679                   a->reid_prefix_len);
2680       vec_add1 (s, 0);
2681       vat_json_object_add_string_copy (e, "reid", s);
2682       vec_free (s);
2683     }
2684
2685   vat_json_print (vam->ofp, &root);
2686   vat_json_free (&root);
2687
2688 end:
2689   vam->retval = retval;
2690   vam->result_ready = 1;
2691 }
2692
2693 static void
2694 vl_api_lisp_map_server_details_t_handler (vl_api_lisp_map_server_details_t
2695                                           * mp)
2696 {
2697   vat_main_t *vam = &vat_main;
2698
2699   print (vam->ofp, "%=20U",
2700          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2701          mp->ip_address);
2702 }
2703
2704 static void
2705   vl_api_lisp_map_server_details_t_handler_json
2706   (vl_api_lisp_map_server_details_t * mp)
2707 {
2708   vat_main_t *vam = &vat_main;
2709   vat_json_node_t *node = NULL;
2710   struct in6_addr ip6;
2711   struct in_addr ip4;
2712
2713   if (VAT_JSON_ARRAY != vam->json_tree.type)
2714     {
2715       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2716       vat_json_init_array (&vam->json_tree);
2717     }
2718   node = vat_json_array_add (&vam->json_tree);
2719
2720   vat_json_init_object (node);
2721   if (mp->is_ipv6)
2722     {
2723       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2724       vat_json_object_add_ip6 (node, "map-server", ip6);
2725     }
2726   else
2727     {
2728       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2729       vat_json_object_add_ip4 (node, "map-server", ip4);
2730     }
2731 }
2732
2733 static void
2734 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2735                                             * mp)
2736 {
2737   vat_main_t *vam = &vat_main;
2738
2739   print (vam->ofp, "%=20U",
2740          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2741          mp->ip_address);
2742 }
2743
2744 static void
2745   vl_api_lisp_map_resolver_details_t_handler_json
2746   (vl_api_lisp_map_resolver_details_t * mp)
2747 {
2748   vat_main_t *vam = &vat_main;
2749   vat_json_node_t *node = NULL;
2750   struct in6_addr ip6;
2751   struct in_addr ip4;
2752
2753   if (VAT_JSON_ARRAY != vam->json_tree.type)
2754     {
2755       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2756       vat_json_init_array (&vam->json_tree);
2757     }
2758   node = vat_json_array_add (&vam->json_tree);
2759
2760   vat_json_init_object (node);
2761   if (mp->is_ipv6)
2762     {
2763       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2764       vat_json_object_add_ip6 (node, "map resolver", ip6);
2765     }
2766   else
2767     {
2768       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2769       vat_json_object_add_ip4 (node, "map resolver", ip4);
2770     }
2771 }
2772
2773 static void
2774   vl_api_show_lisp_status_reply_t_handler
2775   (vl_api_show_lisp_status_reply_t * mp)
2776 {
2777   vat_main_t *vam = &vat_main;
2778   i32 retval = ntohl (mp->retval);
2779
2780   if (0 <= retval)
2781     {
2782       print (vam->ofp, "feature: %s\ngpe: %s",
2783              mp->feature_status ? "enabled" : "disabled",
2784              mp->gpe_status ? "enabled" : "disabled");
2785     }
2786
2787   vam->retval = retval;
2788   vam->result_ready = 1;
2789 }
2790
2791 static void
2792   vl_api_show_lisp_status_reply_t_handler_json
2793   (vl_api_show_lisp_status_reply_t * mp)
2794 {
2795   vat_main_t *vam = &vat_main;
2796   vat_json_node_t node;
2797   u8 *gpe_status = NULL;
2798   u8 *feature_status = NULL;
2799
2800   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2801   feature_status = format (0, "%s",
2802                            mp->feature_status ? "enabled" : "disabled");
2803   vec_add1 (gpe_status, 0);
2804   vec_add1 (feature_status, 0);
2805
2806   vat_json_init_object (&node);
2807   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2808   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2809
2810   vec_free (gpe_status);
2811   vec_free (feature_status);
2812
2813   vat_json_print (vam->ofp, &node);
2814   vat_json_free (&node);
2815
2816   vam->retval = ntohl (mp->retval);
2817   vam->result_ready = 1;
2818 }
2819
2820 static void
2821   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2822   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2823 {
2824   vat_main_t *vam = &vat_main;
2825   i32 retval = ntohl (mp->retval);
2826
2827   if (retval >= 0)
2828     {
2829       print (vam->ofp, "%=20s", mp->locator_set_name);
2830     }
2831
2832   vam->retval = retval;
2833   vam->result_ready = 1;
2834 }
2835
2836 static void
2837   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2838   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2839 {
2840   vat_main_t *vam = &vat_main;
2841   vat_json_node_t *node = NULL;
2842
2843   if (VAT_JSON_ARRAY != vam->json_tree.type)
2844     {
2845       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2846       vat_json_init_array (&vam->json_tree);
2847     }
2848   node = vat_json_array_add (&vam->json_tree);
2849
2850   vat_json_init_object (node);
2851   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2852
2853   vat_json_print (vam->ofp, node);
2854   vat_json_free (node);
2855
2856   vam->retval = ntohl (mp->retval);
2857   vam->result_ready = 1;
2858 }
2859
2860 static u8 *
2861 format_lisp_map_request_mode (u8 * s, va_list * args)
2862 {
2863   u32 mode = va_arg (*args, u32);
2864
2865   switch (mode)
2866     {
2867     case 0:
2868       return format (0, "dst-only");
2869     case 1:
2870       return format (0, "src-dst");
2871     }
2872   return 0;
2873 }
2874
2875 static void
2876   vl_api_show_lisp_map_request_mode_reply_t_handler
2877   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2878 {
2879   vat_main_t *vam = &vat_main;
2880   i32 retval = ntohl (mp->retval);
2881
2882   if (0 <= retval)
2883     {
2884       u32 mode = mp->mode;
2885       print (vam->ofp, "map_request_mode: %U",
2886              format_lisp_map_request_mode, mode);
2887     }
2888
2889   vam->retval = retval;
2890   vam->result_ready = 1;
2891 }
2892
2893 static void
2894   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2895   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2896 {
2897   vat_main_t *vam = &vat_main;
2898   vat_json_node_t node;
2899   u8 *s = 0;
2900   u32 mode;
2901
2902   mode = mp->mode;
2903   s = format (0, "%U", format_lisp_map_request_mode, mode);
2904   vec_add1 (s, 0);
2905
2906   vat_json_init_object (&node);
2907   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2908   vat_json_print (vam->ofp, &node);
2909   vat_json_free (&node);
2910
2911   vec_free (s);
2912   vam->retval = ntohl (mp->retval);
2913   vam->result_ready = 1;
2914 }
2915
2916 static void
2917 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2918 {
2919   vat_main_t *vam = &vat_main;
2920   i32 retval = ntohl (mp->retval);
2921
2922   if (0 <= retval)
2923     {
2924       print (vam->ofp, "%-20s%-16s",
2925              mp->status ? "enabled" : "disabled",
2926              mp->status ? (char *) mp->locator_set_name : "");
2927     }
2928
2929   vam->retval = retval;
2930   vam->result_ready = 1;
2931 }
2932
2933 static void
2934 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2935                                             mp)
2936 {
2937   vat_main_t *vam = &vat_main;
2938   vat_json_node_t node;
2939   u8 *status = 0;
2940
2941   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2942   vec_add1 (status, 0);
2943
2944   vat_json_init_object (&node);
2945   vat_json_object_add_string_copy (&node, "status", status);
2946   if (mp->status)
2947     {
2948       vat_json_object_add_string_copy (&node, "locator_set",
2949                                        mp->locator_set_name);
2950     }
2951
2952   vec_free (status);
2953
2954   vat_json_print (vam->ofp, &node);
2955   vat_json_free (&node);
2956
2957   vam->retval = ntohl (mp->retval);
2958   vam->result_ready = 1;
2959 }
2960
2961 static u8 *
2962 format_policer_type (u8 * s, va_list * va)
2963 {
2964   u32 i = va_arg (*va, u32);
2965
2966   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2967     s = format (s, "1r2c");
2968   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2969     s = format (s, "1r3c");
2970   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2971     s = format (s, "2r3c-2698");
2972   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2973     s = format (s, "2r3c-4115");
2974   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2975     s = format (s, "2r3c-mef5cf1");
2976   else
2977     s = format (s, "ILLEGAL");
2978   return s;
2979 }
2980
2981 static u8 *
2982 format_policer_rate_type (u8 * s, va_list * va)
2983 {
2984   u32 i = va_arg (*va, u32);
2985
2986   if (i == SSE2_QOS_RATE_KBPS)
2987     s = format (s, "kbps");
2988   else if (i == SSE2_QOS_RATE_PPS)
2989     s = format (s, "pps");
2990   else
2991     s = format (s, "ILLEGAL");
2992   return s;
2993 }
2994
2995 static u8 *
2996 format_policer_round_type (u8 * s, va_list * va)
2997 {
2998   u32 i = va_arg (*va, u32);
2999
3000   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3001     s = format (s, "closest");
3002   else if (i == SSE2_QOS_ROUND_TO_UP)
3003     s = format (s, "up");
3004   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3005     s = format (s, "down");
3006   else
3007     s = format (s, "ILLEGAL");
3008   return s;
3009 }
3010
3011 static u8 *
3012 format_policer_action_type (u8 * s, va_list * va)
3013 {
3014   u32 i = va_arg (*va, u32);
3015
3016   if (i == SSE2_QOS_ACTION_DROP)
3017     s = format (s, "drop");
3018   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3019     s = format (s, "transmit");
3020   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3021     s = format (s, "mark-and-transmit");
3022   else
3023     s = format (s, "ILLEGAL");
3024   return s;
3025 }
3026
3027 static u8 *
3028 format_dscp (u8 * s, va_list * va)
3029 {
3030   u32 i = va_arg (*va, u32);
3031   char *t = 0;
3032
3033   switch (i)
3034     {
3035 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3036       foreach_vnet_dscp
3037 #undef _
3038     default:
3039       return format (s, "ILLEGAL");
3040     }
3041   s = format (s, "%s", t);
3042   return s;
3043 }
3044
3045 static void
3046 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3047 {
3048   vat_main_t *vam = &vat_main;
3049   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3050
3051   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3052     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3053   else
3054     conform_dscp_str = format (0, "");
3055
3056   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3057     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3058   else
3059     exceed_dscp_str = format (0, "");
3060
3061   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3062     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3063   else
3064     violate_dscp_str = format (0, "");
3065
3066   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3067          "rate type %U, round type %U, %s rate, %s color-aware, "
3068          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3069          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3070          "conform action %U%s, exceed action %U%s, violate action %U%s",
3071          mp->name,
3072          format_policer_type, mp->type,
3073          ntohl (mp->cir),
3074          ntohl (mp->eir),
3075          clib_net_to_host_u64 (mp->cb),
3076          clib_net_to_host_u64 (mp->eb),
3077          format_policer_rate_type, mp->rate_type,
3078          format_policer_round_type, mp->round_type,
3079          mp->single_rate ? "single" : "dual",
3080          mp->color_aware ? "is" : "not",
3081          ntohl (mp->cir_tokens_per_period),
3082          ntohl (mp->pir_tokens_per_period),
3083          ntohl (mp->scale),
3084          ntohl (mp->current_limit),
3085          ntohl (mp->current_bucket),
3086          ntohl (mp->extended_limit),
3087          ntohl (mp->extended_bucket),
3088          clib_net_to_host_u64 (mp->last_update_time),
3089          format_policer_action_type, mp->conform_action_type,
3090          conform_dscp_str,
3091          format_policer_action_type, mp->exceed_action_type,
3092          exceed_dscp_str,
3093          format_policer_action_type, mp->violate_action_type,
3094          violate_dscp_str);
3095
3096   vec_free (conform_dscp_str);
3097   vec_free (exceed_dscp_str);
3098   vec_free (violate_dscp_str);
3099 }
3100
3101 static void vl_api_policer_details_t_handler_json
3102   (vl_api_policer_details_t * mp)
3103 {
3104   vat_main_t *vam = &vat_main;
3105   vat_json_node_t *node;
3106   u8 *rate_type_str, *round_type_str, *type_str;
3107   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3108
3109   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3110   round_type_str =
3111     format (0, "%U", format_policer_round_type, mp->round_type);
3112   type_str = format (0, "%U", format_policer_type, mp->type);
3113   conform_action_str = format (0, "%U", format_policer_action_type,
3114                                mp->conform_action_type);
3115   exceed_action_str = format (0, "%U", format_policer_action_type,
3116                               mp->exceed_action_type);
3117   violate_action_str = format (0, "%U", format_policer_action_type,
3118                                mp->violate_action_type);
3119
3120   if (VAT_JSON_ARRAY != vam->json_tree.type)
3121     {
3122       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3123       vat_json_init_array (&vam->json_tree);
3124     }
3125   node = vat_json_array_add (&vam->json_tree);
3126
3127   vat_json_init_object (node);
3128   vat_json_object_add_string_copy (node, "name", mp->name);
3129   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3130   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3131   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3132   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3133   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3134   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3135   vat_json_object_add_string_copy (node, "type", type_str);
3136   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3137   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3138   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3139   vat_json_object_add_uint (node, "cir_tokens_per_period",
3140                             ntohl (mp->cir_tokens_per_period));
3141   vat_json_object_add_uint (node, "eir_tokens_per_period",
3142                             ntohl (mp->pir_tokens_per_period));
3143   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3144   vat_json_object_add_uint (node, "current_bucket",
3145                             ntohl (mp->current_bucket));
3146   vat_json_object_add_uint (node, "extended_limit",
3147                             ntohl (mp->extended_limit));
3148   vat_json_object_add_uint (node, "extended_bucket",
3149                             ntohl (mp->extended_bucket));
3150   vat_json_object_add_uint (node, "last_update_time",
3151                             ntohl (mp->last_update_time));
3152   vat_json_object_add_string_copy (node, "conform_action",
3153                                    conform_action_str);
3154   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3155     {
3156       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3157       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3158       vec_free (dscp_str);
3159     }
3160   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3161   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3162     {
3163       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3164       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3165       vec_free (dscp_str);
3166     }
3167   vat_json_object_add_string_copy (node, "violate_action",
3168                                    violate_action_str);
3169   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3170     {
3171       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3172       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3173       vec_free (dscp_str);
3174     }
3175
3176   vec_free (rate_type_str);
3177   vec_free (round_type_str);
3178   vec_free (type_str);
3179   vec_free (conform_action_str);
3180   vec_free (exceed_action_str);
3181   vec_free (violate_action_str);
3182 }
3183
3184 static void
3185 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3186                                            mp)
3187 {
3188   vat_main_t *vam = &vat_main;
3189   int i, count = ntohl (mp->count);
3190
3191   if (count > 0)
3192     print (vam->ofp, "classify table ids (%d) : ", count);
3193   for (i = 0; i < count; i++)
3194     {
3195       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3196       print (vam->ofp, (i < count - 1) ? "," : "");
3197     }
3198   vam->retval = ntohl (mp->retval);
3199   vam->result_ready = 1;
3200 }
3201
3202 static void
3203   vl_api_classify_table_ids_reply_t_handler_json
3204   (vl_api_classify_table_ids_reply_t * mp)
3205 {
3206   vat_main_t *vam = &vat_main;
3207   int i, count = ntohl (mp->count);
3208
3209   if (count > 0)
3210     {
3211       vat_json_node_t node;
3212
3213       vat_json_init_object (&node);
3214       for (i = 0; i < count; i++)
3215         {
3216           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3217         }
3218       vat_json_print (vam->ofp, &node);
3219       vat_json_free (&node);
3220     }
3221   vam->retval = ntohl (mp->retval);
3222   vam->result_ready = 1;
3223 }
3224
3225 static void
3226   vl_api_classify_table_by_interface_reply_t_handler
3227   (vl_api_classify_table_by_interface_reply_t * mp)
3228 {
3229   vat_main_t *vam = &vat_main;
3230   u32 table_id;
3231
3232   table_id = ntohl (mp->l2_table_id);
3233   if (table_id != ~0)
3234     print (vam->ofp, "l2 table id : %d", table_id);
3235   else
3236     print (vam->ofp, "l2 table id : No input ACL tables configured");
3237   table_id = ntohl (mp->ip4_table_id);
3238   if (table_id != ~0)
3239     print (vam->ofp, "ip4 table id : %d", table_id);
3240   else
3241     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3242   table_id = ntohl (mp->ip6_table_id);
3243   if (table_id != ~0)
3244     print (vam->ofp, "ip6 table id : %d", table_id);
3245   else
3246     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3247   vam->retval = ntohl (mp->retval);
3248   vam->result_ready = 1;
3249 }
3250
3251 static void
3252   vl_api_classify_table_by_interface_reply_t_handler_json
3253   (vl_api_classify_table_by_interface_reply_t * mp)
3254 {
3255   vat_main_t *vam = &vat_main;
3256   vat_json_node_t node;
3257
3258   vat_json_init_object (&node);
3259
3260   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3261   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3262   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3263
3264   vat_json_print (vam->ofp, &node);
3265   vat_json_free (&node);
3266
3267   vam->retval = ntohl (mp->retval);
3268   vam->result_ready = 1;
3269 }
3270
3271 static void vl_api_policer_add_del_reply_t_handler
3272   (vl_api_policer_add_del_reply_t * mp)
3273 {
3274   vat_main_t *vam = &vat_main;
3275   i32 retval = ntohl (mp->retval);
3276   if (vam->async_mode)
3277     {
3278       vam->async_errors += (retval < 0);
3279     }
3280   else
3281     {
3282       vam->retval = retval;
3283       vam->result_ready = 1;
3284       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3285         /*
3286          * Note: this is just barely thread-safe, depends on
3287          * the main thread spinning waiting for an answer...
3288          */
3289         errmsg ("policer index %d", ntohl (mp->policer_index));
3290     }
3291 }
3292
3293 static void vl_api_policer_add_del_reply_t_handler_json
3294   (vl_api_policer_add_del_reply_t * mp)
3295 {
3296   vat_main_t *vam = &vat_main;
3297   vat_json_node_t node;
3298
3299   vat_json_init_object (&node);
3300   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3301   vat_json_object_add_uint (&node, "policer_index",
3302                             ntohl (mp->policer_index));
3303
3304   vat_json_print (vam->ofp, &node);
3305   vat_json_free (&node);
3306
3307   vam->retval = ntohl (mp->retval);
3308   vam->result_ready = 1;
3309 }
3310
3311 /* Format hex dump. */
3312 u8 *
3313 format_hex_bytes (u8 * s, va_list * va)
3314 {
3315   u8 *bytes = va_arg (*va, u8 *);
3316   int n_bytes = va_arg (*va, int);
3317   uword i;
3318
3319   /* Print short or long form depending on byte count. */
3320   uword short_form = n_bytes <= 32;
3321   uword indent = format_get_indent (s);
3322
3323   if (n_bytes == 0)
3324     return s;
3325
3326   for (i = 0; i < n_bytes; i++)
3327     {
3328       if (!short_form && (i % 32) == 0)
3329         s = format (s, "%08x: ", i);
3330       s = format (s, "%02x", bytes[i]);
3331       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3332         s = format (s, "\n%U", format_white_space, indent);
3333     }
3334
3335   return s;
3336 }
3337
3338 static void
3339 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3340                                             * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   i32 retval = ntohl (mp->retval);
3344   if (retval == 0)
3345     {
3346       print (vam->ofp, "classify table info :");
3347       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3348              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3349              ntohl (mp->miss_next_index));
3350       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3351              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3352              ntohl (mp->match_n_vectors));
3353       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3354              ntohl (mp->mask_length));
3355     }
3356   vam->retval = retval;
3357   vam->result_ready = 1;
3358 }
3359
3360 static void
3361   vl_api_classify_table_info_reply_t_handler_json
3362   (vl_api_classify_table_info_reply_t * mp)
3363 {
3364   vat_main_t *vam = &vat_main;
3365   vat_json_node_t node;
3366
3367   i32 retval = ntohl (mp->retval);
3368   if (retval == 0)
3369     {
3370       vat_json_init_object (&node);
3371
3372       vat_json_object_add_int (&node, "sessions",
3373                                ntohl (mp->active_sessions));
3374       vat_json_object_add_int (&node, "nexttbl",
3375                                ntohl (mp->next_table_index));
3376       vat_json_object_add_int (&node, "nextnode",
3377                                ntohl (mp->miss_next_index));
3378       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3379       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3380       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3381       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3382                       ntohl (mp->mask_length), 0);
3383       vat_json_object_add_string_copy (&node, "mask", s);
3384
3385       vat_json_print (vam->ofp, &node);
3386       vat_json_free (&node);
3387     }
3388   vam->retval = ntohl (mp->retval);
3389   vam->result_ready = 1;
3390 }
3391
3392 static void
3393 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3394                                            mp)
3395 {
3396   vat_main_t *vam = &vat_main;
3397
3398   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3399          ntohl (mp->hit_next_index), ntohl (mp->advance),
3400          ntohl (mp->opaque_index));
3401   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3402          ntohl (mp->match_length));
3403 }
3404
3405 static void
3406   vl_api_classify_session_details_t_handler_json
3407   (vl_api_classify_session_details_t * mp)
3408 {
3409   vat_main_t *vam = &vat_main;
3410   vat_json_node_t *node = NULL;
3411
3412   if (VAT_JSON_ARRAY != vam->json_tree.type)
3413     {
3414       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3415       vat_json_init_array (&vam->json_tree);
3416     }
3417   node = vat_json_array_add (&vam->json_tree);
3418
3419   vat_json_init_object (node);
3420   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3421   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3422   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3423   u8 *s =
3424     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3425             0);
3426   vat_json_object_add_string_copy (node, "match", s);
3427 }
3428
3429 static void vl_api_pg_create_interface_reply_t_handler
3430   (vl_api_pg_create_interface_reply_t * mp)
3431 {
3432   vat_main_t *vam = &vat_main;
3433
3434   vam->retval = ntohl (mp->retval);
3435   vam->result_ready = 1;
3436 }
3437
3438 static void vl_api_pg_create_interface_reply_t_handler_json
3439   (vl_api_pg_create_interface_reply_t * mp)
3440 {
3441   vat_main_t *vam = &vat_main;
3442   vat_json_node_t node;
3443
3444   i32 retval = ntohl (mp->retval);
3445   if (retval == 0)
3446     {
3447       vat_json_init_object (&node);
3448
3449       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3450
3451       vat_json_print (vam->ofp, &node);
3452       vat_json_free (&node);
3453     }
3454   vam->retval = ntohl (mp->retval);
3455   vam->result_ready = 1;
3456 }
3457
3458 static void vl_api_policer_classify_details_t_handler
3459   (vl_api_policer_classify_details_t * mp)
3460 {
3461   vat_main_t *vam = &vat_main;
3462
3463   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3464          ntohl (mp->table_index));
3465 }
3466
3467 static void vl_api_policer_classify_details_t_handler_json
3468   (vl_api_policer_classify_details_t * mp)
3469 {
3470   vat_main_t *vam = &vat_main;
3471   vat_json_node_t *node;
3472
3473   if (VAT_JSON_ARRAY != vam->json_tree.type)
3474     {
3475       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3476       vat_json_init_array (&vam->json_tree);
3477     }
3478   node = vat_json_array_add (&vam->json_tree);
3479
3480   vat_json_init_object (node);
3481   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3482   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3483 }
3484
3485 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3486   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3487 {
3488   vat_main_t *vam = &vat_main;
3489   i32 retval = ntohl (mp->retval);
3490   if (vam->async_mode)
3491     {
3492       vam->async_errors += (retval < 0);
3493     }
3494   else
3495     {
3496       vam->retval = retval;
3497       vam->sw_if_index = ntohl (mp->sw_if_index);
3498       vam->result_ready = 1;
3499     }
3500 }
3501
3502 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3503   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3504 {
3505   vat_main_t *vam = &vat_main;
3506   vat_json_node_t node;
3507
3508   vat_json_init_object (&node);
3509   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3510   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3511
3512   vat_json_print (vam->ofp, &node);
3513   vat_json_free (&node);
3514
3515   vam->retval = ntohl (mp->retval);
3516   vam->result_ready = 1;
3517 }
3518
3519 static void vl_api_flow_classify_details_t_handler
3520   (vl_api_flow_classify_details_t * mp)
3521 {
3522   vat_main_t *vam = &vat_main;
3523
3524   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3525          ntohl (mp->table_index));
3526 }
3527
3528 static void vl_api_flow_classify_details_t_handler_json
3529   (vl_api_flow_classify_details_t * mp)
3530 {
3531   vat_main_t *vam = &vat_main;
3532   vat_json_node_t *node;
3533
3534   if (VAT_JSON_ARRAY != vam->json_tree.type)
3535     {
3536       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3537       vat_json_init_array (&vam->json_tree);
3538     }
3539   node = vat_json_array_add (&vam->json_tree);
3540
3541   vat_json_init_object (node);
3542   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3543   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3544 }
3545
3546
3547
3548 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3549 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3550 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3551 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3552 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3553 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3554
3555 /*
3556  * Generate boilerplate reply handlers, which
3557  * dig the return value out of the xxx_reply_t API message,
3558  * stick it into vam->retval, and set vam->result_ready
3559  *
3560  * Could also do this by pointing N message decode slots at
3561  * a single function, but that could break in subtle ways.
3562  */
3563
3564 #define foreach_standard_reply_retval_handler           \
3565 _(sw_interface_set_flags_reply)                         \
3566 _(sw_interface_add_del_address_reply)                   \
3567 _(sw_interface_set_table_reply)                         \
3568 _(sw_interface_set_mpls_enable_reply)                   \
3569 _(sw_interface_set_vpath_reply)                         \
3570 _(sw_interface_set_vxlan_bypass_reply)                  \
3571 _(sw_interface_set_l2_bridge_reply)                     \
3572 _(bridge_domain_add_del_reply)                          \
3573 _(sw_interface_set_l2_xconnect_reply)                   \
3574 _(l2fib_add_del_reply)                                  \
3575 _(ip_add_del_route_reply)                               \
3576 _(mpls_route_add_del_reply)                             \
3577 _(mpls_ip_bind_unbind_reply)                            \
3578 _(proxy_arp_add_del_reply)                              \
3579 _(proxy_arp_intfc_enable_disable_reply)                 \
3580 _(sw_interface_set_unnumbered_reply)                    \
3581 _(ip_neighbor_add_del_reply)                            \
3582 _(reset_vrf_reply)                                      \
3583 _(oam_add_del_reply)                                    \
3584 _(reset_fib_reply)                                      \
3585 _(dhcp_proxy_config_reply)                              \
3586 _(dhcp_proxy_config_2_reply)                            \
3587 _(dhcp_proxy_set_vss_reply)                             \
3588 _(dhcp_client_config_reply)                             \
3589 _(set_ip_flow_hash_reply)                               \
3590 _(sw_interface_ip6_enable_disable_reply)                \
3591 _(sw_interface_ip6_set_link_local_address_reply)        \
3592 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3593 _(sw_interface_ip6nd_ra_config_reply)                   \
3594 _(set_arp_neighbor_limit_reply)                         \
3595 _(l2_patch_add_del_reply)                               \
3596 _(sr_tunnel_add_del_reply)                              \
3597 _(sr_policy_add_del_reply)                              \
3598 _(sr_multicast_map_add_del_reply)                       \
3599 _(classify_add_del_session_reply)                       \
3600 _(classify_set_interface_ip_table_reply)                \
3601 _(classify_set_interface_l2_tables_reply)               \
3602 _(l2tpv3_set_tunnel_cookies_reply)                      \
3603 _(l2tpv3_interface_enable_disable_reply)                \
3604 _(l2tpv3_set_lookup_key_reply)                          \
3605 _(l2_fib_clear_table_reply)                             \
3606 _(l2_interface_efp_filter_reply)                        \
3607 _(l2_interface_vlan_tag_rewrite_reply)                  \
3608 _(modify_vhost_user_if_reply)                           \
3609 _(delete_vhost_user_if_reply)                           \
3610 _(want_ip4_arp_events_reply)                            \
3611 _(want_ip6_nd_events_reply)                             \
3612 _(input_acl_set_interface_reply)                        \
3613 _(ipsec_spd_add_del_reply)                              \
3614 _(ipsec_interface_add_del_spd_reply)                    \
3615 _(ipsec_spd_add_del_entry_reply)                        \
3616 _(ipsec_sad_add_del_entry_reply)                        \
3617 _(ipsec_sa_set_key_reply)                               \
3618 _(ikev2_profile_add_del_reply)                          \
3619 _(ikev2_profile_set_auth_reply)                         \
3620 _(ikev2_profile_set_id_reply)                           \
3621 _(ikev2_profile_set_ts_reply)                           \
3622 _(ikev2_set_local_key_reply)                            \
3623 _(delete_loopback_reply)                                \
3624 _(bd_ip_mac_add_del_reply)                              \
3625 _(map_del_domain_reply)                                 \
3626 _(map_add_del_rule_reply)                               \
3627 _(want_interface_events_reply)                          \
3628 _(want_stats_reply)                                     \
3629 _(cop_interface_enable_disable_reply)                   \
3630 _(cop_whitelist_enable_disable_reply)                   \
3631 _(sw_interface_clear_stats_reply)                       \
3632 _(ioam_enable_reply)                              \
3633 _(ioam_disable_reply)                              \
3634 _(lisp_add_del_locator_reply)                           \
3635 _(lisp_add_del_local_eid_reply)                         \
3636 _(lisp_add_del_remote_mapping_reply)                    \
3637 _(lisp_add_del_adjacency_reply)                         \
3638 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3639 _(lisp_add_del_map_resolver_reply)                      \
3640 _(lisp_add_del_map_server_reply)                        \
3641 _(lisp_gpe_enable_disable_reply)                        \
3642 _(lisp_gpe_add_del_iface_reply)                         \
3643 _(lisp_enable_disable_reply)                            \
3644 _(lisp_rloc_probe_enable_disable_reply)                 \
3645 _(lisp_map_register_enable_disable_reply)               \
3646 _(lisp_pitr_set_locator_set_reply)                      \
3647 _(lisp_map_request_mode_reply)                          \
3648 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3649 _(lisp_eid_table_add_del_map_reply)                     \
3650 _(vxlan_gpe_add_del_tunnel_reply)                       \
3651 _(af_packet_delete_reply)                               \
3652 _(policer_classify_set_interface_reply)                 \
3653 _(netmap_create_reply)                                  \
3654 _(netmap_delete_reply)                                  \
3655 _(set_ipfix_exporter_reply)                             \
3656 _(set_ipfix_classify_stream_reply)                      \
3657 _(ipfix_classify_table_add_del_reply)                   \
3658 _(flow_classify_set_interface_reply)                    \
3659 _(sw_interface_span_enable_disable_reply)               \
3660 _(pg_capture_reply)                                     \
3661 _(pg_enable_disable_reply)                              \
3662 _(ip_source_and_port_range_check_add_del_reply)         \
3663 _(ip_source_and_port_range_check_interface_add_del_reply)\
3664 _(delete_subif_reply)                                   \
3665 _(l2_interface_pbb_tag_rewrite_reply)                   \
3666 _(punt_reply)                                           \
3667 _(feature_enable_disable_reply)                         \
3668 _(sw_interface_tag_add_del_reply)                       \
3669 _(sw_interface_set_mtu_reply)
3670
3671 #if DPDK > 0
3672 #define foreach_standard_dpdk_reply_retval_handler      \
3673 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3674 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3675 _(sw_interface_set_dpdk_hqos_tctbl_reply)
3676 #endif
3677
3678 #define _(n)                                    \
3679     static void vl_api_##n##_t_handler          \
3680     (vl_api_##n##_t * mp)                       \
3681     {                                           \
3682         vat_main_t * vam = &vat_main;           \
3683         i32 retval = ntohl(mp->retval);         \
3684         if (vam->async_mode) {                  \
3685             vam->async_errors += (retval < 0);  \
3686         } else {                                \
3687             vam->retval = retval;               \
3688             vam->result_ready = 1;              \
3689         }                                       \
3690     }
3691 foreach_standard_reply_retval_handler;
3692 #undef _
3693
3694 #define _(n)                                    \
3695     static void vl_api_##n##_t_handler_json     \
3696     (vl_api_##n##_t * mp)                       \
3697     {                                           \
3698         vat_main_t * vam = &vat_main;           \
3699         vat_json_node_t node;                   \
3700         vat_json_init_object(&node);            \
3701         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3702         vat_json_print(vam->ofp, &node);        \
3703         vam->retval = ntohl(mp->retval);        \
3704         vam->result_ready = 1;                  \
3705     }
3706 foreach_standard_reply_retval_handler;
3707 #undef _
3708
3709 #if DPDK > 0
3710 #define _(n)                                    \
3711     static void vl_api_##n##_t_handler          \
3712     (vl_api_##n##_t * mp)                       \
3713     {                                           \
3714         vat_main_t * vam = &vat_main;           \
3715         i32 retval = ntohl(mp->retval);         \
3716         if (vam->async_mode) {                  \
3717             vam->async_errors += (retval < 0);  \
3718         } else {                                \
3719             vam->retval = retval;               \
3720             vam->result_ready = 1;              \
3721         }                                       \
3722     }
3723 foreach_standard_dpdk_reply_retval_handler;
3724 #undef _
3725
3726 #define _(n)                                    \
3727     static void vl_api_##n##_t_handler_json     \
3728     (vl_api_##n##_t * mp)                       \
3729     {                                           \
3730         vat_main_t * vam = &vat_main;           \
3731         vat_json_node_t node;                   \
3732         vat_json_init_object(&node);            \
3733         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3734         vat_json_print(vam->ofp, &node);        \
3735         vam->retval = ntohl(mp->retval);        \
3736         vam->result_ready = 1;                  \
3737     }
3738 foreach_standard_dpdk_reply_retval_handler;
3739 #undef _
3740 #endif
3741
3742 /*
3743  * Table of message reply handlers, must include boilerplate handlers
3744  * we just generated
3745  */
3746
3747 #define foreach_vpe_api_reply_msg                                       \
3748 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3749 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3750 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3751 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3752 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3753 _(CLI_REPLY, cli_reply)                                                 \
3754 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3755 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3756   sw_interface_add_del_address_reply)                                   \
3757 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3758 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3759 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3760 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3761 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3762   sw_interface_set_l2_xconnect_reply)                                   \
3763 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3764   sw_interface_set_l2_bridge_reply)                                     \
3765 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3766 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3767 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3768 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3769 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3770 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3771 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3772 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3773 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3774 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3775 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3776 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3777 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3778 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3779 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3780   proxy_arp_intfc_enable_disable_reply)                                 \
3781 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
3782 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3783   sw_interface_set_unnumbered_reply)                                    \
3784 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3785 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3786 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3787 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3788 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3789 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3790 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3791 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3792 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3793 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3794 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3795 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3796   sw_interface_ip6_enable_disable_reply)                                \
3797 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3798   sw_interface_ip6_set_link_local_address_reply)                        \
3799 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3800   sw_interface_ip6nd_ra_prefix_reply)                                   \
3801 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3802   sw_interface_ip6nd_ra_config_reply)                                   \
3803 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3804 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3805 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3806 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3807 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3808 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3809 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3810 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3811 classify_set_interface_ip_table_reply)                                  \
3812 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3813   classify_set_interface_l2_tables_reply)                               \
3814 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3815 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3816 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3817 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3818 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3819   l2tpv3_interface_enable_disable_reply)                                \
3820 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3821 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3822 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3823 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3824 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3825 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3826 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3827 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3828 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3829 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3830 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3831 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3832 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3833 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3834 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3835 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3836 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3837 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3838 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3839 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3840 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3841 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3842 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3843 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3844 _(IP_DETAILS, ip_details)                                               \
3845 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3846 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3847 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3848 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3849 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3850 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3851 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3852 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3853 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3854 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3855 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3856 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3857 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3858 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3859 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3860 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3861 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3862 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3863 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3864 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3865 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3866 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3867 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3868 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3869 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3870 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3871 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3872 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3873 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3874 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3875 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3876 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3877 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3878 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3879 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3880 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3881 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3882 _(LISP_ADD_DEL_MAP_SERVER_REPLY, lisp_add_del_map_server_reply)         \
3883 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3884 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3885 _(LISP_MAP_REGISTER_ENABLE_DISABLE_REPLY,                               \
3886   lisp_map_register_enable_disable_reply)                               \
3887 _(LISP_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                 \
3888   lisp_rloc_probe_enable_disable_reply)                                 \
3889 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3890 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3891 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3892 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3893 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3894 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3895 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3896 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3897 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3898 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3899 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3900 _(LISP_MAP_SERVER_DETAILS, lisp_map_server_details)                     \
3901 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3902 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3903 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3904   lisp_add_del_map_request_itr_rlocs_reply)                             \
3905 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3906   lisp_get_map_request_itr_rlocs_reply)                                 \
3907 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3908 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3909 _(SHOW_LISP_RLOC_PROBE_STATE_REPLY, show_lisp_rloc_probe_state_reply)   \
3910 _(SHOW_LISP_MAP_REGISTER_STATE_REPLY,                                   \
3911   show_lisp_map_register_state_reply)                                   \
3912 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3913 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3914 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3915 _(POLICER_DETAILS, policer_details)                                     \
3916 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3917 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3918 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3919 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3920 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
3921 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3922 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3923 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3924 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3925 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3926 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3927 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3928 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3929 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3930 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3931 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3932 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3933 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3934 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3935 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3936 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3937 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3938 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3939 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3940 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3941  ip_source_and_port_range_check_add_del_reply)                          \
3942 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3943  ip_source_and_port_range_check_interface_add_del_reply)                \
3944 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3945 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3946 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3947 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3948 _(PUNT_REPLY, punt_reply)                                               \
3949 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3950 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
3951 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
3952 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
3953 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
3954 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
3955 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
3956 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
3957
3958 #if DPDK > 0
3959 #define foreach_vpe_dpdk_api_reply_msg                                  \
3960 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3961   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3962 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3963   sw_interface_set_dpdk_hqos_subport_reply)                             \
3964 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3965   sw_interface_set_dpdk_hqos_tctbl_reply)
3966 #endif
3967
3968 /* M: construct, but don't yet send a message */
3969
3970 #define M(T,t)                                          \
3971 do {                                                    \
3972     vam->result_ready = 0;                              \
3973     mp = vl_msg_api_alloc_as_if_client(sizeof(*mp));    \
3974     memset (mp, 0, sizeof (*mp));                       \
3975     mp->_vl_msg_id = ntohs (VL_API_##T);                \
3976     mp->client_index = vam->my_client_index;            \
3977 } while(0);
3978
3979 #define M2(T,t,n)                                               \
3980 do {                                                            \
3981     vam->result_ready = 0;                                      \
3982     mp = vl_msg_api_alloc_as_if_client(sizeof(*mp)+(n));        \
3983     memset (mp, 0, sizeof (*mp));                               \
3984     mp->_vl_msg_id = ntohs (VL_API_##T);                        \
3985     mp->client_index = vam->my_client_index;                    \
3986 } while(0);
3987
3988
3989 /* S: send a message */
3990 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3991
3992 /* W: wait for results, with timeout */
3993 #define W                                       \
3994 do {                                            \
3995     timeout = vat_time_now (vam) + 1.0;         \
3996                                                 \
3997     while (vat_time_now (vam) < timeout) {      \
3998         if (vam->result_ready == 1) {           \
3999             return (vam->retval);               \
4000         }                                       \
4001         vat_suspend (vam->vlib_main, 1e-3);     \
4002     }                                           \
4003     return -99;                                 \
4004 } while(0);
4005
4006 /* W2: wait for results, with timeout */
4007 #define W2(body)                                \
4008 do {                                            \
4009     timeout = vat_time_now (vam) + 1.0;         \
4010                                                 \
4011     while (vat_time_now (vam) < timeout) {      \
4012         if (vam->result_ready == 1) {           \
4013           (body);                               \
4014           return (vam->retval);                 \
4015         }                                       \
4016         vat_suspend (vam->vlib_main, 1e-3);     \
4017     }                                           \
4018     return -99;                                 \
4019 } while(0);
4020
4021 typedef struct
4022 {
4023   u8 *name;
4024   u32 value;
4025 } name_sort_t;
4026
4027
4028 #define STR_VTR_OP_CASE(op)     \
4029     case L2_VTR_ ## op:         \
4030         return "" # op;
4031
4032 static const char *
4033 str_vtr_op (u32 vtr_op)
4034 {
4035   switch (vtr_op)
4036     {
4037       STR_VTR_OP_CASE (DISABLED);
4038       STR_VTR_OP_CASE (PUSH_1);
4039       STR_VTR_OP_CASE (PUSH_2);
4040       STR_VTR_OP_CASE (POP_1);
4041       STR_VTR_OP_CASE (POP_2);
4042       STR_VTR_OP_CASE (TRANSLATE_1_1);
4043       STR_VTR_OP_CASE (TRANSLATE_1_2);
4044       STR_VTR_OP_CASE (TRANSLATE_2_1);
4045       STR_VTR_OP_CASE (TRANSLATE_2_2);
4046     }
4047
4048   return "UNKNOWN";
4049 }
4050
4051 static int
4052 dump_sub_interface_table (vat_main_t * vam)
4053 {
4054   const sw_interface_subif_t *sub = NULL;
4055
4056   if (vam->json_output)
4057     {
4058       clib_warning
4059         ("JSON output supported only for VPE API calls and dump_stats_table");
4060       return -99;
4061     }
4062
4063   print (vam->ofp,
4064          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4065          "Interface", "sw_if_index",
4066          "sub id", "dot1ad", "tags", "outer id",
4067          "inner id", "exact", "default", "outer any", "inner any");
4068
4069   vec_foreach (sub, vam->sw_if_subif_table)
4070   {
4071     print (vam->ofp,
4072            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4073            sub->interface_name,
4074            sub->sw_if_index,
4075            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4076            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4077            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4078            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4079     if (sub->vtr_op != L2_VTR_DISABLED)
4080       {
4081         print (vam->ofp,
4082                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4083                "tag1: %d tag2: %d ]",
4084                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4085                sub->vtr_tag1, sub->vtr_tag2);
4086       }
4087   }
4088
4089   return 0;
4090 }
4091
4092 static int
4093 name_sort_cmp (void *a1, void *a2)
4094 {
4095   name_sort_t *n1 = a1;
4096   name_sort_t *n2 = a2;
4097
4098   return strcmp ((char *) n1->name, (char *) n2->name);
4099 }
4100
4101 static int
4102 dump_interface_table (vat_main_t * vam)
4103 {
4104   hash_pair_t *p;
4105   name_sort_t *nses = 0, *ns;
4106
4107   if (vam->json_output)
4108     {
4109       clib_warning
4110         ("JSON output supported only for VPE API calls and dump_stats_table");
4111       return -99;
4112     }
4113
4114   /* *INDENT-OFF* */
4115   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4116   ({
4117     vec_add2 (nses, ns, 1);
4118     ns->name = (u8 *)(p->key);
4119     ns->value = (u32) p->value[0];
4120   }));
4121   /* *INDENT-ON* */
4122
4123   vec_sort_with_function (nses, name_sort_cmp);
4124
4125   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4126   vec_foreach (ns, nses)
4127   {
4128     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4129   }
4130   vec_free (nses);
4131   return 0;
4132 }
4133
4134 static int
4135 dump_ip_table (vat_main_t * vam, int is_ipv6)
4136 {
4137   const ip_details_t *det = NULL;
4138   const ip_address_details_t *address = NULL;
4139   u32 i = ~0;
4140
4141   print (vam->ofp, "%-12s", "sw_if_index");
4142
4143   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4144   {
4145     i++;
4146     if (!det->present)
4147       {
4148         continue;
4149       }
4150     print (vam->ofp, "%-12d", i);
4151     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4152     if (!det->addr)
4153       {
4154         continue;
4155       }
4156     vec_foreach (address, det->addr)
4157     {
4158       print (vam->ofp,
4159              "            %-30U%-13d",
4160              is_ipv6 ? format_ip6_address : format_ip4_address,
4161              address->ip, address->prefix_length);
4162     }
4163   }
4164
4165   return 0;
4166 }
4167
4168 static int
4169 dump_ipv4_table (vat_main_t * vam)
4170 {
4171   if (vam->json_output)
4172     {
4173       clib_warning
4174         ("JSON output supported only for VPE API calls and dump_stats_table");
4175       return -99;
4176     }
4177
4178   return dump_ip_table (vam, 0);
4179 }
4180
4181 static int
4182 dump_ipv6_table (vat_main_t * vam)
4183 {
4184   if (vam->json_output)
4185     {
4186       clib_warning
4187         ("JSON output supported only for VPE API calls and dump_stats_table");
4188       return -99;
4189     }
4190
4191   return dump_ip_table (vam, 1);
4192 }
4193
4194 static char *
4195 counter_type_to_str (u8 counter_type, u8 is_combined)
4196 {
4197   if (!is_combined)
4198     {
4199       switch (counter_type)
4200         {
4201         case VNET_INTERFACE_COUNTER_DROP:
4202           return "drop";
4203         case VNET_INTERFACE_COUNTER_PUNT:
4204           return "punt";
4205         case VNET_INTERFACE_COUNTER_IP4:
4206           return "ip4";
4207         case VNET_INTERFACE_COUNTER_IP6:
4208           return "ip6";
4209         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4210           return "rx-no-buf";
4211         case VNET_INTERFACE_COUNTER_RX_MISS:
4212           return "rx-miss";
4213         case VNET_INTERFACE_COUNTER_RX_ERROR:
4214           return "rx-error";
4215         case VNET_INTERFACE_COUNTER_TX_ERROR:
4216           return "tx-error";
4217         default:
4218           return "INVALID-COUNTER-TYPE";
4219         }
4220     }
4221   else
4222     {
4223       switch (counter_type)
4224         {
4225         case VNET_INTERFACE_COUNTER_RX:
4226           return "rx";
4227         case VNET_INTERFACE_COUNTER_TX:
4228           return "tx";
4229         default:
4230           return "INVALID-COUNTER-TYPE";
4231         }
4232     }
4233 }
4234
4235 static int
4236 dump_stats_table (vat_main_t * vam)
4237 {
4238   vat_json_node_t node;
4239   vat_json_node_t *msg_array;
4240   vat_json_node_t *msg;
4241   vat_json_node_t *counter_array;
4242   vat_json_node_t *counter;
4243   interface_counter_t c;
4244   u64 packets;
4245   ip4_fib_counter_t *c4;
4246   ip6_fib_counter_t *c6;
4247   int i, j;
4248
4249   if (!vam->json_output)
4250     {
4251       clib_warning ("dump_stats_table supported only in JSON format");
4252       return -99;
4253     }
4254
4255   vat_json_init_object (&node);
4256
4257   /* interface counters */
4258   msg_array = vat_json_object_add (&node, "interface_counters");
4259   vat_json_init_array (msg_array);
4260   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4261     {
4262       msg = vat_json_array_add (msg_array);
4263       vat_json_init_object (msg);
4264       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4265                                        (u8 *) counter_type_to_str (i, 0));
4266       vat_json_object_add_int (msg, "is_combined", 0);
4267       counter_array = vat_json_object_add (msg, "data");
4268       vat_json_init_array (counter_array);
4269       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4270         {
4271           packets = vam->simple_interface_counters[i][j];
4272           vat_json_array_add_uint (counter_array, packets);
4273         }
4274     }
4275   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4276     {
4277       msg = vat_json_array_add (msg_array);
4278       vat_json_init_object (msg);
4279       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4280                                        (u8 *) counter_type_to_str (i, 1));
4281       vat_json_object_add_int (msg, "is_combined", 1);
4282       counter_array = vat_json_object_add (msg, "data");
4283       vat_json_init_array (counter_array);
4284       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4285         {
4286           c = vam->combined_interface_counters[i][j];
4287           counter = vat_json_array_add (counter_array);
4288           vat_json_init_object (counter);
4289           vat_json_object_add_uint (counter, "packets", c.packets);
4290           vat_json_object_add_uint (counter, "bytes", c.bytes);
4291         }
4292     }
4293
4294   /* ip4 fib counters */
4295   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4296   vat_json_init_array (msg_array);
4297   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4298     {
4299       msg = vat_json_array_add (msg_array);
4300       vat_json_init_object (msg);
4301       vat_json_object_add_uint (msg, "vrf_id",
4302                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4303       counter_array = vat_json_object_add (msg, "c");
4304       vat_json_init_array (counter_array);
4305       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4306         {
4307           counter = vat_json_array_add (counter_array);
4308           vat_json_init_object (counter);
4309           c4 = &vam->ip4_fib_counters[i][j];
4310           vat_json_object_add_ip4 (counter, "address", c4->address);
4311           vat_json_object_add_uint (counter, "address_length",
4312                                     c4->address_length);
4313           vat_json_object_add_uint (counter, "packets", c4->packets);
4314           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4315         }
4316     }
4317
4318   /* ip6 fib counters */
4319   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4320   vat_json_init_array (msg_array);
4321   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4322     {
4323       msg = vat_json_array_add (msg_array);
4324       vat_json_init_object (msg);
4325       vat_json_object_add_uint (msg, "vrf_id",
4326                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4327       counter_array = vat_json_object_add (msg, "c");
4328       vat_json_init_array (counter_array);
4329       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4330         {
4331           counter = vat_json_array_add (counter_array);
4332           vat_json_init_object (counter);
4333           c6 = &vam->ip6_fib_counters[i][j];
4334           vat_json_object_add_ip6 (counter, "address", c6->address);
4335           vat_json_object_add_uint (counter, "address_length",
4336                                     c6->address_length);
4337           vat_json_object_add_uint (counter, "packets", c6->packets);
4338           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4339         }
4340     }
4341
4342   vat_json_print (vam->ofp, &node);
4343   vat_json_free (&node);
4344
4345   return 0;
4346 }
4347
4348 int
4349 exec (vat_main_t * vam)
4350 {
4351   api_main_t *am = &api_main;
4352   vl_api_cli_request_t *mp;
4353   f64 timeout;
4354   void *oldheap;
4355   u8 *cmd = 0;
4356   unformat_input_t *i = vam->input;
4357
4358   if (vec_len (i->buffer) == 0)
4359     return -1;
4360
4361   if (vam->exec_mode == 0 && unformat (i, "mode"))
4362     {
4363       vam->exec_mode = 1;
4364       return 0;
4365     }
4366   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4367     {
4368       vam->exec_mode = 0;
4369       return 0;
4370     }
4371
4372
4373   M (CLI_REQUEST, cli_request);
4374
4375   /*
4376    * Copy cmd into shared memory.
4377    * In order for the CLI command to work, it
4378    * must be a vector ending in \n, not a C-string ending
4379    * in \n\0.
4380    */
4381   pthread_mutex_lock (&am->vlib_rp->mutex);
4382   oldheap = svm_push_data_heap (am->vlib_rp);
4383
4384   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4385   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4386
4387   svm_pop_heap (oldheap);
4388   pthread_mutex_unlock (&am->vlib_rp->mutex);
4389
4390   mp->cmd_in_shmem = (u64) cmd;
4391   S;
4392   timeout = vat_time_now (vam) + 10.0;
4393
4394   while (vat_time_now (vam) < timeout)
4395     {
4396       if (vam->result_ready == 1)
4397         {
4398           u8 *free_me;
4399           if (vam->shmem_result != NULL)
4400             print (vam->ofp, "%s", vam->shmem_result);
4401           pthread_mutex_lock (&am->vlib_rp->mutex);
4402           oldheap = svm_push_data_heap (am->vlib_rp);
4403
4404           free_me = (u8 *) vam->shmem_result;
4405           vec_free (free_me);
4406
4407           svm_pop_heap (oldheap);
4408           pthread_mutex_unlock (&am->vlib_rp->mutex);
4409           return 0;
4410         }
4411     }
4412   return -99;
4413 }
4414
4415 /*
4416  * Future replacement of exec() that passes CLI buffers directly in
4417  * the API messages instead of an additional shared memory area.
4418  */
4419 static int
4420 exec_inband (vat_main_t * vam)
4421 {
4422   vl_api_cli_inband_t *mp;
4423   f64 timeout;
4424   unformat_input_t *i = vam->input;
4425
4426   if (vec_len (i->buffer) == 0)
4427     return -1;
4428
4429   if (vam->exec_mode == 0 && unformat (i, "mode"))
4430     {
4431       vam->exec_mode = 1;
4432       return 0;
4433     }
4434   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4435     {
4436       vam->exec_mode = 0;
4437       return 0;
4438     }
4439
4440   /*
4441    * In order for the CLI command to work, it
4442    * must be a vector ending in \n, not a C-string ending
4443    * in \n\0.
4444    */
4445   u32 len = vec_len (vam->input->buffer);
4446   M2 (CLI_INBAND, cli_inband, len);
4447   clib_memcpy (mp->cmd, vam->input->buffer, len);
4448   mp->length = htonl (len);
4449
4450   S;
4451   W2 (print (vam->ofp, "%s", vam->cmd_reply));
4452 }
4453
4454 static int
4455 api_create_loopback (vat_main_t * vam)
4456 {
4457   unformat_input_t *i = vam->input;
4458   vl_api_create_loopback_t *mp;
4459   f64 timeout;
4460   u8 mac_address[6];
4461   u8 mac_set = 0;
4462
4463   memset (mac_address, 0, sizeof (mac_address));
4464
4465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4466     {
4467       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4468         mac_set = 1;
4469       else
4470         break;
4471     }
4472
4473   /* Construct the API message */
4474   M (CREATE_LOOPBACK, create_loopback);
4475   if (mac_set)
4476     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4477
4478   S;
4479   W;
4480 }
4481
4482 static int
4483 api_delete_loopback (vat_main_t * vam)
4484 {
4485   unformat_input_t *i = vam->input;
4486   vl_api_delete_loopback_t *mp;
4487   f64 timeout;
4488   u32 sw_if_index = ~0;
4489
4490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4491     {
4492       if (unformat (i, "sw_if_index %d", &sw_if_index))
4493         ;
4494       else
4495         break;
4496     }
4497
4498   if (sw_if_index == ~0)
4499     {
4500       errmsg ("missing sw_if_index");
4501       return -99;
4502     }
4503
4504   /* Construct the API message */
4505   M (DELETE_LOOPBACK, delete_loopback);
4506   mp->sw_if_index = ntohl (sw_if_index);
4507
4508   S;
4509   W;
4510 }
4511
4512 static int
4513 api_want_stats (vat_main_t * vam)
4514 {
4515   unformat_input_t *i = vam->input;
4516   vl_api_want_stats_t *mp;
4517   f64 timeout;
4518   int enable = -1;
4519
4520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4521     {
4522       if (unformat (i, "enable"))
4523         enable = 1;
4524       else if (unformat (i, "disable"))
4525         enable = 0;
4526       else
4527         break;
4528     }
4529
4530   if (enable == -1)
4531     {
4532       errmsg ("missing enable|disable");
4533       return -99;
4534     }
4535
4536   M (WANT_STATS, want_stats);
4537   mp->enable_disable = enable;
4538
4539   S;
4540   W;
4541 }
4542
4543 static int
4544 api_want_interface_events (vat_main_t * vam)
4545 {
4546   unformat_input_t *i = vam->input;
4547   vl_api_want_interface_events_t *mp;
4548   f64 timeout;
4549   int enable = -1;
4550
4551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4552     {
4553       if (unformat (i, "enable"))
4554         enable = 1;
4555       else if (unformat (i, "disable"))
4556         enable = 0;
4557       else
4558         break;
4559     }
4560
4561   if (enable == -1)
4562     {
4563       errmsg ("missing enable|disable");
4564       return -99;
4565     }
4566
4567   M (WANT_INTERFACE_EVENTS, want_interface_events);
4568   mp->enable_disable = enable;
4569
4570   vam->interface_event_display = enable;
4571
4572   S;
4573   W;
4574 }
4575
4576
4577 /* Note: non-static, called once to set up the initial intfc table */
4578 int
4579 api_sw_interface_dump (vat_main_t * vam)
4580 {
4581   vl_api_sw_interface_dump_t *mp;
4582   f64 timeout;
4583   hash_pair_t *p;
4584   name_sort_t *nses = 0, *ns;
4585   sw_interface_subif_t *sub = NULL;
4586
4587   /* Toss the old name table */
4588   /* *INDENT-OFF* */
4589   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4590   ({
4591     vec_add2 (nses, ns, 1);
4592     ns->name = (u8 *)(p->key);
4593     ns->value = (u32) p->value[0];
4594   }));
4595   /* *INDENT-ON* */
4596
4597   hash_free (vam->sw_if_index_by_interface_name);
4598
4599   vec_foreach (ns, nses) vec_free (ns->name);
4600
4601   vec_free (nses);
4602
4603   vec_foreach (sub, vam->sw_if_subif_table)
4604   {
4605     vec_free (sub->interface_name);
4606   }
4607   vec_free (vam->sw_if_subif_table);
4608
4609   /* recreate the interface name hash table */
4610   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4611
4612   /* Get list of ethernets */
4613   M (SW_INTERFACE_DUMP, sw_interface_dump);
4614   mp->name_filter_valid = 1;
4615   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4616   S;
4617
4618   /* and local / loopback interfaces */
4619   M (SW_INTERFACE_DUMP, sw_interface_dump);
4620   mp->name_filter_valid = 1;
4621   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4622   S;
4623
4624   /* and packet-generator interfaces */
4625   M (SW_INTERFACE_DUMP, sw_interface_dump);
4626   mp->name_filter_valid = 1;
4627   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4628   S;
4629
4630   /* and vxlan-gpe tunnel interfaces */
4631   M (SW_INTERFACE_DUMP, sw_interface_dump);
4632   mp->name_filter_valid = 1;
4633   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4634            sizeof (mp->name_filter) - 1);
4635   S;
4636
4637   /* and vxlan tunnel interfaces */
4638   M (SW_INTERFACE_DUMP, sw_interface_dump);
4639   mp->name_filter_valid = 1;
4640   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4641   S;
4642
4643   /* and host (af_packet) interfaces */
4644   M (SW_INTERFACE_DUMP, sw_interface_dump);
4645   mp->name_filter_valid = 1;
4646   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4647   S;
4648
4649   /* and l2tpv3 tunnel interfaces */
4650   M (SW_INTERFACE_DUMP, sw_interface_dump);
4651   mp->name_filter_valid = 1;
4652   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4653            sizeof (mp->name_filter) - 1);
4654   S;
4655
4656   /* and GRE tunnel interfaces */
4657   M (SW_INTERFACE_DUMP, sw_interface_dump);
4658   mp->name_filter_valid = 1;
4659   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4660   S;
4661
4662   /* and LISP-GPE interfaces */
4663   M (SW_INTERFACE_DUMP, sw_interface_dump);
4664   mp->name_filter_valid = 1;
4665   strncpy ((char *) mp->name_filter, "lisp_gpe",
4666            sizeof (mp->name_filter) - 1);
4667   S;
4668
4669   /* and IPSEC tunnel interfaces */
4670   M (SW_INTERFACE_DUMP, sw_interface_dump);
4671   mp->name_filter_valid = 1;
4672   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4673   S;
4674
4675   /* Use a control ping for synchronization */
4676   {
4677     vl_api_control_ping_t *mp;
4678     M (CONTROL_PING, control_ping);
4679     S;
4680   }
4681   W;
4682 }
4683
4684 static int
4685 api_sw_interface_set_flags (vat_main_t * vam)
4686 {
4687   unformat_input_t *i = vam->input;
4688   vl_api_sw_interface_set_flags_t *mp;
4689   f64 timeout;
4690   u32 sw_if_index;
4691   u8 sw_if_index_set = 0;
4692   u8 admin_up = 0, link_up = 0;
4693
4694   /* Parse args required to build the message */
4695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4696     {
4697       if (unformat (i, "admin-up"))
4698         admin_up = 1;
4699       else if (unformat (i, "admin-down"))
4700         admin_up = 0;
4701       else if (unformat (i, "link-up"))
4702         link_up = 1;
4703       else if (unformat (i, "link-down"))
4704         link_up = 0;
4705       else
4706         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4707         sw_if_index_set = 1;
4708       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4709         sw_if_index_set = 1;
4710       else
4711         break;
4712     }
4713
4714   if (sw_if_index_set == 0)
4715     {
4716       errmsg ("missing interface name or sw_if_index");
4717       return -99;
4718     }
4719
4720   /* Construct the API message */
4721   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4722   mp->sw_if_index = ntohl (sw_if_index);
4723   mp->admin_up_down = admin_up;
4724   mp->link_up_down = link_up;
4725
4726   /* send it... */
4727   S;
4728
4729   /* Wait for a reply, return the good/bad news... */
4730   W;
4731 }
4732
4733 static int
4734 api_sw_interface_clear_stats (vat_main_t * vam)
4735 {
4736   unformat_input_t *i = vam->input;
4737   vl_api_sw_interface_clear_stats_t *mp;
4738   f64 timeout;
4739   u32 sw_if_index;
4740   u8 sw_if_index_set = 0;
4741
4742   /* Parse args required to build the message */
4743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4744     {
4745       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4746         sw_if_index_set = 1;
4747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4748         sw_if_index_set = 1;
4749       else
4750         break;
4751     }
4752
4753   /* Construct the API message */
4754   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4755
4756   if (sw_if_index_set == 1)
4757     mp->sw_if_index = ntohl (sw_if_index);
4758   else
4759     mp->sw_if_index = ~0;
4760
4761   /* send it... */
4762   S;
4763
4764   /* Wait for a reply, return the good/bad news... */
4765   W;
4766 }
4767
4768 #if DPDK >0
4769 static int
4770 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4771 {
4772   unformat_input_t *i = vam->input;
4773   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4774   f64 timeout;
4775   u32 sw_if_index;
4776   u8 sw_if_index_set = 0;
4777   u32 subport;
4778   u8 subport_set = 0;
4779   u32 pipe;
4780   u8 pipe_set = 0;
4781   u32 profile;
4782   u8 profile_set = 0;
4783
4784   /* Parse args required to build the message */
4785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4786     {
4787       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4788         sw_if_index_set = 1;
4789       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4790         sw_if_index_set = 1;
4791       else if (unformat (i, "subport %u", &subport))
4792         subport_set = 1;
4793       else
4794         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4795         sw_if_index_set = 1;
4796       else if (unformat (i, "pipe %u", &pipe))
4797         pipe_set = 1;
4798       else if (unformat (i, "profile %u", &profile))
4799         profile_set = 1;
4800       else
4801         break;
4802     }
4803
4804   if (sw_if_index_set == 0)
4805     {
4806       errmsg ("missing interface name or sw_if_index");
4807       return -99;
4808     }
4809
4810   if (subport_set == 0)
4811     {
4812       errmsg ("missing subport ");
4813       return -99;
4814     }
4815
4816   if (pipe_set == 0)
4817     {
4818       errmsg ("missing pipe");
4819       return -99;
4820     }
4821
4822   if (profile_set == 0)
4823     {
4824       errmsg ("missing profile");
4825       return -99;
4826     }
4827
4828   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4829
4830   mp->sw_if_index = ntohl (sw_if_index);
4831   mp->subport = ntohl (subport);
4832   mp->pipe = ntohl (pipe);
4833   mp->profile = ntohl (profile);
4834
4835
4836   S;
4837   W;
4838   /* NOTREACHED */
4839   return 0;
4840 }
4841
4842 static int
4843 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4844 {
4845   unformat_input_t *i = vam->input;
4846   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4847   f64 timeout;
4848   u32 sw_if_index;
4849   u8 sw_if_index_set = 0;
4850   u32 subport;
4851   u8 subport_set = 0;
4852   u32 tb_rate = 1250000000;     /* 10GbE */
4853   u32 tb_size = 1000000;
4854   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4855   u32 tc_period = 10;
4856
4857   /* Parse args required to build the message */
4858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4859     {
4860       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4861         sw_if_index_set = 1;
4862       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4863         sw_if_index_set = 1;
4864       else if (unformat (i, "subport %u", &subport))
4865         subport_set = 1;
4866       else
4867         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4868         sw_if_index_set = 1;
4869       else if (unformat (i, "rate %u", &tb_rate))
4870         {
4871           u32 tc_id;
4872
4873           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4874                tc_id++)
4875             tc_rate[tc_id] = tb_rate;
4876         }
4877       else if (unformat (i, "bktsize %u", &tb_size))
4878         ;
4879       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4880         ;
4881       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4882         ;
4883       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4884         ;
4885       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4886         ;
4887       else if (unformat (i, "period %u", &tc_period))
4888         ;
4889       else
4890         break;
4891     }
4892
4893   if (sw_if_index_set == 0)
4894     {
4895       errmsg ("missing interface name or sw_if_index");
4896       return -99;
4897     }
4898
4899   if (subport_set == 0)
4900     {
4901       errmsg ("missing subport ");
4902       return -99;
4903     }
4904
4905   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4906
4907   mp->sw_if_index = ntohl (sw_if_index);
4908   mp->subport = ntohl (subport);
4909   mp->tb_rate = ntohl (tb_rate);
4910   mp->tb_size = ntohl (tb_size);
4911   mp->tc_rate[0] = ntohl (tc_rate[0]);
4912   mp->tc_rate[1] = ntohl (tc_rate[1]);
4913   mp->tc_rate[2] = ntohl (tc_rate[2]);
4914   mp->tc_rate[3] = ntohl (tc_rate[3]);
4915   mp->tc_period = ntohl (tc_period);
4916
4917   S;
4918   W;
4919   /* NOTREACHED */
4920   return 0;
4921 }
4922
4923 static int
4924 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4925 {
4926   unformat_input_t *i = vam->input;
4927   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4928   f64 timeout;
4929   u32 sw_if_index;
4930   u8 sw_if_index_set = 0;
4931   u8 entry_set = 0;
4932   u8 tc_set = 0;
4933   u8 queue_set = 0;
4934   u32 entry, tc, queue;
4935
4936   /* Parse args required to build the message */
4937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4938     {
4939       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4940         sw_if_index_set = 1;
4941       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4942         sw_if_index_set = 1;
4943       else if (unformat (i, "entry %d", &entry))
4944         entry_set = 1;
4945       else if (unformat (i, "tc %d", &tc))
4946         tc_set = 1;
4947       else if (unformat (i, "queue %d", &queue))
4948         queue_set = 1;
4949       else
4950         break;
4951     }
4952
4953   if (sw_if_index_set == 0)
4954     {
4955       errmsg ("missing interface name or sw_if_index");
4956       return -99;
4957     }
4958
4959   if (entry_set == 0)
4960     {
4961       errmsg ("missing entry ");
4962       return -99;
4963     }
4964
4965   if (tc_set == 0)
4966     {
4967       errmsg ("missing traffic class ");
4968       return -99;
4969     }
4970
4971   if (queue_set == 0)
4972     {
4973       errmsg ("missing queue ");
4974       return -99;
4975     }
4976
4977   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4978
4979   mp->sw_if_index = ntohl (sw_if_index);
4980   mp->entry = ntohl (entry);
4981   mp->tc = ntohl (tc);
4982   mp->queue = ntohl (queue);
4983
4984   S;
4985   W;
4986   /* NOTREACHED */
4987   return 0;
4988 }
4989 #endif
4990
4991 static int
4992 api_sw_interface_add_del_address (vat_main_t * vam)
4993 {
4994   unformat_input_t *i = vam->input;
4995   vl_api_sw_interface_add_del_address_t *mp;
4996   f64 timeout;
4997   u32 sw_if_index;
4998   u8 sw_if_index_set = 0;
4999   u8 is_add = 1, del_all = 0;
5000   u32 address_length = 0;
5001   u8 v4_address_set = 0;
5002   u8 v6_address_set = 0;
5003   ip4_address_t v4address;
5004   ip6_address_t v6address;
5005
5006   /* Parse args required to build the message */
5007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5008     {
5009       if (unformat (i, "del-all"))
5010         del_all = 1;
5011       else if (unformat (i, "del"))
5012         is_add = 0;
5013       else
5014         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5015         sw_if_index_set = 1;
5016       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5017         sw_if_index_set = 1;
5018       else if (unformat (i, "%U/%d",
5019                          unformat_ip4_address, &v4address, &address_length))
5020         v4_address_set = 1;
5021       else if (unformat (i, "%U/%d",
5022                          unformat_ip6_address, &v6address, &address_length))
5023         v6_address_set = 1;
5024       else
5025         break;
5026     }
5027
5028   if (sw_if_index_set == 0)
5029     {
5030       errmsg ("missing interface name or sw_if_index");
5031       return -99;
5032     }
5033   if (v4_address_set && v6_address_set)
5034     {
5035       errmsg ("both v4 and v6 addresses set");
5036       return -99;
5037     }
5038   if (!v4_address_set && !v6_address_set && !del_all)
5039     {
5040       errmsg ("no addresses set");
5041       return -99;
5042     }
5043
5044   /* Construct the API message */
5045   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
5046
5047   mp->sw_if_index = ntohl (sw_if_index);
5048   mp->is_add = is_add;
5049   mp->del_all = del_all;
5050   if (v6_address_set)
5051     {
5052       mp->is_ipv6 = 1;
5053       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5054     }
5055   else
5056     {
5057       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5058     }
5059   mp->address_length = address_length;
5060
5061   /* send it... */
5062   S;
5063
5064   /* Wait for a reply, return good/bad news  */
5065   W;
5066 }
5067
5068 static int
5069 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5070 {
5071   unformat_input_t *i = vam->input;
5072   vl_api_sw_interface_set_mpls_enable_t *mp;
5073   f64 timeout;
5074   u32 sw_if_index;
5075   u8 sw_if_index_set = 0;
5076   u8 enable = 1;
5077
5078   /* Parse args required to build the message */
5079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5080     {
5081       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5082         sw_if_index_set = 1;
5083       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5084         sw_if_index_set = 1;
5085       else if (unformat (i, "disable"))
5086         enable = 0;
5087       else if (unformat (i, "dis"))
5088         enable = 0;
5089       else
5090         break;
5091     }
5092
5093   if (sw_if_index_set == 0)
5094     {
5095       errmsg ("missing interface name or sw_if_index");
5096       return -99;
5097     }
5098
5099   /* Construct the API message */
5100   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
5101
5102   mp->sw_if_index = ntohl (sw_if_index);
5103   mp->enable = enable;
5104
5105   /* send it... */
5106   S;
5107
5108   /* Wait for a reply... */
5109   W;
5110 }
5111
5112 static int
5113 api_sw_interface_set_table (vat_main_t * vam)
5114 {
5115   unformat_input_t *i = vam->input;
5116   vl_api_sw_interface_set_table_t *mp;
5117   f64 timeout;
5118   u32 sw_if_index, vrf_id = 0;
5119   u8 sw_if_index_set = 0;
5120   u8 is_ipv6 = 0;
5121
5122   /* Parse args required to build the message */
5123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5124     {
5125       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5126         sw_if_index_set = 1;
5127       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5128         sw_if_index_set = 1;
5129       else if (unformat (i, "vrf %d", &vrf_id))
5130         ;
5131       else if (unformat (i, "ipv6"))
5132         is_ipv6 = 1;
5133       else
5134         break;
5135     }
5136
5137   if (sw_if_index_set == 0)
5138     {
5139       errmsg ("missing interface name or sw_if_index");
5140       return -99;
5141     }
5142
5143   /* Construct the API message */
5144   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
5145
5146   mp->sw_if_index = ntohl (sw_if_index);
5147   mp->is_ipv6 = is_ipv6;
5148   mp->vrf_id = ntohl (vrf_id);
5149
5150   /* send it... */
5151   S;
5152
5153   /* Wait for a reply... */
5154   W;
5155 }
5156
5157 static void vl_api_sw_interface_get_table_reply_t_handler
5158   (vl_api_sw_interface_get_table_reply_t * mp)
5159 {
5160   vat_main_t *vam = &vat_main;
5161
5162   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5163
5164   vam->retval = ntohl (mp->retval);
5165   vam->result_ready = 1;
5166
5167 }
5168
5169 static void vl_api_sw_interface_get_table_reply_t_handler_json
5170   (vl_api_sw_interface_get_table_reply_t * mp)
5171 {
5172   vat_main_t *vam = &vat_main;
5173   vat_json_node_t node;
5174
5175   vat_json_init_object (&node);
5176   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5177   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5178
5179   vat_json_print (vam->ofp, &node);
5180   vat_json_free (&node);
5181
5182   vam->retval = ntohl (mp->retval);
5183   vam->result_ready = 1;
5184 }
5185
5186 static int
5187 api_sw_interface_get_table (vat_main_t * vam)
5188 {
5189   unformat_input_t *i = vam->input;
5190   vl_api_sw_interface_get_table_t *mp;
5191   u32 sw_if_index;
5192   u8 sw_if_index_set = 0;
5193   u8 is_ipv6 = 0;
5194   f64 timeout;
5195
5196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5197     {
5198       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5199         sw_if_index_set = 1;
5200       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5201         sw_if_index_set = 1;
5202       else if (unformat (i, "ipv6"))
5203         is_ipv6 = 1;
5204       else
5205         break;
5206     }
5207
5208   if (sw_if_index_set == 0)
5209     {
5210       errmsg ("missing interface name or sw_if_index");
5211       return -99;
5212     }
5213
5214   M (SW_INTERFACE_GET_TABLE, sw_interface_get_table);
5215   mp->sw_if_index = htonl (sw_if_index);
5216   mp->is_ipv6 = is_ipv6;
5217
5218   S;
5219   W;
5220 }
5221
5222 static int
5223 api_sw_interface_set_vpath (vat_main_t * vam)
5224 {
5225   unformat_input_t *i = vam->input;
5226   vl_api_sw_interface_set_vpath_t *mp;
5227   f64 timeout;
5228   u32 sw_if_index = 0;
5229   u8 sw_if_index_set = 0;
5230   u8 is_enable = 0;
5231
5232   /* Parse args required to build the message */
5233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5234     {
5235       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5236         sw_if_index_set = 1;
5237       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5238         sw_if_index_set = 1;
5239       else if (unformat (i, "enable"))
5240         is_enable = 1;
5241       else if (unformat (i, "disable"))
5242         is_enable = 0;
5243       else
5244         break;
5245     }
5246
5247   if (sw_if_index_set == 0)
5248     {
5249       errmsg ("missing interface name or sw_if_index");
5250       return -99;
5251     }
5252
5253   /* Construct the API message */
5254   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5255
5256   mp->sw_if_index = ntohl (sw_if_index);
5257   mp->enable = is_enable;
5258
5259   /* send it... */
5260   S;
5261
5262   /* Wait for a reply... */
5263   W;
5264 }
5265
5266 static int
5267 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5268 {
5269   unformat_input_t *i = vam->input;
5270   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5271   f64 timeout;
5272   u32 sw_if_index = 0;
5273   u8 sw_if_index_set = 0;
5274   u8 is_enable = 0;
5275   u8 is_ipv6 = 0;
5276
5277   /* Parse args required to build the message */
5278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5279     {
5280       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5281         sw_if_index_set = 1;
5282       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5283         sw_if_index_set = 1;
5284       else if (unformat (i, "enable"))
5285         is_enable = 1;
5286       else if (unformat (i, "disable"))
5287         is_enable = 0;
5288       else if (unformat (i, "ip4"))
5289         is_ipv6 = 0;
5290       else if (unformat (i, "ip6"))
5291         is_ipv6 = 1;
5292       else
5293         break;
5294     }
5295
5296   if (sw_if_index_set == 0)
5297     {
5298       errmsg ("missing interface name or sw_if_index");
5299       return -99;
5300     }
5301
5302   /* Construct the API message */
5303   M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5304
5305   mp->sw_if_index = ntohl (sw_if_index);
5306   mp->enable = is_enable;
5307   mp->is_ipv6 = is_ipv6;
5308
5309   /* send it... */
5310   S;
5311
5312   /* Wait for a reply... */
5313   W;
5314 }
5315
5316 static int
5317 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5318 {
5319   unformat_input_t *i = vam->input;
5320   vl_api_sw_interface_set_l2_xconnect_t *mp;
5321   f64 timeout;
5322   u32 rx_sw_if_index;
5323   u8 rx_sw_if_index_set = 0;
5324   u32 tx_sw_if_index;
5325   u8 tx_sw_if_index_set = 0;
5326   u8 enable = 1;
5327
5328   /* Parse args required to build the message */
5329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5330     {
5331       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5332         rx_sw_if_index_set = 1;
5333       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5334         tx_sw_if_index_set = 1;
5335       else if (unformat (i, "rx"))
5336         {
5337           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5338             {
5339               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5340                             &rx_sw_if_index))
5341                 rx_sw_if_index_set = 1;
5342             }
5343           else
5344             break;
5345         }
5346       else if (unformat (i, "tx"))
5347         {
5348           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5349             {
5350               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5351                             &tx_sw_if_index))
5352                 tx_sw_if_index_set = 1;
5353             }
5354           else
5355             break;
5356         }
5357       else if (unformat (i, "enable"))
5358         enable = 1;
5359       else if (unformat (i, "disable"))
5360         enable = 0;
5361       else
5362         break;
5363     }
5364
5365   if (rx_sw_if_index_set == 0)
5366     {
5367       errmsg ("missing rx interface name or rx_sw_if_index");
5368       return -99;
5369     }
5370
5371   if (enable && (tx_sw_if_index_set == 0))
5372     {
5373       errmsg ("missing tx interface name or tx_sw_if_index");
5374       return -99;
5375     }
5376
5377   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5378
5379   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5380   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5381   mp->enable = enable;
5382
5383   S;
5384   W;
5385   /* NOTREACHED */
5386   return 0;
5387 }
5388
5389 static int
5390 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5391 {
5392   unformat_input_t *i = vam->input;
5393   vl_api_sw_interface_set_l2_bridge_t *mp;
5394   f64 timeout;
5395   u32 rx_sw_if_index;
5396   u8 rx_sw_if_index_set = 0;
5397   u32 bd_id;
5398   u8 bd_id_set = 0;
5399   u8 bvi = 0;
5400   u32 shg = 0;
5401   u8 enable = 1;
5402
5403   /* Parse args required to build the message */
5404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5405     {
5406       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5407         rx_sw_if_index_set = 1;
5408       else if (unformat (i, "bd_id %d", &bd_id))
5409         bd_id_set = 1;
5410       else
5411         if (unformat
5412             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5413         rx_sw_if_index_set = 1;
5414       else if (unformat (i, "shg %d", &shg))
5415         ;
5416       else if (unformat (i, "bvi"))
5417         bvi = 1;
5418       else if (unformat (i, "enable"))
5419         enable = 1;
5420       else if (unformat (i, "disable"))
5421         enable = 0;
5422       else
5423         break;
5424     }
5425
5426   if (rx_sw_if_index_set == 0)
5427     {
5428       errmsg ("missing rx interface name or sw_if_index");
5429       return -99;
5430     }
5431
5432   if (enable && (bd_id_set == 0))
5433     {
5434       errmsg ("missing bridge domain");
5435       return -99;
5436     }
5437
5438   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5439
5440   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5441   mp->bd_id = ntohl (bd_id);
5442   mp->shg = (u8) shg;
5443   mp->bvi = bvi;
5444   mp->enable = enable;
5445
5446   S;
5447   W;
5448   /* NOTREACHED */
5449   return 0;
5450 }
5451
5452 static int
5453 api_bridge_domain_dump (vat_main_t * vam)
5454 {
5455   unformat_input_t *i = vam->input;
5456   vl_api_bridge_domain_dump_t *mp;
5457   f64 timeout;
5458   u32 bd_id = ~0;
5459
5460   /* Parse args required to build the message */
5461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5462     {
5463       if (unformat (i, "bd_id %d", &bd_id))
5464         ;
5465       else
5466         break;
5467     }
5468
5469   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5470   mp->bd_id = ntohl (bd_id);
5471   S;
5472
5473   /* Use a control ping for synchronization */
5474   {
5475     vl_api_control_ping_t *mp;
5476     M (CONTROL_PING, control_ping);
5477     S;
5478   }
5479
5480   W;
5481   /* NOTREACHED */
5482   return 0;
5483 }
5484
5485 static int
5486 api_bridge_domain_add_del (vat_main_t * vam)
5487 {
5488   unformat_input_t *i = vam->input;
5489   vl_api_bridge_domain_add_del_t *mp;
5490   f64 timeout;
5491   u32 bd_id = ~0;
5492   u8 is_add = 1;
5493   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5494   u32 mac_age = 0;
5495
5496   /* Parse args required to build the message */
5497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5498     {
5499       if (unformat (i, "bd_id %d", &bd_id))
5500         ;
5501       else if (unformat (i, "flood %d", &flood))
5502         ;
5503       else if (unformat (i, "uu-flood %d", &uu_flood))
5504         ;
5505       else if (unformat (i, "forward %d", &forward))
5506         ;
5507       else if (unformat (i, "learn %d", &learn))
5508         ;
5509       else if (unformat (i, "arp-term %d", &arp_term))
5510         ;
5511       else if (unformat (i, "mac-age %d", &mac_age))
5512         ;
5513       else if (unformat (i, "del"))
5514         {
5515           is_add = 0;
5516           flood = uu_flood = forward = learn = 0;
5517         }
5518       else
5519         break;
5520     }
5521
5522   if (bd_id == ~0)
5523     {
5524       errmsg ("missing bridge domain");
5525       return -99;
5526     }
5527
5528   if (mac_age > 255)
5529     {
5530       errmsg ("mac age must be less than 256 ");
5531       return -99;
5532     }
5533
5534   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5535
5536   mp->bd_id = ntohl (bd_id);
5537   mp->flood = flood;
5538   mp->uu_flood = uu_flood;
5539   mp->forward = forward;
5540   mp->learn = learn;
5541   mp->arp_term = arp_term;
5542   mp->is_add = is_add;
5543   mp->mac_age = (u8) mac_age;
5544
5545   S;
5546   W;
5547   /* NOTREACHED */
5548   return 0;
5549 }
5550
5551 static int
5552 api_l2fib_add_del (vat_main_t * vam)
5553 {
5554   unformat_input_t *i = vam->input;
5555   vl_api_l2fib_add_del_t *mp;
5556   f64 timeout;
5557   u64 mac = 0;
5558   u8 mac_set = 0;
5559   u32 bd_id;
5560   u8 bd_id_set = 0;
5561   u32 sw_if_index = ~0;
5562   u8 sw_if_index_set = 0;
5563   u8 is_add = 1;
5564   u8 static_mac = 0;
5565   u8 filter_mac = 0;
5566   u8 bvi_mac = 0;
5567   int count = 1;
5568   f64 before = 0;
5569   int j;
5570
5571   /* Parse args required to build the message */
5572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5573     {
5574       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5575         mac_set = 1;
5576       else if (unformat (i, "bd_id %d", &bd_id))
5577         bd_id_set = 1;
5578       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5579         sw_if_index_set = 1;
5580       else if (unformat (i, "sw_if"))
5581         {
5582           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5583             {
5584               if (unformat
5585                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5586                 sw_if_index_set = 1;
5587             }
5588           else
5589             break;
5590         }
5591       else if (unformat (i, "static"))
5592         static_mac = 1;
5593       else if (unformat (i, "filter"))
5594         {
5595           filter_mac = 1;
5596           static_mac = 1;
5597         }
5598       else if (unformat (i, "bvi"))
5599         {
5600           bvi_mac = 1;
5601           static_mac = 1;
5602         }
5603       else if (unformat (i, "del"))
5604         is_add = 0;
5605       else if (unformat (i, "count %d", &count))
5606         ;
5607       else
5608         break;
5609     }
5610
5611   if (mac_set == 0)
5612     {
5613       errmsg ("missing mac address");
5614       return -99;
5615     }
5616
5617   if (bd_id_set == 0)
5618     {
5619       errmsg ("missing bridge domain");
5620       return -99;
5621     }
5622
5623   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5624     {
5625       errmsg ("missing interface name or sw_if_index");
5626       return -99;
5627     }
5628
5629   if (count > 1)
5630     {
5631       /* Turn on async mode */
5632       vam->async_mode = 1;
5633       vam->async_errors = 0;
5634       before = vat_time_now (vam);
5635     }
5636
5637   for (j = 0; j < count; j++)
5638     {
5639       M (L2FIB_ADD_DEL, l2fib_add_del);
5640
5641       mp->mac = mac;
5642       mp->bd_id = ntohl (bd_id);
5643       mp->is_add = is_add;
5644
5645       if (is_add)
5646         {
5647           mp->sw_if_index = ntohl (sw_if_index);
5648           mp->static_mac = static_mac;
5649           mp->filter_mac = filter_mac;
5650           mp->bvi_mac = bvi_mac;
5651         }
5652       increment_mac_address (&mac);
5653       /* send it... */
5654       S;
5655     }
5656
5657   if (count > 1)
5658     {
5659       vl_api_control_ping_t *mp;
5660       f64 after;
5661
5662       /* Shut off async mode */
5663       vam->async_mode = 0;
5664
5665       M (CONTROL_PING, control_ping);
5666       S;
5667
5668       timeout = vat_time_now (vam) + 1.0;
5669       while (vat_time_now (vam) < timeout)
5670         if (vam->result_ready == 1)
5671           goto out;
5672       vam->retval = -99;
5673
5674     out:
5675       if (vam->retval == -99)
5676         errmsg ("timeout");
5677
5678       if (vam->async_errors > 0)
5679         {
5680           errmsg ("%d asynchronous errors", vam->async_errors);
5681           vam->retval = -98;
5682         }
5683       vam->async_errors = 0;
5684       after = vat_time_now (vam);
5685
5686       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5687              count, after - before, count / (after - before));
5688     }
5689   else
5690     {
5691       /* Wait for a reply... */
5692       W;
5693     }
5694   /* Return the good/bad news */
5695   return (vam->retval);
5696 }
5697
5698 static int
5699 api_l2_flags (vat_main_t * vam)
5700 {
5701   unformat_input_t *i = vam->input;
5702   vl_api_l2_flags_t *mp;
5703   f64 timeout;
5704   u32 sw_if_index;
5705   u32 feature_bitmap = 0;
5706   u8 sw_if_index_set = 0;
5707
5708   /* Parse args required to build the message */
5709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5710     {
5711       if (unformat (i, "sw_if_index %d", &sw_if_index))
5712         sw_if_index_set = 1;
5713       else if (unformat (i, "sw_if"))
5714         {
5715           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5716             {
5717               if (unformat
5718                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5719                 sw_if_index_set = 1;
5720             }
5721           else
5722             break;
5723         }
5724       else if (unformat (i, "learn"))
5725         feature_bitmap |= L2INPUT_FEAT_LEARN;
5726       else if (unformat (i, "forward"))
5727         feature_bitmap |= L2INPUT_FEAT_FWD;
5728       else if (unformat (i, "flood"))
5729         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5730       else if (unformat (i, "uu-flood"))
5731         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5732       else
5733         break;
5734     }
5735
5736   if (sw_if_index_set == 0)
5737     {
5738       errmsg ("missing interface name or sw_if_index");
5739       return -99;
5740     }
5741
5742   M (L2_FLAGS, l2_flags);
5743
5744   mp->sw_if_index = ntohl (sw_if_index);
5745   mp->feature_bitmap = ntohl (feature_bitmap);
5746
5747   S;
5748   W;
5749   /* NOTREACHED */
5750   return 0;
5751 }
5752
5753 static int
5754 api_bridge_flags (vat_main_t * vam)
5755 {
5756   unformat_input_t *i = vam->input;
5757   vl_api_bridge_flags_t *mp;
5758   f64 timeout;
5759   u32 bd_id;
5760   u8 bd_id_set = 0;
5761   u8 is_set = 1;
5762   u32 flags = 0;
5763
5764   /* Parse args required to build the message */
5765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5766     {
5767       if (unformat (i, "bd_id %d", &bd_id))
5768         bd_id_set = 1;
5769       else if (unformat (i, "learn"))
5770         flags |= L2_LEARN;
5771       else if (unformat (i, "forward"))
5772         flags |= L2_FWD;
5773       else if (unformat (i, "flood"))
5774         flags |= L2_FLOOD;
5775       else if (unformat (i, "uu-flood"))
5776         flags |= L2_UU_FLOOD;
5777       else if (unformat (i, "arp-term"))
5778         flags |= L2_ARP_TERM;
5779       else if (unformat (i, "off"))
5780         is_set = 0;
5781       else if (unformat (i, "disable"))
5782         is_set = 0;
5783       else
5784         break;
5785     }
5786
5787   if (bd_id_set == 0)
5788     {
5789       errmsg ("missing bridge domain");
5790       return -99;
5791     }
5792
5793   M (BRIDGE_FLAGS, bridge_flags);
5794
5795   mp->bd_id = ntohl (bd_id);
5796   mp->feature_bitmap = ntohl (flags);
5797   mp->is_set = is_set;
5798
5799   S;
5800   W;
5801   /* NOTREACHED */
5802   return 0;
5803 }
5804
5805 static int
5806 api_bd_ip_mac_add_del (vat_main_t * vam)
5807 {
5808   unformat_input_t *i = vam->input;
5809   vl_api_bd_ip_mac_add_del_t *mp;
5810   f64 timeout;
5811   u32 bd_id;
5812   u8 is_ipv6 = 0;
5813   u8 is_add = 1;
5814   u8 bd_id_set = 0;
5815   u8 ip_set = 0;
5816   u8 mac_set = 0;
5817   ip4_address_t v4addr;
5818   ip6_address_t v6addr;
5819   u8 macaddr[6];
5820
5821
5822   /* Parse args required to build the message */
5823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5824     {
5825       if (unformat (i, "bd_id %d", &bd_id))
5826         {
5827           bd_id_set++;
5828         }
5829       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5830         {
5831           ip_set++;
5832         }
5833       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5834         {
5835           ip_set++;
5836           is_ipv6++;
5837         }
5838       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5839         {
5840           mac_set++;
5841         }
5842       else if (unformat (i, "del"))
5843         is_add = 0;
5844       else
5845         break;
5846     }
5847
5848   if (bd_id_set == 0)
5849     {
5850       errmsg ("missing bridge domain");
5851       return -99;
5852     }
5853   else if (ip_set == 0)
5854     {
5855       errmsg ("missing IP address");
5856       return -99;
5857     }
5858   else if (mac_set == 0)
5859     {
5860       errmsg ("missing MAC address");
5861       return -99;
5862     }
5863
5864   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5865
5866   mp->bd_id = ntohl (bd_id);
5867   mp->is_ipv6 = is_ipv6;
5868   mp->is_add = is_add;
5869   if (is_ipv6)
5870     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5871   else
5872     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5873   clib_memcpy (mp->mac_address, macaddr, 6);
5874   S;
5875   W;
5876   /* NOTREACHED */
5877   return 0;
5878 }
5879
5880 static int
5881 api_tap_connect (vat_main_t * vam)
5882 {
5883   unformat_input_t *i = vam->input;
5884   vl_api_tap_connect_t *mp;
5885   f64 timeout;
5886   u8 mac_address[6];
5887   u8 random_mac = 1;
5888   u8 name_set = 0;
5889   u8 *tap_name;
5890   u8 *tag = 0;
5891
5892   memset (mac_address, 0, sizeof (mac_address));
5893
5894   /* Parse args required to build the message */
5895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5896     {
5897       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5898         {
5899           random_mac = 0;
5900         }
5901       else if (unformat (i, "random-mac"))
5902         random_mac = 1;
5903       else if (unformat (i, "tapname %s", &tap_name))
5904         name_set = 1;
5905       else if (unformat (i, "tag %s", &tag))
5906         ;
5907       else
5908         break;
5909     }
5910
5911   if (name_set == 0)
5912     {
5913       errmsg ("missing tap name");
5914       return -99;
5915     }
5916   if (vec_len (tap_name) > 63)
5917     {
5918       errmsg ("tap name too long");
5919       return -99;
5920     }
5921   vec_add1 (tap_name, 0);
5922
5923   if (vec_len (tag) > 63)
5924     {
5925       errmsg ("tag too long");
5926       return -99;
5927     }
5928
5929   /* Construct the API message */
5930   M (TAP_CONNECT, tap_connect);
5931
5932   mp->use_random_mac = random_mac;
5933   clib_memcpy (mp->mac_address, mac_address, 6);
5934   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5935   if (tag)
5936     clib_memcpy (mp->tag, tag, vec_len (tag));
5937
5938   vec_free (tap_name);
5939   vec_free (tag);
5940
5941   /* send it... */
5942   S;
5943
5944   /* Wait for a reply... */
5945   W;
5946 }
5947
5948 static int
5949 api_tap_modify (vat_main_t * vam)
5950 {
5951   unformat_input_t *i = vam->input;
5952   vl_api_tap_modify_t *mp;
5953   f64 timeout;
5954   u8 mac_address[6];
5955   u8 random_mac = 1;
5956   u8 name_set = 0;
5957   u8 *tap_name;
5958   u32 sw_if_index = ~0;
5959   u8 sw_if_index_set = 0;
5960
5961   memset (mac_address, 0, sizeof (mac_address));
5962
5963   /* Parse args required to build the message */
5964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5965     {
5966       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5967         sw_if_index_set = 1;
5968       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5969         sw_if_index_set = 1;
5970       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5971         {
5972           random_mac = 0;
5973         }
5974       else if (unformat (i, "random-mac"))
5975         random_mac = 1;
5976       else if (unformat (i, "tapname %s", &tap_name))
5977         name_set = 1;
5978       else
5979         break;
5980     }
5981
5982   if (sw_if_index_set == 0)
5983     {
5984       errmsg ("missing vpp interface name");
5985       return -99;
5986     }
5987   if (name_set == 0)
5988     {
5989       errmsg ("missing tap name");
5990       return -99;
5991     }
5992   if (vec_len (tap_name) > 63)
5993     {
5994       errmsg ("tap name too long");
5995     }
5996   vec_add1 (tap_name, 0);
5997
5998   /* Construct the API message */
5999   M (TAP_MODIFY, tap_modify);
6000
6001   mp->use_random_mac = random_mac;
6002   mp->sw_if_index = ntohl (sw_if_index);
6003   clib_memcpy (mp->mac_address, mac_address, 6);
6004   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6005   vec_free (tap_name);
6006
6007   /* send it... */
6008   S;
6009
6010   /* Wait for a reply... */
6011   W;
6012 }
6013
6014 static int
6015 api_tap_delete (vat_main_t * vam)
6016 {
6017   unformat_input_t *i = vam->input;
6018   vl_api_tap_delete_t *mp;
6019   f64 timeout;
6020   u32 sw_if_index = ~0;
6021   u8 sw_if_index_set = 0;
6022
6023   /* Parse args required to build the message */
6024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6025     {
6026       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6027         sw_if_index_set = 1;
6028       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6029         sw_if_index_set = 1;
6030       else
6031         break;
6032     }
6033
6034   if (sw_if_index_set == 0)
6035     {
6036       errmsg ("missing vpp interface name");
6037       return -99;
6038     }
6039
6040   /* Construct the API message */
6041   M (TAP_DELETE, tap_delete);
6042
6043   mp->sw_if_index = ntohl (sw_if_index);
6044
6045   /* send it... */
6046   S;
6047
6048   /* Wait for a reply... */
6049   W;
6050 }
6051
6052 static int
6053 api_ip_add_del_route (vat_main_t * vam)
6054 {
6055   unformat_input_t *i = vam->input;
6056   vl_api_ip_add_del_route_t *mp;
6057   f64 timeout;
6058   u32 sw_if_index = ~0, vrf_id = 0;
6059   u8 is_ipv6 = 0;
6060   u8 is_local = 0, is_drop = 0;
6061   u8 is_unreach = 0, is_prohibit = 0;
6062   u8 create_vrf_if_needed = 0;
6063   u8 is_add = 1;
6064   u32 next_hop_weight = 1;
6065   u8 not_last = 0;
6066   u8 is_multipath = 0;
6067   u8 address_set = 0;
6068   u8 address_length_set = 0;
6069   u32 next_hop_table_id = 0;
6070   u32 resolve_attempts = 0;
6071   u32 dst_address_length = 0;
6072   u8 next_hop_set = 0;
6073   ip4_address_t v4_dst_address, v4_next_hop_address;
6074   ip6_address_t v6_dst_address, v6_next_hop_address;
6075   int count = 1;
6076   int j;
6077   f64 before = 0;
6078   u32 random_add_del = 0;
6079   u32 *random_vector = 0;
6080   uword *random_hash;
6081   u32 random_seed = 0xdeaddabe;
6082   u32 classify_table_index = ~0;
6083   u8 is_classify = 0;
6084   u8 resolve_host = 0, resolve_attached = 0;
6085   mpls_label_t *next_hop_out_label_stack = NULL;
6086   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6087   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6088
6089   /* Parse args required to build the message */
6090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6091     {
6092       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6093         ;
6094       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6095         ;
6096       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6097         {
6098           address_set = 1;
6099           is_ipv6 = 0;
6100         }
6101       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6102         {
6103           address_set = 1;
6104           is_ipv6 = 1;
6105         }
6106       else if (unformat (i, "/%d", &dst_address_length))
6107         {
6108           address_length_set = 1;
6109         }
6110
6111       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6112                                          &v4_next_hop_address))
6113         {
6114           next_hop_set = 1;
6115         }
6116       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6117                                          &v6_next_hop_address))
6118         {
6119           next_hop_set = 1;
6120         }
6121       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6122         ;
6123       else if (unformat (i, "weight %d", &next_hop_weight))
6124         ;
6125       else if (unformat (i, "drop"))
6126         {
6127           is_drop = 1;
6128         }
6129       else if (unformat (i, "null-send-unreach"))
6130         {
6131           is_unreach = 1;
6132         }
6133       else if (unformat (i, "null-send-prohibit"))
6134         {
6135           is_prohibit = 1;
6136         }
6137       else if (unformat (i, "local"))
6138         {
6139           is_local = 1;
6140         }
6141       else if (unformat (i, "classify %d", &classify_table_index))
6142         {
6143           is_classify = 1;
6144         }
6145       else if (unformat (i, "del"))
6146         is_add = 0;
6147       else if (unformat (i, "add"))
6148         is_add = 1;
6149       else if (unformat (i, "not-last"))
6150         not_last = 1;
6151       else if (unformat (i, "resolve-via-host"))
6152         resolve_host = 1;
6153       else if (unformat (i, "resolve-via-attached"))
6154         resolve_attached = 1;
6155       else if (unformat (i, "multipath"))
6156         is_multipath = 1;
6157       else if (unformat (i, "vrf %d", &vrf_id))
6158         ;
6159       else if (unformat (i, "create-vrf"))
6160         create_vrf_if_needed = 1;
6161       else if (unformat (i, "count %d", &count))
6162         ;
6163       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6164         ;
6165       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6166         ;
6167       else if (unformat (i, "out-label %d", &next_hop_out_label))
6168         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6169       else if (unformat (i, "via-label %d", &next_hop_via_label))
6170         ;
6171       else if (unformat (i, "random"))
6172         random_add_del = 1;
6173       else if (unformat (i, "seed %d", &random_seed))
6174         ;
6175       else
6176         {
6177           clib_warning ("parse error '%U'", format_unformat_error, i);
6178           return -99;
6179         }
6180     }
6181
6182   if (!next_hop_set && !is_drop && !is_local &&
6183       !is_classify && !is_unreach && !is_prohibit &&
6184       MPLS_LABEL_INVALID == next_hop_via_label)
6185     {
6186       errmsg
6187         ("next hop / local / drop / unreach / prohibit / classify not set");
6188       return -99;
6189     }
6190
6191   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6192     {
6193       errmsg ("next hop and next-hop via label set");
6194       return -99;
6195     }
6196   if (address_set == 0)
6197     {
6198       errmsg ("missing addresses");
6199       return -99;
6200     }
6201
6202   if (address_length_set == 0)
6203     {
6204       errmsg ("missing address length");
6205       return -99;
6206     }
6207
6208   /* Generate a pile of unique, random routes */
6209   if (random_add_del)
6210     {
6211       u32 this_random_address;
6212       random_hash = hash_create (count, sizeof (uword));
6213
6214       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6215       for (j = 0; j <= count; j++)
6216         {
6217           do
6218             {
6219               this_random_address = random_u32 (&random_seed);
6220               this_random_address =
6221                 clib_host_to_net_u32 (this_random_address);
6222             }
6223           while (hash_get (random_hash, this_random_address));
6224           vec_add1 (random_vector, this_random_address);
6225           hash_set (random_hash, this_random_address, 1);
6226         }
6227       hash_free (random_hash);
6228       v4_dst_address.as_u32 = random_vector[0];
6229     }
6230
6231   if (count > 1)
6232     {
6233       /* Turn on async mode */
6234       vam->async_mode = 1;
6235       vam->async_errors = 0;
6236       before = vat_time_now (vam);
6237     }
6238
6239   for (j = 0; j < count; j++)
6240     {
6241       /* Construct the API message */
6242       M2 (IP_ADD_DEL_ROUTE, ip_add_del_route,
6243           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6244
6245       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6246       mp->table_id = ntohl (vrf_id);
6247       mp->create_vrf_if_needed = create_vrf_if_needed;
6248
6249       mp->is_add = is_add;
6250       mp->is_drop = is_drop;
6251       mp->is_unreach = is_unreach;
6252       mp->is_prohibit = is_prohibit;
6253       mp->is_ipv6 = is_ipv6;
6254       mp->is_local = is_local;
6255       mp->is_classify = is_classify;
6256       mp->is_multipath = is_multipath;
6257       mp->is_resolve_host = resolve_host;
6258       mp->is_resolve_attached = resolve_attached;
6259       mp->not_last = not_last;
6260       mp->next_hop_weight = next_hop_weight;
6261       mp->dst_address_length = dst_address_length;
6262       mp->next_hop_table_id = ntohl (next_hop_table_id);
6263       mp->classify_table_index = ntohl (classify_table_index);
6264       mp->next_hop_via_label = ntohl (next_hop_via_label);
6265       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6266       if (0 != mp->next_hop_n_out_labels)
6267         {
6268           memcpy (mp->next_hop_out_label_stack,
6269                   next_hop_out_label_stack,
6270                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6271           vec_free (next_hop_out_label_stack);
6272         }
6273
6274       if (is_ipv6)
6275         {
6276           clib_memcpy (mp->dst_address, &v6_dst_address,
6277                        sizeof (v6_dst_address));
6278           if (next_hop_set)
6279             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6280                          sizeof (v6_next_hop_address));
6281           increment_v6_address (&v6_dst_address);
6282         }
6283       else
6284         {
6285           clib_memcpy (mp->dst_address, &v4_dst_address,
6286                        sizeof (v4_dst_address));
6287           if (next_hop_set)
6288             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6289                          sizeof (v4_next_hop_address));
6290           if (random_add_del)
6291             v4_dst_address.as_u32 = random_vector[j + 1];
6292           else
6293             increment_v4_address (&v4_dst_address);
6294         }
6295       /* send it... */
6296       S;
6297       /* If we receive SIGTERM, stop now... */
6298       if (vam->do_exit)
6299         break;
6300     }
6301
6302   /* When testing multiple add/del ops, use a control-ping to sync */
6303   if (count > 1)
6304     {
6305       vl_api_control_ping_t *mp;
6306       f64 after;
6307
6308       /* Shut off async mode */
6309       vam->async_mode = 0;
6310
6311       M (CONTROL_PING, control_ping);
6312       S;
6313
6314       timeout = vat_time_now (vam) + 1.0;
6315       while (vat_time_now (vam) < timeout)
6316         if (vam->result_ready == 1)
6317           goto out;
6318       vam->retval = -99;
6319
6320     out:
6321       if (vam->retval == -99)
6322         errmsg ("timeout");
6323
6324       if (vam->async_errors > 0)
6325         {
6326           errmsg ("%d asynchronous errors", vam->async_errors);
6327           vam->retval = -98;
6328         }
6329       vam->async_errors = 0;
6330       after = vat_time_now (vam);
6331
6332       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6333       if (j > 0)
6334         count = j;
6335
6336       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6337              count, after - before, count / (after - before));
6338     }
6339   else
6340     {
6341       /* Wait for a reply... */
6342       W;
6343     }
6344
6345   /* Return the good/bad news */
6346   return (vam->retval);
6347 }
6348
6349 static int
6350 api_mpls_route_add_del (vat_main_t * vam)
6351 {
6352   unformat_input_t *i = vam->input;
6353   vl_api_mpls_route_add_del_t *mp;
6354   f64 timeout;
6355   u32 sw_if_index = ~0, table_id = 0;
6356   u8 create_table_if_needed = 0;
6357   u8 is_add = 1;
6358   u32 next_hop_weight = 1;
6359   u8 is_multipath = 0;
6360   u32 next_hop_table_id = 0;
6361   u8 next_hop_set = 0;
6362   ip4_address_t v4_next_hop_address = {
6363     .as_u32 = 0,
6364   };
6365   ip6_address_t v6_next_hop_address = { {0} };
6366   int count = 1;
6367   int j;
6368   f64 before = 0;
6369   u32 classify_table_index = ~0;
6370   u8 is_classify = 0;
6371   u8 resolve_host = 0, resolve_attached = 0;
6372   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6373   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6374   mpls_label_t *next_hop_out_label_stack = NULL;
6375   mpls_label_t local_label = MPLS_LABEL_INVALID;
6376   u8 is_eos = 0;
6377   u8 next_hop_proto_is_ip4 = 1;
6378
6379   /* Parse args required to build the message */
6380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6381     {
6382       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6383         ;
6384       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6385         ;
6386       else if (unformat (i, "%d", &local_label))
6387         ;
6388       else if (unformat (i, "eos"))
6389         is_eos = 1;
6390       else if (unformat (i, "non-eos"))
6391         is_eos = 0;
6392       else if (unformat (i, "via %U", unformat_ip4_address,
6393                          &v4_next_hop_address))
6394         {
6395           next_hop_set = 1;
6396           next_hop_proto_is_ip4 = 1;
6397         }
6398       else if (unformat (i, "via %U", unformat_ip6_address,
6399                          &v6_next_hop_address))
6400         {
6401           next_hop_set = 1;
6402           next_hop_proto_is_ip4 = 0;
6403         }
6404       else if (unformat (i, "weight %d", &next_hop_weight))
6405         ;
6406       else if (unformat (i, "create-table"))
6407         create_table_if_needed = 1;
6408       else if (unformat (i, "classify %d", &classify_table_index))
6409         {
6410           is_classify = 1;
6411         }
6412       else if (unformat (i, "del"))
6413         is_add = 0;
6414       else if (unformat (i, "add"))
6415         is_add = 1;
6416       else if (unformat (i, "resolve-via-host"))
6417         resolve_host = 1;
6418       else if (unformat (i, "resolve-via-attached"))
6419         resolve_attached = 1;
6420       else if (unformat (i, "multipath"))
6421         is_multipath = 1;
6422       else if (unformat (i, "count %d", &count))
6423         ;
6424       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6425         {
6426           next_hop_set = 1;
6427           next_hop_proto_is_ip4 = 1;
6428         }
6429       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6430         {
6431           next_hop_set = 1;
6432           next_hop_proto_is_ip4 = 0;
6433         }
6434       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6435         ;
6436       else if (unformat (i, "via-label %d", &next_hop_via_label))
6437         ;
6438       else if (unformat (i, "out-label %d", &next_hop_out_label))
6439         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6440       else
6441         {
6442           clib_warning ("parse error '%U'", format_unformat_error, i);
6443           return -99;
6444         }
6445     }
6446
6447   if (!next_hop_set && !is_classify)
6448     {
6449       errmsg ("next hop / classify not set");
6450       return -99;
6451     }
6452
6453   if (MPLS_LABEL_INVALID == local_label)
6454     {
6455       errmsg ("missing label");
6456       return -99;
6457     }
6458
6459   if (count > 1)
6460     {
6461       /* Turn on async mode */
6462       vam->async_mode = 1;
6463       vam->async_errors = 0;
6464       before = vat_time_now (vam);
6465     }
6466
6467   for (j = 0; j < count; j++)
6468     {
6469       /* Construct the API message */
6470       M2 (MPLS_ROUTE_ADD_DEL, mpls_route_add_del,
6471           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6472
6473       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6474       mp->mr_table_id = ntohl (table_id);
6475       mp->mr_create_table_if_needed = create_table_if_needed;
6476
6477       mp->mr_is_add = is_add;
6478       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6479       mp->mr_is_classify = is_classify;
6480       mp->mr_is_multipath = is_multipath;
6481       mp->mr_is_resolve_host = resolve_host;
6482       mp->mr_is_resolve_attached = resolve_attached;
6483       mp->mr_next_hop_weight = next_hop_weight;
6484       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6485       mp->mr_classify_table_index = ntohl (classify_table_index);
6486       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6487       mp->mr_label = ntohl (local_label);
6488       mp->mr_eos = is_eos;
6489
6490       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6491       if (0 != mp->mr_next_hop_n_out_labels)
6492         {
6493           memcpy (mp->mr_next_hop_out_label_stack,
6494                   next_hop_out_label_stack,
6495                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6496           vec_free (next_hop_out_label_stack);
6497         }
6498
6499       if (next_hop_set)
6500         {
6501           if (next_hop_proto_is_ip4)
6502             {
6503               clib_memcpy (mp->mr_next_hop,
6504                            &v4_next_hop_address,
6505                            sizeof (v4_next_hop_address));
6506             }
6507           else
6508             {
6509               clib_memcpy (mp->mr_next_hop,
6510                            &v6_next_hop_address,
6511                            sizeof (v6_next_hop_address));
6512             }
6513         }
6514       local_label++;
6515
6516       /* send it... */
6517       S;
6518       /* If we receive SIGTERM, stop now... */
6519       if (vam->do_exit)
6520         break;
6521     }
6522
6523   /* When testing multiple add/del ops, use a control-ping to sync */
6524   if (count > 1)
6525     {
6526       vl_api_control_ping_t *mp;
6527       f64 after;
6528
6529       /* Shut off async mode */
6530       vam->async_mode = 0;
6531
6532       M (CONTROL_PING, control_ping);
6533       S;
6534
6535       timeout = vat_time_now (vam) + 1.0;
6536       while (vat_time_now (vam) < timeout)
6537         if (vam->result_ready == 1)
6538           goto out;
6539       vam->retval = -99;
6540
6541     out:
6542       if (vam->retval == -99)
6543         errmsg ("timeout");
6544
6545       if (vam->async_errors > 0)
6546         {
6547           errmsg ("%d asynchronous errors", vam->async_errors);
6548           vam->retval = -98;
6549         }
6550       vam->async_errors = 0;
6551       after = vat_time_now (vam);
6552
6553       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6554       if (j > 0)
6555         count = j;
6556
6557       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6558              count, after - before, count / (after - before));
6559     }
6560   else
6561     {
6562       /* Wait for a reply... */
6563       W;
6564     }
6565
6566   /* Return the good/bad news */
6567   return (vam->retval);
6568 }
6569
6570 static int
6571 api_mpls_ip_bind_unbind (vat_main_t * vam)
6572 {
6573   unformat_input_t *i = vam->input;
6574   vl_api_mpls_ip_bind_unbind_t *mp;
6575   f64 timeout;
6576   u32 ip_table_id = 0;
6577   u8 create_table_if_needed = 0;
6578   u8 is_bind = 1;
6579   u8 is_ip4 = 1;
6580   ip4_address_t v4_address;
6581   ip6_address_t v6_address;
6582   u32 address_length;
6583   u8 address_set = 0;
6584   mpls_label_t local_label = MPLS_LABEL_INVALID;
6585
6586   /* Parse args required to build the message */
6587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6588     {
6589       if (unformat (i, "%U/%d", unformat_ip4_address,
6590                     &v4_address, &address_length))
6591         {
6592           is_ip4 = 1;
6593           address_set = 1;
6594         }
6595       else if (unformat (i, "%U/%d", unformat_ip6_address,
6596                          &v6_address, &address_length))
6597         {
6598           is_ip4 = 0;
6599           address_set = 1;
6600         }
6601       else if (unformat (i, "%d", &local_label))
6602         ;
6603       else if (unformat (i, "create-table"))
6604         create_table_if_needed = 1;
6605       else if (unformat (i, "table-id %d", &ip_table_id))
6606         ;
6607       else if (unformat (i, "unbind"))
6608         is_bind = 0;
6609       else if (unformat (i, "bind"))
6610         is_bind = 1;
6611       else
6612         {
6613           clib_warning ("parse error '%U'", format_unformat_error, i);
6614           return -99;
6615         }
6616     }
6617
6618   if (!address_set)
6619     {
6620       errmsg ("IP addres not set");
6621       return -99;
6622     }
6623
6624   if (MPLS_LABEL_INVALID == local_label)
6625     {
6626       errmsg ("missing label");
6627       return -99;
6628     }
6629
6630   /* Construct the API message */
6631   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6632
6633   mp->mb_create_table_if_needed = create_table_if_needed;
6634   mp->mb_is_bind = is_bind;
6635   mp->mb_is_ip4 = is_ip4;
6636   mp->mb_ip_table_id = ntohl (ip_table_id);
6637   mp->mb_mpls_table_id = 0;
6638   mp->mb_label = ntohl (local_label);
6639   mp->mb_address_length = address_length;
6640
6641   if (is_ip4)
6642     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6643   else
6644     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6645
6646   /* send it... */
6647   S;
6648
6649   /* Wait for a reply... */
6650   W;
6651 }
6652
6653 static int
6654 api_proxy_arp_add_del (vat_main_t * vam)
6655 {
6656   unformat_input_t *i = vam->input;
6657   vl_api_proxy_arp_add_del_t *mp;
6658   f64 timeout;
6659   u32 vrf_id = 0;
6660   u8 is_add = 1;
6661   ip4_address_t lo, hi;
6662   u8 range_set = 0;
6663
6664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6665     {
6666       if (unformat (i, "vrf %d", &vrf_id))
6667         ;
6668       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6669                          unformat_ip4_address, &hi))
6670         range_set = 1;
6671       else if (unformat (i, "del"))
6672         is_add = 0;
6673       else
6674         {
6675           clib_warning ("parse error '%U'", format_unformat_error, i);
6676           return -99;
6677         }
6678     }
6679
6680   if (range_set == 0)
6681     {
6682       errmsg ("address range not set");
6683       return -99;
6684     }
6685
6686   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6687
6688   mp->vrf_id = ntohl (vrf_id);
6689   mp->is_add = is_add;
6690   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6691   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6692
6693   S;
6694   W;
6695   /* NOTREACHED */
6696   return 0;
6697 }
6698
6699 static int
6700 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6701 {
6702   unformat_input_t *i = vam->input;
6703   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6704   f64 timeout;
6705   u32 sw_if_index;
6706   u8 enable = 1;
6707   u8 sw_if_index_set = 0;
6708
6709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6710     {
6711       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6712         sw_if_index_set = 1;
6713       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6714         sw_if_index_set = 1;
6715       else if (unformat (i, "enable"))
6716         enable = 1;
6717       else if (unformat (i, "disable"))
6718         enable = 0;
6719       else
6720         {
6721           clib_warning ("parse error '%U'", format_unformat_error, i);
6722           return -99;
6723         }
6724     }
6725
6726   if (sw_if_index_set == 0)
6727     {
6728       errmsg ("missing interface name or sw_if_index");
6729       return -99;
6730     }
6731
6732   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6733
6734   mp->sw_if_index = ntohl (sw_if_index);
6735   mp->enable_disable = enable;
6736
6737   S;
6738   W;
6739   /* NOTREACHED */
6740   return 0;
6741 }
6742
6743 static int
6744 api_mpls_tunnel_add_del (vat_main_t * vam)
6745 {
6746   unformat_input_t *i = vam->input;
6747   vl_api_mpls_tunnel_add_del_t *mp;
6748   f64 timeout;
6749
6750   u8 is_add = 1;
6751   u8 l2_only = 0;
6752   u32 sw_if_index = ~0;
6753   u32 next_hop_sw_if_index = ~0;
6754   u32 next_hop_proto_is_ip4 = 1;
6755
6756   u32 next_hop_table_id = 0;
6757   ip4_address_t v4_next_hop_address = {
6758     .as_u32 = 0,
6759   };
6760   ip6_address_t v6_next_hop_address = { {0} };
6761   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
6762
6763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6764     {
6765       if (unformat (i, "add"))
6766         is_add = 1;
6767       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6768         is_add = 0;
6769       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
6770         ;
6771       else if (unformat (i, "via %U",
6772                          unformat_ip4_address, &v4_next_hop_address))
6773         {
6774           next_hop_proto_is_ip4 = 1;
6775         }
6776       else if (unformat (i, "via %U",
6777                          unformat_ip6_address, &v6_next_hop_address))
6778         {
6779           next_hop_proto_is_ip4 = 0;
6780         }
6781       else if (unformat (i, "l2-only"))
6782         l2_only = 1;
6783       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6784         ;
6785       else if (unformat (i, "out-label %d", &next_hop_out_label))
6786         vec_add1 (labels, ntohl (next_hop_out_label));
6787       else
6788         {
6789           clib_warning ("parse error '%U'", format_unformat_error, i);
6790           return -99;
6791         }
6792     }
6793
6794   M2 (MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del,
6795       sizeof (mpls_label_t) * vec_len (labels));
6796
6797   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
6798   mp->mt_sw_if_index = ntohl (sw_if_index);
6799   mp->mt_is_add = is_add;
6800   mp->mt_l2_only = l2_only;
6801   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
6802   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6803
6804   mp->mt_next_hop_n_out_labels = vec_len (labels);
6805
6806   if (0 != mp->mt_next_hop_n_out_labels)
6807     {
6808       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
6809                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
6810       vec_free (labels);
6811     }
6812
6813   if (next_hop_proto_is_ip4)
6814     {
6815       clib_memcpy (mp->mt_next_hop,
6816                    &v4_next_hop_address, sizeof (v4_next_hop_address));
6817     }
6818   else
6819     {
6820       clib_memcpy (mp->mt_next_hop,
6821                    &v6_next_hop_address, sizeof (v6_next_hop_address));
6822     }
6823
6824   S;
6825   W;
6826   /* NOTREACHED */
6827   return 0;
6828 }
6829
6830 static int
6831 api_sw_interface_set_unnumbered (vat_main_t * vam)
6832 {
6833   unformat_input_t *i = vam->input;
6834   vl_api_sw_interface_set_unnumbered_t *mp;
6835   f64 timeout;
6836   u32 sw_if_index;
6837   u32 unnum_sw_index = ~0;
6838   u8 is_add = 1;
6839   u8 sw_if_index_set = 0;
6840
6841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6842     {
6843       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6844         sw_if_index_set = 1;
6845       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6846         sw_if_index_set = 1;
6847       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6848         ;
6849       else if (unformat (i, "del"))
6850         is_add = 0;
6851       else
6852         {
6853           clib_warning ("parse error '%U'", format_unformat_error, i);
6854           return -99;
6855         }
6856     }
6857
6858   if (sw_if_index_set == 0)
6859     {
6860       errmsg ("missing interface name or sw_if_index");
6861       return -99;
6862     }
6863
6864   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6865
6866   mp->sw_if_index = ntohl (sw_if_index);
6867   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6868   mp->is_add = is_add;
6869
6870   S;
6871   W;
6872   /* NOTREACHED */
6873   return 0;
6874 }
6875
6876 static int
6877 api_ip_neighbor_add_del (vat_main_t * vam)
6878 {
6879   unformat_input_t *i = vam->input;
6880   vl_api_ip_neighbor_add_del_t *mp;
6881   f64 timeout;
6882   u32 sw_if_index;
6883   u8 sw_if_index_set = 0;
6884   u32 vrf_id = 0;
6885   u8 is_add = 1;
6886   u8 is_static = 0;
6887   u8 mac_address[6];
6888   u8 mac_set = 0;
6889   u8 v4_address_set = 0;
6890   u8 v6_address_set = 0;
6891   ip4_address_t v4address;
6892   ip6_address_t v6address;
6893
6894   memset (mac_address, 0, sizeof (mac_address));
6895
6896   /* Parse args required to build the message */
6897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6898     {
6899       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6900         {
6901           mac_set = 1;
6902         }
6903       else if (unformat (i, "del"))
6904         is_add = 0;
6905       else
6906         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6907         sw_if_index_set = 1;
6908       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6909         sw_if_index_set = 1;
6910       else if (unformat (i, "is_static"))
6911         is_static = 1;
6912       else if (unformat (i, "vrf %d", &vrf_id))
6913         ;
6914       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6915         v4_address_set = 1;
6916       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6917         v6_address_set = 1;
6918       else
6919         {
6920           clib_warning ("parse error '%U'", format_unformat_error, i);
6921           return -99;
6922         }
6923     }
6924
6925   if (sw_if_index_set == 0)
6926     {
6927       errmsg ("missing interface name or sw_if_index");
6928       return -99;
6929     }
6930   if (v4_address_set && v6_address_set)
6931     {
6932       errmsg ("both v4 and v6 addresses set");
6933       return -99;
6934     }
6935   if (!v4_address_set && !v6_address_set)
6936     {
6937       errmsg ("no address set");
6938       return -99;
6939     }
6940
6941   /* Construct the API message */
6942   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6943
6944   mp->sw_if_index = ntohl (sw_if_index);
6945   mp->is_add = is_add;
6946   mp->vrf_id = ntohl (vrf_id);
6947   mp->is_static = is_static;
6948   if (mac_set)
6949     clib_memcpy (mp->mac_address, mac_address, 6);
6950   if (v6_address_set)
6951     {
6952       mp->is_ipv6 = 1;
6953       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6954     }
6955   else
6956     {
6957       /* mp->is_ipv6 = 0; via memset in M macro above */
6958       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6959     }
6960
6961   /* send it... */
6962   S;
6963
6964   /* Wait for a reply, return good/bad news  */
6965   W;
6966
6967   /* NOTREACHED */
6968   return 0;
6969 }
6970
6971 static int
6972 api_reset_vrf (vat_main_t * vam)
6973 {
6974   unformat_input_t *i = vam->input;
6975   vl_api_reset_vrf_t *mp;
6976   f64 timeout;
6977   u32 vrf_id = 0;
6978   u8 is_ipv6 = 0;
6979   u8 vrf_id_set = 0;
6980
6981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6982     {
6983       if (unformat (i, "vrf %d", &vrf_id))
6984         vrf_id_set = 1;
6985       else if (unformat (i, "ipv6"))
6986         is_ipv6 = 1;
6987       else
6988         {
6989           clib_warning ("parse error '%U'", format_unformat_error, i);
6990           return -99;
6991         }
6992     }
6993
6994   if (vrf_id_set == 0)
6995     {
6996       errmsg ("missing vrf id");
6997       return -99;
6998     }
6999
7000   M (RESET_VRF, reset_vrf);
7001
7002   mp->vrf_id = ntohl (vrf_id);
7003   mp->is_ipv6 = is_ipv6;
7004
7005   S;
7006   W;
7007   /* NOTREACHED */
7008   return 0;
7009 }
7010
7011 static int
7012 api_create_vlan_subif (vat_main_t * vam)
7013 {
7014   unformat_input_t *i = vam->input;
7015   vl_api_create_vlan_subif_t *mp;
7016   f64 timeout;
7017   u32 sw_if_index;
7018   u8 sw_if_index_set = 0;
7019   u32 vlan_id;
7020   u8 vlan_id_set = 0;
7021
7022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7023     {
7024       if (unformat (i, "sw_if_index %d", &sw_if_index))
7025         sw_if_index_set = 1;
7026       else
7027         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7028         sw_if_index_set = 1;
7029       else if (unformat (i, "vlan %d", &vlan_id))
7030         vlan_id_set = 1;
7031       else
7032         {
7033           clib_warning ("parse error '%U'", format_unformat_error, i);
7034           return -99;
7035         }
7036     }
7037
7038   if (sw_if_index_set == 0)
7039     {
7040       errmsg ("missing interface name or sw_if_index");
7041       return -99;
7042     }
7043
7044   if (vlan_id_set == 0)
7045     {
7046       errmsg ("missing vlan_id");
7047       return -99;
7048     }
7049   M (CREATE_VLAN_SUBIF, create_vlan_subif);
7050
7051   mp->sw_if_index = ntohl (sw_if_index);
7052   mp->vlan_id = ntohl (vlan_id);
7053
7054   S;
7055   W;
7056   /* NOTREACHED */
7057   return 0;
7058 }
7059
7060 #define foreach_create_subif_bit                \
7061 _(no_tags)                                      \
7062 _(one_tag)                                      \
7063 _(two_tags)                                     \
7064 _(dot1ad)                                       \
7065 _(exact_match)                                  \
7066 _(default_sub)                                  \
7067 _(outer_vlan_id_any)                            \
7068 _(inner_vlan_id_any)
7069
7070 static int
7071 api_create_subif (vat_main_t * vam)
7072 {
7073   unformat_input_t *i = vam->input;
7074   vl_api_create_subif_t *mp;
7075   f64 timeout;
7076   u32 sw_if_index;
7077   u8 sw_if_index_set = 0;
7078   u32 sub_id;
7079   u8 sub_id_set = 0;
7080   u32 no_tags = 0;
7081   u32 one_tag = 0;
7082   u32 two_tags = 0;
7083   u32 dot1ad = 0;
7084   u32 exact_match = 0;
7085   u32 default_sub = 0;
7086   u32 outer_vlan_id_any = 0;
7087   u32 inner_vlan_id_any = 0;
7088   u32 tmp;
7089   u16 outer_vlan_id = 0;
7090   u16 inner_vlan_id = 0;
7091
7092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7093     {
7094       if (unformat (i, "sw_if_index %d", &sw_if_index))
7095         sw_if_index_set = 1;
7096       else
7097         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7098         sw_if_index_set = 1;
7099       else if (unformat (i, "sub_id %d", &sub_id))
7100         sub_id_set = 1;
7101       else if (unformat (i, "outer_vlan_id %d", &tmp))
7102         outer_vlan_id = tmp;
7103       else if (unformat (i, "inner_vlan_id %d", &tmp))
7104         inner_vlan_id = tmp;
7105
7106 #define _(a) else if (unformat (i, #a)) a = 1 ;
7107       foreach_create_subif_bit
7108 #undef _
7109         else
7110         {
7111           clib_warning ("parse error '%U'", format_unformat_error, i);
7112           return -99;
7113         }
7114     }
7115
7116   if (sw_if_index_set == 0)
7117     {
7118       errmsg ("missing interface name or sw_if_index");
7119       return -99;
7120     }
7121
7122   if (sub_id_set == 0)
7123     {
7124       errmsg ("missing sub_id");
7125       return -99;
7126     }
7127   M (CREATE_SUBIF, create_subif);
7128
7129   mp->sw_if_index = ntohl (sw_if_index);
7130   mp->sub_id = ntohl (sub_id);
7131
7132 #define _(a) mp->a = a;
7133   foreach_create_subif_bit;
7134 #undef _
7135
7136   mp->outer_vlan_id = ntohs (outer_vlan_id);
7137   mp->inner_vlan_id = ntohs (inner_vlan_id);
7138
7139   S;
7140   W;
7141   /* NOTREACHED */
7142   return 0;
7143 }
7144
7145 static int
7146 api_oam_add_del (vat_main_t * vam)
7147 {
7148   unformat_input_t *i = vam->input;
7149   vl_api_oam_add_del_t *mp;
7150   f64 timeout;
7151   u32 vrf_id = 0;
7152   u8 is_add = 1;
7153   ip4_address_t src, dst;
7154   u8 src_set = 0;
7155   u8 dst_set = 0;
7156
7157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7158     {
7159       if (unformat (i, "vrf %d", &vrf_id))
7160         ;
7161       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7162         src_set = 1;
7163       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7164         dst_set = 1;
7165       else if (unformat (i, "del"))
7166         is_add = 0;
7167       else
7168         {
7169           clib_warning ("parse error '%U'", format_unformat_error, i);
7170           return -99;
7171         }
7172     }
7173
7174   if (src_set == 0)
7175     {
7176       errmsg ("missing src addr");
7177       return -99;
7178     }
7179
7180   if (dst_set == 0)
7181     {
7182       errmsg ("missing dst addr");
7183       return -99;
7184     }
7185
7186   M (OAM_ADD_DEL, oam_add_del);
7187
7188   mp->vrf_id = ntohl (vrf_id);
7189   mp->is_add = is_add;
7190   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7191   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7192
7193   S;
7194   W;
7195   /* NOTREACHED */
7196   return 0;
7197 }
7198
7199 static int
7200 api_reset_fib (vat_main_t * vam)
7201 {
7202   unformat_input_t *i = vam->input;
7203   vl_api_reset_fib_t *mp;
7204   f64 timeout;
7205   u32 vrf_id = 0;
7206   u8 is_ipv6 = 0;
7207   u8 vrf_id_set = 0;
7208
7209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7210     {
7211       if (unformat (i, "vrf %d", &vrf_id))
7212         vrf_id_set = 1;
7213       else if (unformat (i, "ipv6"))
7214         is_ipv6 = 1;
7215       else
7216         {
7217           clib_warning ("parse error '%U'", format_unformat_error, i);
7218           return -99;
7219         }
7220     }
7221
7222   if (vrf_id_set == 0)
7223     {
7224       errmsg ("missing vrf id");
7225       return -99;
7226     }
7227
7228   M (RESET_FIB, reset_fib);
7229
7230   mp->vrf_id = ntohl (vrf_id);
7231   mp->is_ipv6 = is_ipv6;
7232
7233   S;
7234   W;
7235   /* NOTREACHED */
7236   return 0;
7237 }
7238
7239 static int
7240 api_dhcp_proxy_config (vat_main_t * vam)
7241 {
7242   unformat_input_t *i = vam->input;
7243   vl_api_dhcp_proxy_config_t *mp;
7244   f64 timeout;
7245   u32 vrf_id = 0;
7246   u8 is_add = 1;
7247   u8 insert_cid = 1;
7248   u8 v4_address_set = 0;
7249   u8 v6_address_set = 0;
7250   ip4_address_t v4address;
7251   ip6_address_t v6address;
7252   u8 v4_src_address_set = 0;
7253   u8 v6_src_address_set = 0;
7254   ip4_address_t v4srcaddress;
7255   ip6_address_t v6srcaddress;
7256
7257   /* Parse args required to build the message */
7258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7259     {
7260       if (unformat (i, "del"))
7261         is_add = 0;
7262       else if (unformat (i, "vrf %d", &vrf_id))
7263         ;
7264       else if (unformat (i, "insert-cid %d", &insert_cid))
7265         ;
7266       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7267         v4_address_set = 1;
7268       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7269         v6_address_set = 1;
7270       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7271         v4_src_address_set = 1;
7272       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7273         v6_src_address_set = 1;
7274       else
7275         break;
7276     }
7277
7278   if (v4_address_set && v6_address_set)
7279     {
7280       errmsg ("both v4 and v6 server addresses set");
7281       return -99;
7282     }
7283   if (!v4_address_set && !v6_address_set)
7284     {
7285       errmsg ("no server addresses set");
7286       return -99;
7287     }
7288
7289   if (v4_src_address_set && v6_src_address_set)
7290     {
7291       errmsg ("both v4 and v6  src addresses set");
7292       return -99;
7293     }
7294   if (!v4_src_address_set && !v6_src_address_set)
7295     {
7296       errmsg ("no src addresses set");
7297       return -99;
7298     }
7299
7300   if (!(v4_src_address_set && v4_address_set) &&
7301       !(v6_src_address_set && v6_address_set))
7302     {
7303       errmsg ("no matching server and src addresses set");
7304       return -99;
7305     }
7306
7307   /* Construct the API message */
7308   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7309
7310   mp->insert_circuit_id = insert_cid;
7311   mp->is_add = is_add;
7312   mp->vrf_id = ntohl (vrf_id);
7313   if (v6_address_set)
7314     {
7315       mp->is_ipv6 = 1;
7316       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7317       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7318     }
7319   else
7320     {
7321       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7322       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7323     }
7324
7325   /* send it... */
7326   S;
7327
7328   /* Wait for a reply, return good/bad news  */
7329   W;
7330   /* NOTREACHED */
7331   return 0;
7332 }
7333
7334 static int
7335 api_dhcp_proxy_config_2 (vat_main_t * vam)
7336 {
7337   unformat_input_t *i = vam->input;
7338   vl_api_dhcp_proxy_config_2_t *mp;
7339   f64 timeout;
7340   u32 rx_vrf_id = 0;
7341   u32 server_vrf_id = 0;
7342   u8 is_add = 1;
7343   u8 insert_cid = 1;
7344   u8 v4_address_set = 0;
7345   u8 v6_address_set = 0;
7346   ip4_address_t v4address;
7347   ip6_address_t v6address;
7348   u8 v4_src_address_set = 0;
7349   u8 v6_src_address_set = 0;
7350   ip4_address_t v4srcaddress;
7351   ip6_address_t v6srcaddress;
7352
7353   /* Parse args required to build the message */
7354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7355     {
7356       if (unformat (i, "del"))
7357         is_add = 0;
7358       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7359         ;
7360       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7361         ;
7362       else if (unformat (i, "insert-cid %d", &insert_cid))
7363         ;
7364       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7365         v4_address_set = 1;
7366       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7367         v6_address_set = 1;
7368       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7369         v4_src_address_set = 1;
7370       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7371         v6_src_address_set = 1;
7372       else
7373         break;
7374     }
7375
7376   if (v4_address_set && v6_address_set)
7377     {
7378       errmsg ("both v4 and v6 server addresses set");
7379       return -99;
7380     }
7381   if (!v4_address_set && !v6_address_set)
7382     {
7383       errmsg ("no server addresses set");
7384       return -99;
7385     }
7386
7387   if (v4_src_address_set && v6_src_address_set)
7388     {
7389       errmsg ("both v4 and v6  src addresses set");
7390       return -99;
7391     }
7392   if (!v4_src_address_set && !v6_src_address_set)
7393     {
7394       errmsg ("no src addresses set");
7395       return -99;
7396     }
7397
7398   if (!(v4_src_address_set && v4_address_set) &&
7399       !(v6_src_address_set && v6_address_set))
7400     {
7401       errmsg ("no matching server and src addresses set");
7402       return -99;
7403     }
7404
7405   /* Construct the API message */
7406   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7407
7408   mp->insert_circuit_id = insert_cid;
7409   mp->is_add = is_add;
7410   mp->rx_vrf_id = ntohl (rx_vrf_id);
7411   mp->server_vrf_id = ntohl (server_vrf_id);
7412   if (v6_address_set)
7413     {
7414       mp->is_ipv6 = 1;
7415       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7416       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7417     }
7418   else
7419     {
7420       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7421       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7422     }
7423
7424   /* send it... */
7425   S;
7426
7427   /* Wait for a reply, return good/bad news  */
7428   W;
7429   /* NOTREACHED */
7430   return 0;
7431 }
7432
7433 static int
7434 api_dhcp_proxy_set_vss (vat_main_t * vam)
7435 {
7436   unformat_input_t *i = vam->input;
7437   vl_api_dhcp_proxy_set_vss_t *mp;
7438   f64 timeout;
7439   u8 is_ipv6 = 0;
7440   u8 is_add = 1;
7441   u32 tbl_id;
7442   u8 tbl_id_set = 0;
7443   u32 oui;
7444   u8 oui_set = 0;
7445   u32 fib_id;
7446   u8 fib_id_set = 0;
7447
7448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7449     {
7450       if (unformat (i, "tbl_id %d", &tbl_id))
7451         tbl_id_set = 1;
7452       if (unformat (i, "fib_id %d", &fib_id))
7453         fib_id_set = 1;
7454       if (unformat (i, "oui %d", &oui))
7455         oui_set = 1;
7456       else if (unformat (i, "ipv6"))
7457         is_ipv6 = 1;
7458       else if (unformat (i, "del"))
7459         is_add = 0;
7460       else
7461         {
7462           clib_warning ("parse error '%U'", format_unformat_error, i);
7463           return -99;
7464         }
7465     }
7466
7467   if (tbl_id_set == 0)
7468     {
7469       errmsg ("missing tbl id");
7470       return -99;
7471     }
7472
7473   if (fib_id_set == 0)
7474     {
7475       errmsg ("missing fib id");
7476       return -99;
7477     }
7478   if (oui_set == 0)
7479     {
7480       errmsg ("missing oui");
7481       return -99;
7482     }
7483
7484   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7485   mp->tbl_id = ntohl (tbl_id);
7486   mp->fib_id = ntohl (fib_id);
7487   mp->oui = ntohl (oui);
7488   mp->is_ipv6 = is_ipv6;
7489   mp->is_add = is_add;
7490
7491   S;
7492   W;
7493   /* NOTREACHED */
7494   return 0;
7495 }
7496
7497 static int
7498 api_dhcp_client_config (vat_main_t * vam)
7499 {
7500   unformat_input_t *i = vam->input;
7501   vl_api_dhcp_client_config_t *mp;
7502   f64 timeout;
7503   u32 sw_if_index;
7504   u8 sw_if_index_set = 0;
7505   u8 is_add = 1;
7506   u8 *hostname = 0;
7507   u8 disable_event = 0;
7508
7509   /* Parse args required to build the message */
7510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7511     {
7512       if (unformat (i, "del"))
7513         is_add = 0;
7514       else
7515         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7516         sw_if_index_set = 1;
7517       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7518         sw_if_index_set = 1;
7519       else if (unformat (i, "hostname %s", &hostname))
7520         ;
7521       else if (unformat (i, "disable_event"))
7522         disable_event = 1;
7523       else
7524         break;
7525     }
7526
7527   if (sw_if_index_set == 0)
7528     {
7529       errmsg ("missing interface name or sw_if_index");
7530       return -99;
7531     }
7532
7533   if (vec_len (hostname) > 63)
7534     {
7535       errmsg ("hostname too long");
7536     }
7537   vec_add1 (hostname, 0);
7538
7539   /* Construct the API message */
7540   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7541
7542   mp->sw_if_index = ntohl (sw_if_index);
7543   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7544   vec_free (hostname);
7545   mp->is_add = is_add;
7546   mp->want_dhcp_event = disable_event ? 0 : 1;
7547   mp->pid = getpid ();
7548
7549   /* send it... */
7550   S;
7551
7552   /* Wait for a reply, return good/bad news  */
7553   W;
7554   /* NOTREACHED */
7555   return 0;
7556 }
7557
7558 static int
7559 api_set_ip_flow_hash (vat_main_t * vam)
7560 {
7561   unformat_input_t *i = vam->input;
7562   vl_api_set_ip_flow_hash_t *mp;
7563   f64 timeout;
7564   u32 vrf_id = 0;
7565   u8 is_ipv6 = 0;
7566   u8 vrf_id_set = 0;
7567   u8 src = 0;
7568   u8 dst = 0;
7569   u8 sport = 0;
7570   u8 dport = 0;
7571   u8 proto = 0;
7572   u8 reverse = 0;
7573
7574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7575     {
7576       if (unformat (i, "vrf %d", &vrf_id))
7577         vrf_id_set = 1;
7578       else if (unformat (i, "ipv6"))
7579         is_ipv6 = 1;
7580       else if (unformat (i, "src"))
7581         src = 1;
7582       else if (unformat (i, "dst"))
7583         dst = 1;
7584       else if (unformat (i, "sport"))
7585         sport = 1;
7586       else if (unformat (i, "dport"))
7587         dport = 1;
7588       else if (unformat (i, "proto"))
7589         proto = 1;
7590       else if (unformat (i, "reverse"))
7591         reverse = 1;
7592
7593       else
7594         {
7595           clib_warning ("parse error '%U'", format_unformat_error, i);
7596           return -99;
7597         }
7598     }
7599
7600   if (vrf_id_set == 0)
7601     {
7602       errmsg ("missing vrf id");
7603       return -99;
7604     }
7605
7606   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7607   mp->src = src;
7608   mp->dst = dst;
7609   mp->sport = sport;
7610   mp->dport = dport;
7611   mp->proto = proto;
7612   mp->reverse = reverse;
7613   mp->vrf_id = ntohl (vrf_id);
7614   mp->is_ipv6 = is_ipv6;
7615
7616   S;
7617   W;
7618   /* NOTREACHED */
7619   return 0;
7620 }
7621
7622 static int
7623 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7624 {
7625   unformat_input_t *i = vam->input;
7626   vl_api_sw_interface_ip6_enable_disable_t *mp;
7627   f64 timeout;
7628   u32 sw_if_index;
7629   u8 sw_if_index_set = 0;
7630   u8 enable = 0;
7631
7632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7633     {
7634       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7635         sw_if_index_set = 1;
7636       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7637         sw_if_index_set = 1;
7638       else if (unformat (i, "enable"))
7639         enable = 1;
7640       else if (unformat (i, "disable"))
7641         enable = 0;
7642       else
7643         {
7644           clib_warning ("parse error '%U'", format_unformat_error, i);
7645           return -99;
7646         }
7647     }
7648
7649   if (sw_if_index_set == 0)
7650     {
7651       errmsg ("missing interface name or sw_if_index");
7652       return -99;
7653     }
7654
7655   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7656
7657   mp->sw_if_index = ntohl (sw_if_index);
7658   mp->enable = enable;
7659
7660   S;
7661   W;
7662   /* NOTREACHED */
7663   return 0;
7664 }
7665
7666 static int
7667 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7668 {
7669   unformat_input_t *i = vam->input;
7670   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7671   f64 timeout;
7672   u32 sw_if_index;
7673   u8 sw_if_index_set = 0;
7674   u32 address_length = 0;
7675   u8 v6_address_set = 0;
7676   ip6_address_t v6address;
7677
7678   /* Parse args required to build the message */
7679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7680     {
7681       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7682         sw_if_index_set = 1;
7683       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7684         sw_if_index_set = 1;
7685       else if (unformat (i, "%U/%d",
7686                          unformat_ip6_address, &v6address, &address_length))
7687         v6_address_set = 1;
7688       else
7689         break;
7690     }
7691
7692   if (sw_if_index_set == 0)
7693     {
7694       errmsg ("missing interface name or sw_if_index");
7695       return -99;
7696     }
7697   if (!v6_address_set)
7698     {
7699       errmsg ("no address set");
7700       return -99;
7701     }
7702
7703   /* Construct the API message */
7704   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7705      sw_interface_ip6_set_link_local_address);
7706
7707   mp->sw_if_index = ntohl (sw_if_index);
7708   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7709   mp->address_length = address_length;
7710
7711   /* send it... */
7712   S;
7713
7714   /* Wait for a reply, return good/bad news  */
7715   W;
7716
7717   /* NOTREACHED */
7718   return 0;
7719 }
7720
7721
7722 static int
7723 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7724 {
7725   unformat_input_t *i = vam->input;
7726   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7727   f64 timeout;
7728   u32 sw_if_index;
7729   u8 sw_if_index_set = 0;
7730   u32 address_length = 0;
7731   u8 v6_address_set = 0;
7732   ip6_address_t v6address;
7733   u8 use_default = 0;
7734   u8 no_advertise = 0;
7735   u8 off_link = 0;
7736   u8 no_autoconfig = 0;
7737   u8 no_onlink = 0;
7738   u8 is_no = 0;
7739   u32 val_lifetime = 0;
7740   u32 pref_lifetime = 0;
7741
7742   /* Parse args required to build the message */
7743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7744     {
7745       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7746         sw_if_index_set = 1;
7747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7748         sw_if_index_set = 1;
7749       else if (unformat (i, "%U/%d",
7750                          unformat_ip6_address, &v6address, &address_length))
7751         v6_address_set = 1;
7752       else if (unformat (i, "val_life %d", &val_lifetime))
7753         ;
7754       else if (unformat (i, "pref_life %d", &pref_lifetime))
7755         ;
7756       else if (unformat (i, "def"))
7757         use_default = 1;
7758       else if (unformat (i, "noadv"))
7759         no_advertise = 1;
7760       else if (unformat (i, "offl"))
7761         off_link = 1;
7762       else if (unformat (i, "noauto"))
7763         no_autoconfig = 1;
7764       else if (unformat (i, "nolink"))
7765         no_onlink = 1;
7766       else if (unformat (i, "isno"))
7767         is_no = 1;
7768       else
7769         {
7770           clib_warning ("parse error '%U'", format_unformat_error, i);
7771           return -99;
7772         }
7773     }
7774
7775   if (sw_if_index_set == 0)
7776     {
7777       errmsg ("missing interface name or sw_if_index");
7778       return -99;
7779     }
7780   if (!v6_address_set)
7781     {
7782       errmsg ("no address set");
7783       return -99;
7784     }
7785
7786   /* Construct the API message */
7787   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7788
7789   mp->sw_if_index = ntohl (sw_if_index);
7790   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7791   mp->address_length = address_length;
7792   mp->use_default = use_default;
7793   mp->no_advertise = no_advertise;
7794   mp->off_link = off_link;
7795   mp->no_autoconfig = no_autoconfig;
7796   mp->no_onlink = no_onlink;
7797   mp->is_no = is_no;
7798   mp->val_lifetime = ntohl (val_lifetime);
7799   mp->pref_lifetime = ntohl (pref_lifetime);
7800
7801   /* send it... */
7802   S;
7803
7804   /* Wait for a reply, return good/bad news  */
7805   W;
7806
7807   /* NOTREACHED */
7808   return 0;
7809 }
7810
7811 static int
7812 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7813 {
7814   unformat_input_t *i = vam->input;
7815   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7816   f64 timeout;
7817   u32 sw_if_index;
7818   u8 sw_if_index_set = 0;
7819   u8 suppress = 0;
7820   u8 managed = 0;
7821   u8 other = 0;
7822   u8 ll_option = 0;
7823   u8 send_unicast = 0;
7824   u8 cease = 0;
7825   u8 is_no = 0;
7826   u8 default_router = 0;
7827   u32 max_interval = 0;
7828   u32 min_interval = 0;
7829   u32 lifetime = 0;
7830   u32 initial_count = 0;
7831   u32 initial_interval = 0;
7832
7833
7834   /* Parse args required to build the message */
7835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7836     {
7837       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7838         sw_if_index_set = 1;
7839       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7840         sw_if_index_set = 1;
7841       else if (unformat (i, "maxint %d", &max_interval))
7842         ;
7843       else if (unformat (i, "minint %d", &min_interval))
7844         ;
7845       else if (unformat (i, "life %d", &lifetime))
7846         ;
7847       else if (unformat (i, "count %d", &initial_count))
7848         ;
7849       else if (unformat (i, "interval %d", &initial_interval))
7850         ;
7851       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7852         suppress = 1;
7853       else if (unformat (i, "managed"))
7854         managed = 1;
7855       else if (unformat (i, "other"))
7856         other = 1;
7857       else if (unformat (i, "ll"))
7858         ll_option = 1;
7859       else if (unformat (i, "send"))
7860         send_unicast = 1;
7861       else if (unformat (i, "cease"))
7862         cease = 1;
7863       else if (unformat (i, "isno"))
7864         is_no = 1;
7865       else if (unformat (i, "def"))
7866         default_router = 1;
7867       else
7868         {
7869           clib_warning ("parse error '%U'", format_unformat_error, i);
7870           return -99;
7871         }
7872     }
7873
7874   if (sw_if_index_set == 0)
7875     {
7876       errmsg ("missing interface name or sw_if_index");
7877       return -99;
7878     }
7879
7880   /* Construct the API message */
7881   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7882
7883   mp->sw_if_index = ntohl (sw_if_index);
7884   mp->max_interval = ntohl (max_interval);
7885   mp->min_interval = ntohl (min_interval);
7886   mp->lifetime = ntohl (lifetime);
7887   mp->initial_count = ntohl (initial_count);
7888   mp->initial_interval = ntohl (initial_interval);
7889   mp->suppress = suppress;
7890   mp->managed = managed;
7891   mp->other = other;
7892   mp->ll_option = ll_option;
7893   mp->send_unicast = send_unicast;
7894   mp->cease = cease;
7895   mp->is_no = is_no;
7896   mp->default_router = default_router;
7897
7898   /* send it... */
7899   S;
7900
7901   /* Wait for a reply, return good/bad news  */
7902   W;
7903
7904   /* NOTREACHED */
7905   return 0;
7906 }
7907
7908 static int
7909 api_set_arp_neighbor_limit (vat_main_t * vam)
7910 {
7911   unformat_input_t *i = vam->input;
7912   vl_api_set_arp_neighbor_limit_t *mp;
7913   f64 timeout;
7914   u32 arp_nbr_limit;
7915   u8 limit_set = 0;
7916   u8 is_ipv6 = 0;
7917
7918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7919     {
7920       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7921         limit_set = 1;
7922       else if (unformat (i, "ipv6"))
7923         is_ipv6 = 1;
7924       else
7925         {
7926           clib_warning ("parse error '%U'", format_unformat_error, i);
7927           return -99;
7928         }
7929     }
7930
7931   if (limit_set == 0)
7932     {
7933       errmsg ("missing limit value");
7934       return -99;
7935     }
7936
7937   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7938
7939   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7940   mp->is_ipv6 = is_ipv6;
7941
7942   S;
7943   W;
7944   /* NOTREACHED */
7945   return 0;
7946 }
7947
7948 static int
7949 api_l2_patch_add_del (vat_main_t * vam)
7950 {
7951   unformat_input_t *i = vam->input;
7952   vl_api_l2_patch_add_del_t *mp;
7953   f64 timeout;
7954   u32 rx_sw_if_index;
7955   u8 rx_sw_if_index_set = 0;
7956   u32 tx_sw_if_index;
7957   u8 tx_sw_if_index_set = 0;
7958   u8 is_add = 1;
7959
7960   /* Parse args required to build the message */
7961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7962     {
7963       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7964         rx_sw_if_index_set = 1;
7965       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7966         tx_sw_if_index_set = 1;
7967       else if (unformat (i, "rx"))
7968         {
7969           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7970             {
7971               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7972                             &rx_sw_if_index))
7973                 rx_sw_if_index_set = 1;
7974             }
7975           else
7976             break;
7977         }
7978       else if (unformat (i, "tx"))
7979         {
7980           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7981             {
7982               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7983                             &tx_sw_if_index))
7984                 tx_sw_if_index_set = 1;
7985             }
7986           else
7987             break;
7988         }
7989       else if (unformat (i, "del"))
7990         is_add = 0;
7991       else
7992         break;
7993     }
7994
7995   if (rx_sw_if_index_set == 0)
7996     {
7997       errmsg ("missing rx interface name or rx_sw_if_index");
7998       return -99;
7999     }
8000
8001   if (tx_sw_if_index_set == 0)
8002     {
8003       errmsg ("missing tx interface name or tx_sw_if_index");
8004       return -99;
8005     }
8006
8007   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
8008
8009   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8010   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8011   mp->is_add = is_add;
8012
8013   S;
8014   W;
8015   /* NOTREACHED */
8016   return 0;
8017 }
8018
8019 static int
8020 api_ioam_enable (vat_main_t * vam)
8021 {
8022   unformat_input_t *input = vam->input;
8023   vl_api_ioam_enable_t *mp;
8024   f64 timeout;
8025   u32 id = 0;
8026   int has_trace_option = 0;
8027   int has_pot_option = 0;
8028   int has_seqno_option = 0;
8029   int has_analyse_option = 0;
8030
8031   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8032     {
8033       if (unformat (input, "trace"))
8034         has_trace_option = 1;
8035       else if (unformat (input, "pot"))
8036         has_pot_option = 1;
8037       else if (unformat (input, "seqno"))
8038         has_seqno_option = 1;
8039       else if (unformat (input, "analyse"))
8040         has_analyse_option = 1;
8041       else
8042         break;
8043     }
8044   M (IOAM_ENABLE, ioam_enable);
8045   mp->id = htons (id);
8046   mp->seqno = has_seqno_option;
8047   mp->analyse = has_analyse_option;
8048   mp->pot_enable = has_pot_option;
8049   mp->trace_enable = has_trace_option;
8050
8051   S;
8052   W;
8053
8054   return (0);
8055
8056 }
8057
8058
8059 static int
8060 api_ioam_disable (vat_main_t * vam)
8061 {
8062   vl_api_ioam_disable_t *mp;
8063   f64 timeout;
8064
8065   M (IOAM_DISABLE, ioam_disable);
8066   S;
8067   W;
8068   return 0;
8069 }
8070
8071 static int
8072 api_sr_tunnel_add_del (vat_main_t * vam)
8073 {
8074   unformat_input_t *i = vam->input;
8075   vl_api_sr_tunnel_add_del_t *mp;
8076   f64 timeout;
8077   int is_del = 0;
8078   int pl_index;
8079   ip6_address_t src_address;
8080   int src_address_set = 0;
8081   ip6_address_t dst_address;
8082   u32 dst_mask_width;
8083   int dst_address_set = 0;
8084   u16 flags = 0;
8085   u32 rx_table_id = 0;
8086   u32 tx_table_id = 0;
8087   ip6_address_t *segments = 0;
8088   ip6_address_t *this_seg;
8089   ip6_address_t *tags = 0;
8090   ip6_address_t *this_tag;
8091   ip6_address_t next_address, tag;
8092   u8 *name = 0;
8093   u8 *policy_name = 0;
8094
8095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8096     {
8097       if (unformat (i, "del"))
8098         is_del = 1;
8099       else if (unformat (i, "name %s", &name))
8100         ;
8101       else if (unformat (i, "policy %s", &policy_name))
8102         ;
8103       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8104         ;
8105       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8106         ;
8107       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8108         src_address_set = 1;
8109       else if (unformat (i, "dst %U/%d",
8110                          unformat_ip6_address, &dst_address, &dst_mask_width))
8111         dst_address_set = 1;
8112       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8113         {
8114           vec_add2 (segments, this_seg, 1);
8115           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8116                        sizeof (*this_seg));
8117         }
8118       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8119         {
8120           vec_add2 (tags, this_tag, 1);
8121           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8122         }
8123       else if (unformat (i, "clean"))
8124         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8125       else if (unformat (i, "protected"))
8126         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8127       else if (unformat (i, "InPE %d", &pl_index))
8128         {
8129           if (pl_index <= 0 || pl_index > 4)
8130             {
8131             pl_index_range_error:
8132               errmsg ("pl index %d out of range", pl_index);
8133               return -99;
8134             }
8135           flags |=
8136             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8137         }
8138       else if (unformat (i, "EgPE %d", &pl_index))
8139         {
8140           if (pl_index <= 0 || pl_index > 4)
8141             goto pl_index_range_error;
8142           flags |=
8143             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8144         }
8145       else if (unformat (i, "OrgSrc %d", &pl_index))
8146         {
8147           if (pl_index <= 0 || pl_index > 4)
8148             goto pl_index_range_error;
8149           flags |=
8150             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8151         }
8152       else
8153         break;
8154     }
8155
8156   if (!src_address_set)
8157     {
8158       errmsg ("src address required");
8159       return -99;
8160     }
8161
8162   if (!dst_address_set)
8163     {
8164       errmsg ("dst address required");
8165       return -99;
8166     }
8167
8168   if (!segments)
8169     {
8170       errmsg ("at least one sr segment required");
8171       return -99;
8172     }
8173
8174   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
8175       vec_len (segments) * sizeof (ip6_address_t)
8176       + vec_len (tags) * sizeof (ip6_address_t));
8177
8178   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8179   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8180   mp->dst_mask_width = dst_mask_width;
8181   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8182   mp->n_segments = vec_len (segments);
8183   mp->n_tags = vec_len (tags);
8184   mp->is_add = is_del == 0;
8185   clib_memcpy (mp->segs_and_tags, segments,
8186                vec_len (segments) * sizeof (ip6_address_t));
8187   clib_memcpy (mp->segs_and_tags +
8188                vec_len (segments) * sizeof (ip6_address_t), tags,
8189                vec_len (tags) * sizeof (ip6_address_t));
8190
8191   mp->outer_vrf_id = ntohl (rx_table_id);
8192   mp->inner_vrf_id = ntohl (tx_table_id);
8193   memcpy (mp->name, name, vec_len (name));
8194   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8195
8196   vec_free (segments);
8197   vec_free (tags);
8198
8199   S;
8200   W;
8201   /* NOTREACHED */
8202 }
8203
8204 static int
8205 api_sr_policy_add_del (vat_main_t * vam)
8206 {
8207   unformat_input_t *input = vam->input;
8208   vl_api_sr_policy_add_del_t *mp;
8209   f64 timeout;
8210   int is_del = 0;
8211   u8 *name = 0;
8212   u8 *tunnel_name = 0;
8213   u8 **tunnel_names = 0;
8214
8215   int name_set = 0;
8216   int tunnel_set = 0;
8217   int j = 0;
8218   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8219   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8220
8221   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8222     {
8223       if (unformat (input, "del"))
8224         is_del = 1;
8225       else if (unformat (input, "name %s", &name))
8226         name_set = 1;
8227       else if (unformat (input, "tunnel %s", &tunnel_name))
8228         {
8229           if (tunnel_name)
8230             {
8231               vec_add1 (tunnel_names, tunnel_name);
8232               /* For serializer:
8233                  - length = #bytes to store in serial vector
8234                  - +1 = byte to store that length
8235                */
8236               tunnel_names_length += (vec_len (tunnel_name) + 1);
8237               tunnel_set = 1;
8238               tunnel_name = 0;
8239             }
8240         }
8241       else
8242         break;
8243     }
8244
8245   if (!name_set)
8246     {
8247       errmsg ("policy name required");
8248       return -99;
8249     }
8250
8251   if ((!tunnel_set) && (!is_del))
8252     {
8253       errmsg ("tunnel name required");
8254       return -99;
8255     }
8256
8257   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8258
8259
8260
8261   mp->is_add = !is_del;
8262
8263   memcpy (mp->name, name, vec_len (name));
8264   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8265   u8 *serial_orig = 0;
8266   vec_validate (serial_orig, tunnel_names_length);
8267   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8268   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8269
8270   for (j = 0; j < vec_len (tunnel_names); j++)
8271     {
8272       tun_name_len = vec_len (tunnel_names[j]);
8273       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8274       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8275       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8276       serial_orig += tun_name_len;      // Advance past the copy
8277     }
8278   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8279
8280   vec_free (tunnel_names);
8281   vec_free (tunnel_name);
8282
8283   S;
8284   W;
8285   /* NOTREACHED */
8286 }
8287
8288 static int
8289 api_sr_multicast_map_add_del (vat_main_t * vam)
8290 {
8291   unformat_input_t *input = vam->input;
8292   vl_api_sr_multicast_map_add_del_t *mp;
8293   f64 timeout;
8294   int is_del = 0;
8295   ip6_address_t multicast_address;
8296   u8 *policy_name = 0;
8297   int multicast_address_set = 0;
8298
8299   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8300     {
8301       if (unformat (input, "del"))
8302         is_del = 1;
8303       else
8304         if (unformat
8305             (input, "address %U", unformat_ip6_address, &multicast_address))
8306         multicast_address_set = 1;
8307       else if (unformat (input, "sr-policy %s", &policy_name))
8308         ;
8309       else
8310         break;
8311     }
8312
8313   if (!is_del && !policy_name)
8314     {
8315       errmsg ("sr-policy name required");
8316       return -99;
8317     }
8318
8319
8320   if (!multicast_address_set)
8321     {
8322       errmsg ("address required");
8323       return -99;
8324     }
8325
8326   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8327
8328   mp->is_add = !is_del;
8329   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8330   clib_memcpy (mp->multicast_address, &multicast_address,
8331                sizeof (mp->multicast_address));
8332
8333
8334   vec_free (policy_name);
8335
8336   S;
8337   W;
8338   /* NOTREACHED */
8339 }
8340
8341
8342 #define foreach_tcp_proto_field                 \
8343 _(src_port)                                     \
8344 _(dst_port)
8345
8346 #define foreach_udp_proto_field                 \
8347 _(src_port)                                     \
8348 _(dst_port)
8349
8350 #define foreach_ip4_proto_field                 \
8351 _(src_address)                                  \
8352 _(dst_address)                                  \
8353 _(tos)                                          \
8354 _(length)                                       \
8355 _(fragment_id)                                  \
8356 _(ttl)                                          \
8357 _(protocol)                                     \
8358 _(checksum)
8359
8360 uword
8361 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8362 {
8363   u8 **maskp = va_arg (*args, u8 **);
8364   u8 *mask = 0;
8365   u8 found_something = 0;
8366   tcp_header_t *tcp;
8367
8368 #define _(a) u8 a=0;
8369   foreach_tcp_proto_field;
8370 #undef _
8371
8372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8373     {
8374       if (0);
8375 #define _(a) else if (unformat (input, #a)) a=1;
8376       foreach_tcp_proto_field
8377 #undef _
8378         else
8379         break;
8380     }
8381
8382 #define _(a) found_something += a;
8383   foreach_tcp_proto_field;
8384 #undef _
8385
8386   if (found_something == 0)
8387     return 0;
8388
8389   vec_validate (mask, sizeof (*tcp) - 1);
8390
8391   tcp = (tcp_header_t *) mask;
8392
8393 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8394   foreach_tcp_proto_field;
8395 #undef _
8396
8397   *maskp = mask;
8398   return 1;
8399 }
8400
8401 uword
8402 unformat_udp_mask (unformat_input_t * input, va_list * args)
8403 {
8404   u8 **maskp = va_arg (*args, u8 **);
8405   u8 *mask = 0;
8406   u8 found_something = 0;
8407   udp_header_t *udp;
8408
8409 #define _(a) u8 a=0;
8410   foreach_udp_proto_field;
8411 #undef _
8412
8413   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8414     {
8415       if (0);
8416 #define _(a) else if (unformat (input, #a)) a=1;
8417       foreach_udp_proto_field
8418 #undef _
8419         else
8420         break;
8421     }
8422
8423 #define _(a) found_something += a;
8424   foreach_udp_proto_field;
8425 #undef _
8426
8427   if (found_something == 0)
8428     return 0;
8429
8430   vec_validate (mask, sizeof (*udp) - 1);
8431
8432   udp = (udp_header_t *) mask;
8433
8434 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8435   foreach_udp_proto_field;
8436 #undef _
8437
8438   *maskp = mask;
8439   return 1;
8440 }
8441
8442 typedef struct
8443 {
8444   u16 src_port, dst_port;
8445 } tcpudp_header_t;
8446
8447 uword
8448 unformat_l4_mask (unformat_input_t * input, va_list * args)
8449 {
8450   u8 **maskp = va_arg (*args, u8 **);
8451   u16 src_port = 0, dst_port = 0;
8452   tcpudp_header_t *tcpudp;
8453
8454   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8455     {
8456       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8457         return 1;
8458       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8459         return 1;
8460       else if (unformat (input, "src_port"))
8461         src_port = 0xFFFF;
8462       else if (unformat (input, "dst_port"))
8463         dst_port = 0xFFFF;
8464       else
8465         return 0;
8466     }
8467
8468   if (!src_port && !dst_port)
8469     return 0;
8470
8471   u8 *mask = 0;
8472   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8473
8474   tcpudp = (tcpudp_header_t *) mask;
8475   tcpudp->src_port = src_port;
8476   tcpudp->dst_port = dst_port;
8477
8478   *maskp = mask;
8479
8480   return 1;
8481 }
8482
8483 uword
8484 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8485 {
8486   u8 **maskp = va_arg (*args, u8 **);
8487   u8 *mask = 0;
8488   u8 found_something = 0;
8489   ip4_header_t *ip;
8490
8491 #define _(a) u8 a=0;
8492   foreach_ip4_proto_field;
8493 #undef _
8494   u8 version = 0;
8495   u8 hdr_length = 0;
8496
8497
8498   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8499     {
8500       if (unformat (input, "version"))
8501         version = 1;
8502       else if (unformat (input, "hdr_length"))
8503         hdr_length = 1;
8504       else if (unformat (input, "src"))
8505         src_address = 1;
8506       else if (unformat (input, "dst"))
8507         dst_address = 1;
8508       else if (unformat (input, "proto"))
8509         protocol = 1;
8510
8511 #define _(a) else if (unformat (input, #a)) a=1;
8512       foreach_ip4_proto_field
8513 #undef _
8514         else
8515         break;
8516     }
8517
8518 #define _(a) found_something += a;
8519   foreach_ip4_proto_field;
8520 #undef _
8521
8522   if (found_something == 0)
8523     return 0;
8524
8525   vec_validate (mask, sizeof (*ip) - 1);
8526
8527   ip = (ip4_header_t *) mask;
8528
8529 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8530   foreach_ip4_proto_field;
8531 #undef _
8532
8533   ip->ip_version_and_header_length = 0;
8534
8535   if (version)
8536     ip->ip_version_and_header_length |= 0xF0;
8537
8538   if (hdr_length)
8539     ip->ip_version_and_header_length |= 0x0F;
8540
8541   *maskp = mask;
8542   return 1;
8543 }
8544
8545 #define foreach_ip6_proto_field                 \
8546 _(src_address)                                  \
8547 _(dst_address)                                  \
8548 _(payload_length)                               \
8549 _(hop_limit)                                    \
8550 _(protocol)
8551
8552 uword
8553 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8554 {
8555   u8 **maskp = va_arg (*args, u8 **);
8556   u8 *mask = 0;
8557   u8 found_something = 0;
8558   ip6_header_t *ip;
8559   u32 ip_version_traffic_class_and_flow_label;
8560
8561 #define _(a) u8 a=0;
8562   foreach_ip6_proto_field;
8563 #undef _
8564   u8 version = 0;
8565   u8 traffic_class = 0;
8566   u8 flow_label = 0;
8567
8568   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8569     {
8570       if (unformat (input, "version"))
8571         version = 1;
8572       else if (unformat (input, "traffic-class"))
8573         traffic_class = 1;
8574       else if (unformat (input, "flow-label"))
8575         flow_label = 1;
8576       else if (unformat (input, "src"))
8577         src_address = 1;
8578       else if (unformat (input, "dst"))
8579         dst_address = 1;
8580       else if (unformat (input, "proto"))
8581         protocol = 1;
8582
8583 #define _(a) else if (unformat (input, #a)) a=1;
8584       foreach_ip6_proto_field
8585 #undef _
8586         else
8587         break;
8588     }
8589
8590 #define _(a) found_something += a;
8591   foreach_ip6_proto_field;
8592 #undef _
8593
8594   if (found_something == 0)
8595     return 0;
8596
8597   vec_validate (mask, sizeof (*ip) - 1);
8598
8599   ip = (ip6_header_t *) mask;
8600
8601 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8602   foreach_ip6_proto_field;
8603 #undef _
8604
8605   ip_version_traffic_class_and_flow_label = 0;
8606
8607   if (version)
8608     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8609
8610   if (traffic_class)
8611     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8612
8613   if (flow_label)
8614     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8615
8616   ip->ip_version_traffic_class_and_flow_label =
8617     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8618
8619   *maskp = mask;
8620   return 1;
8621 }
8622
8623 uword
8624 unformat_l3_mask (unformat_input_t * input, va_list * args)
8625 {
8626   u8 **maskp = va_arg (*args, u8 **);
8627
8628   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8629     {
8630       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8631         return 1;
8632       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8633         return 1;
8634       else
8635         break;
8636     }
8637   return 0;
8638 }
8639
8640 uword
8641 unformat_l2_mask (unformat_input_t * input, va_list * args)
8642 {
8643   u8 **maskp = va_arg (*args, u8 **);
8644   u8 *mask = 0;
8645   u8 src = 0;
8646   u8 dst = 0;
8647   u8 proto = 0;
8648   u8 tag1 = 0;
8649   u8 tag2 = 0;
8650   u8 ignore_tag1 = 0;
8651   u8 ignore_tag2 = 0;
8652   u8 cos1 = 0;
8653   u8 cos2 = 0;
8654   u8 dot1q = 0;
8655   u8 dot1ad = 0;
8656   int len = 14;
8657
8658   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8659     {
8660       if (unformat (input, "src"))
8661         src = 1;
8662       else if (unformat (input, "dst"))
8663         dst = 1;
8664       else if (unformat (input, "proto"))
8665         proto = 1;
8666       else if (unformat (input, "tag1"))
8667         tag1 = 1;
8668       else if (unformat (input, "tag2"))
8669         tag2 = 1;
8670       else if (unformat (input, "ignore-tag1"))
8671         ignore_tag1 = 1;
8672       else if (unformat (input, "ignore-tag2"))
8673         ignore_tag2 = 1;
8674       else if (unformat (input, "cos1"))
8675         cos1 = 1;
8676       else if (unformat (input, "cos2"))
8677         cos2 = 1;
8678       else if (unformat (input, "dot1q"))
8679         dot1q = 1;
8680       else if (unformat (input, "dot1ad"))
8681         dot1ad = 1;
8682       else
8683         break;
8684     }
8685   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8686        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8687     return 0;
8688
8689   if (tag1 || ignore_tag1 || cos1 || dot1q)
8690     len = 18;
8691   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8692     len = 22;
8693
8694   vec_validate (mask, len - 1);
8695
8696   if (dst)
8697     memset (mask, 0xff, 6);
8698
8699   if (src)
8700     memset (mask + 6, 0xff, 6);
8701
8702   if (tag2 || dot1ad)
8703     {
8704       /* inner vlan tag */
8705       if (tag2)
8706         {
8707           mask[19] = 0xff;
8708           mask[18] = 0x0f;
8709         }
8710       if (cos2)
8711         mask[18] |= 0xe0;
8712       if (proto)
8713         mask[21] = mask[20] = 0xff;
8714       if (tag1)
8715         {
8716           mask[15] = 0xff;
8717           mask[14] = 0x0f;
8718         }
8719       if (cos1)
8720         mask[14] |= 0xe0;
8721       *maskp = mask;
8722       return 1;
8723     }
8724   if (tag1 | dot1q)
8725     {
8726       if (tag1)
8727         {
8728           mask[15] = 0xff;
8729           mask[14] = 0x0f;
8730         }
8731       if (cos1)
8732         mask[14] |= 0xe0;
8733       if (proto)
8734         mask[16] = mask[17] = 0xff;
8735
8736       *maskp = mask;
8737       return 1;
8738     }
8739   if (cos2)
8740     mask[18] |= 0xe0;
8741   if (cos1)
8742     mask[14] |= 0xe0;
8743   if (proto)
8744     mask[12] = mask[13] = 0xff;
8745
8746   *maskp = mask;
8747   return 1;
8748 }
8749
8750 uword
8751 unformat_classify_mask (unformat_input_t * input, va_list * args)
8752 {
8753   u8 **maskp = va_arg (*args, u8 **);
8754   u32 *skipp = va_arg (*args, u32 *);
8755   u32 *matchp = va_arg (*args, u32 *);
8756   u32 match;
8757   u8 *mask = 0;
8758   u8 *l2 = 0;
8759   u8 *l3 = 0;
8760   u8 *l4 = 0;
8761   int i;
8762
8763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8764     {
8765       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8766         ;
8767       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8768         ;
8769       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8770         ;
8771       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8772         ;
8773       else
8774         break;
8775     }
8776
8777   if (l4 && !l3)
8778     {
8779       vec_free (mask);
8780       vec_free (l2);
8781       vec_free (l4);
8782       return 0;
8783     }
8784
8785   if (mask || l2 || l3 || l4)
8786     {
8787       if (l2 || l3 || l4)
8788         {
8789           /* "With a free Ethernet header in every package" */
8790           if (l2 == 0)
8791             vec_validate (l2, 13);
8792           mask = l2;
8793           if (vec_len (l3))
8794             {
8795               vec_append (mask, l3);
8796               vec_free (l3);
8797             }
8798           if (vec_len (l4))
8799             {
8800               vec_append (mask, l4);
8801               vec_free (l4);
8802             }
8803         }
8804
8805       /* Scan forward looking for the first significant mask octet */
8806       for (i = 0; i < vec_len (mask); i++)
8807         if (mask[i])
8808           break;
8809
8810       /* compute (skip, match) params */
8811       *skipp = i / sizeof (u32x4);
8812       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8813
8814       /* Pad mask to an even multiple of the vector size */
8815       while (vec_len (mask) % sizeof (u32x4))
8816         vec_add1 (mask, 0);
8817
8818       match = vec_len (mask) / sizeof (u32x4);
8819
8820       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8821         {
8822           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8823           if (*tmp || *(tmp + 1))
8824             break;
8825           match--;
8826         }
8827       if (match == 0)
8828         clib_warning ("BUG: match 0");
8829
8830       _vec_len (mask) = match * sizeof (u32x4);
8831
8832       *matchp = match;
8833       *maskp = mask;
8834
8835       return 1;
8836     }
8837
8838   return 0;
8839 }
8840
8841 #define foreach_l2_next                         \
8842 _(drop, DROP)                                   \
8843 _(ethernet, ETHERNET_INPUT)                     \
8844 _(ip4, IP4_INPUT)                               \
8845 _(ip6, IP6_INPUT)
8846
8847 uword
8848 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8849 {
8850   u32 *miss_next_indexp = va_arg (*args, u32 *);
8851   u32 next_index = 0;
8852   u32 tmp;
8853
8854 #define _(n,N) \
8855   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8856   foreach_l2_next;
8857 #undef _
8858
8859   if (unformat (input, "%d", &tmp))
8860     {
8861       next_index = tmp;
8862       goto out;
8863     }
8864
8865   return 0;
8866
8867 out:
8868   *miss_next_indexp = next_index;
8869   return 1;
8870 }
8871
8872 #define foreach_ip_next                         \
8873 _(drop, DROP)                                   \
8874 _(local, LOCAL)                                 \
8875 _(rewrite, REWRITE)
8876
8877 uword
8878 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8879 {
8880   u32 *miss_next_indexp = va_arg (*args, u32 *);
8881   u32 next_index = 0;
8882   u32 tmp;
8883
8884 #define _(n,N) \
8885   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8886   foreach_ip_next;
8887 #undef _
8888
8889   if (unformat (input, "%d", &tmp))
8890     {
8891       next_index = tmp;
8892       goto out;
8893     }
8894
8895   return 0;
8896
8897 out:
8898   *miss_next_indexp = next_index;
8899   return 1;
8900 }
8901
8902 #define foreach_acl_next                        \
8903 _(deny, DENY)
8904
8905 uword
8906 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8907 {
8908   u32 *miss_next_indexp = va_arg (*args, u32 *);
8909   u32 next_index = 0;
8910   u32 tmp;
8911
8912 #define _(n,N) \
8913   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8914   foreach_acl_next;
8915 #undef _
8916
8917   if (unformat (input, "permit"))
8918     {
8919       next_index = ~0;
8920       goto out;
8921     }
8922   else if (unformat (input, "%d", &tmp))
8923     {
8924       next_index = tmp;
8925       goto out;
8926     }
8927
8928   return 0;
8929
8930 out:
8931   *miss_next_indexp = next_index;
8932   return 1;
8933 }
8934
8935 uword
8936 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8937 {
8938   u32 *r = va_arg (*args, u32 *);
8939
8940   if (unformat (input, "conform-color"))
8941     *r = POLICE_CONFORM;
8942   else if (unformat (input, "exceed-color"))
8943     *r = POLICE_EXCEED;
8944   else
8945     return 0;
8946
8947   return 1;
8948 }
8949
8950 static int
8951 api_classify_add_del_table (vat_main_t * vam)
8952 {
8953   unformat_input_t *i = vam->input;
8954   vl_api_classify_add_del_table_t *mp;
8955
8956   u32 nbuckets = 2;
8957   u32 skip = ~0;
8958   u32 match = ~0;
8959   int is_add = 1;
8960   int del_chain = 0;
8961   u32 table_index = ~0;
8962   u32 next_table_index = ~0;
8963   u32 miss_next_index = ~0;
8964   u32 memory_size = 32 << 20;
8965   u8 *mask = 0;
8966   f64 timeout;
8967   u32 current_data_flag = 0;
8968   int current_data_offset = 0;
8969
8970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8971     {
8972       if (unformat (i, "del"))
8973         is_add = 0;
8974       else if (unformat (i, "del-chain"))
8975         {
8976           is_add = 0;
8977           del_chain = 1;
8978         }
8979       else if (unformat (i, "buckets %d", &nbuckets))
8980         ;
8981       else if (unformat (i, "memory_size %d", &memory_size))
8982         ;
8983       else if (unformat (i, "skip %d", &skip))
8984         ;
8985       else if (unformat (i, "match %d", &match))
8986         ;
8987       else if (unformat (i, "table %d", &table_index))
8988         ;
8989       else if (unformat (i, "mask %U", unformat_classify_mask,
8990                          &mask, &skip, &match))
8991         ;
8992       else if (unformat (i, "next-table %d", &next_table_index))
8993         ;
8994       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8995                          &miss_next_index))
8996         ;
8997       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8998                          &miss_next_index))
8999         ;
9000       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
9001                          &miss_next_index))
9002         ;
9003       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9004         ;
9005       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9006         ;
9007       else
9008         break;
9009     }
9010
9011   if (is_add && mask == 0)
9012     {
9013       errmsg ("Mask required");
9014       return -99;
9015     }
9016
9017   if (is_add && skip == ~0)
9018     {
9019       errmsg ("skip count required");
9020       return -99;
9021     }
9022
9023   if (is_add && match == ~0)
9024     {
9025       errmsg ("match count required");
9026       return -99;
9027     }
9028
9029   if (!is_add && table_index == ~0)
9030     {
9031       errmsg ("table index required for delete");
9032       return -99;
9033     }
9034
9035   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
9036
9037   mp->is_add = is_add;
9038   mp->del_chain = del_chain;
9039   mp->table_index = ntohl (table_index);
9040   mp->nbuckets = ntohl (nbuckets);
9041   mp->memory_size = ntohl (memory_size);
9042   mp->skip_n_vectors = ntohl (skip);
9043   mp->match_n_vectors = ntohl (match);
9044   mp->next_table_index = ntohl (next_table_index);
9045   mp->miss_next_index = ntohl (miss_next_index);
9046   mp->current_data_flag = ntohl (current_data_flag);
9047   mp->current_data_offset = ntohl (current_data_offset);
9048   clib_memcpy (mp->mask, mask, vec_len (mask));
9049
9050   vec_free (mask);
9051
9052   S;
9053   W;
9054   /* NOTREACHED */
9055 }
9056
9057 uword
9058 unformat_l4_match (unformat_input_t * input, va_list * args)
9059 {
9060   u8 **matchp = va_arg (*args, u8 **);
9061
9062   u8 *proto_header = 0;
9063   int src_port = 0;
9064   int dst_port = 0;
9065
9066   tcpudp_header_t h;
9067
9068   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9069     {
9070       if (unformat (input, "src_port %d", &src_port))
9071         ;
9072       else if (unformat (input, "dst_port %d", &dst_port))
9073         ;
9074       else
9075         return 0;
9076     }
9077
9078   h.src_port = clib_host_to_net_u16 (src_port);
9079   h.dst_port = clib_host_to_net_u16 (dst_port);
9080   vec_validate (proto_header, sizeof (h) - 1);
9081   memcpy (proto_header, &h, sizeof (h));
9082
9083   *matchp = proto_header;
9084
9085   return 1;
9086 }
9087
9088 uword
9089 unformat_ip4_match (unformat_input_t * input, va_list * args)
9090 {
9091   u8 **matchp = va_arg (*args, u8 **);
9092   u8 *match = 0;
9093   ip4_header_t *ip;
9094   int version = 0;
9095   u32 version_val;
9096   int hdr_length = 0;
9097   u32 hdr_length_val;
9098   int src = 0, dst = 0;
9099   ip4_address_t src_val, dst_val;
9100   int proto = 0;
9101   u32 proto_val;
9102   int tos = 0;
9103   u32 tos_val;
9104   int length = 0;
9105   u32 length_val;
9106   int fragment_id = 0;
9107   u32 fragment_id_val;
9108   int ttl = 0;
9109   int ttl_val;
9110   int checksum = 0;
9111   u32 checksum_val;
9112
9113   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9114     {
9115       if (unformat (input, "version %d", &version_val))
9116         version = 1;
9117       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9118         hdr_length = 1;
9119       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9120         src = 1;
9121       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9122         dst = 1;
9123       else if (unformat (input, "proto %d", &proto_val))
9124         proto = 1;
9125       else if (unformat (input, "tos %d", &tos_val))
9126         tos = 1;
9127       else if (unformat (input, "length %d", &length_val))
9128         length = 1;
9129       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9130         fragment_id = 1;
9131       else if (unformat (input, "ttl %d", &ttl_val))
9132         ttl = 1;
9133       else if (unformat (input, "checksum %d", &checksum_val))
9134         checksum = 1;
9135       else
9136         break;
9137     }
9138
9139   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9140       + ttl + checksum == 0)
9141     return 0;
9142
9143   /*
9144    * Aligned because we use the real comparison functions
9145    */
9146   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9147
9148   ip = (ip4_header_t *) match;
9149
9150   /* These are realistically matched in practice */
9151   if (src)
9152     ip->src_address.as_u32 = src_val.as_u32;
9153
9154   if (dst)
9155     ip->dst_address.as_u32 = dst_val.as_u32;
9156
9157   if (proto)
9158     ip->protocol = proto_val;
9159
9160
9161   /* These are not, but they're included for completeness */
9162   if (version)
9163     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9164
9165   if (hdr_length)
9166     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9167
9168   if (tos)
9169     ip->tos = tos_val;
9170
9171   if (length)
9172     ip->length = clib_host_to_net_u16 (length_val);
9173
9174   if (ttl)
9175     ip->ttl = ttl_val;
9176
9177   if (checksum)
9178     ip->checksum = clib_host_to_net_u16 (checksum_val);
9179
9180   *matchp = match;
9181   return 1;
9182 }
9183
9184 uword
9185 unformat_ip6_match (unformat_input_t * input, va_list * args)
9186 {
9187   u8 **matchp = va_arg (*args, u8 **);
9188   u8 *match = 0;
9189   ip6_header_t *ip;
9190   int version = 0;
9191   u32 version_val;
9192   u8 traffic_class = 0;
9193   u32 traffic_class_val = 0;
9194   u8 flow_label = 0;
9195   u8 flow_label_val;
9196   int src = 0, dst = 0;
9197   ip6_address_t src_val, dst_val;
9198   int proto = 0;
9199   u32 proto_val;
9200   int payload_length = 0;
9201   u32 payload_length_val;
9202   int hop_limit = 0;
9203   int hop_limit_val;
9204   u32 ip_version_traffic_class_and_flow_label;
9205
9206   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9207     {
9208       if (unformat (input, "version %d", &version_val))
9209         version = 1;
9210       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9211         traffic_class = 1;
9212       else if (unformat (input, "flow_label %d", &flow_label_val))
9213         flow_label = 1;
9214       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9215         src = 1;
9216       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9217         dst = 1;
9218       else if (unformat (input, "proto %d", &proto_val))
9219         proto = 1;
9220       else if (unformat (input, "payload_length %d", &payload_length_val))
9221         payload_length = 1;
9222       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9223         hop_limit = 1;
9224       else
9225         break;
9226     }
9227
9228   if (version + traffic_class + flow_label + src + dst + proto +
9229       payload_length + hop_limit == 0)
9230     return 0;
9231
9232   /*
9233    * Aligned because we use the real comparison functions
9234    */
9235   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9236
9237   ip = (ip6_header_t *) match;
9238
9239   if (src)
9240     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9241
9242   if (dst)
9243     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9244
9245   if (proto)
9246     ip->protocol = proto_val;
9247
9248   ip_version_traffic_class_and_flow_label = 0;
9249
9250   if (version)
9251     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9252
9253   if (traffic_class)
9254     ip_version_traffic_class_and_flow_label |=
9255       (traffic_class_val & 0xFF) << 20;
9256
9257   if (flow_label)
9258     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9259
9260   ip->ip_version_traffic_class_and_flow_label =
9261     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9262
9263   if (payload_length)
9264     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9265
9266   if (hop_limit)
9267     ip->hop_limit = hop_limit_val;
9268
9269   *matchp = match;
9270   return 1;
9271 }
9272
9273 uword
9274 unformat_l3_match (unformat_input_t * input, va_list * args)
9275 {
9276   u8 **matchp = va_arg (*args, u8 **);
9277
9278   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9279     {
9280       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9281         return 1;
9282       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9283         return 1;
9284       else
9285         break;
9286     }
9287   return 0;
9288 }
9289
9290 uword
9291 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9292 {
9293   u8 *tagp = va_arg (*args, u8 *);
9294   u32 tag;
9295
9296   if (unformat (input, "%d", &tag))
9297     {
9298       tagp[0] = (tag >> 8) & 0x0F;
9299       tagp[1] = tag & 0xFF;
9300       return 1;
9301     }
9302
9303   return 0;
9304 }
9305
9306 uword
9307 unformat_l2_match (unformat_input_t * input, va_list * args)
9308 {
9309   u8 **matchp = va_arg (*args, u8 **);
9310   u8 *match = 0;
9311   u8 src = 0;
9312   u8 src_val[6];
9313   u8 dst = 0;
9314   u8 dst_val[6];
9315   u8 proto = 0;
9316   u16 proto_val;
9317   u8 tag1 = 0;
9318   u8 tag1_val[2];
9319   u8 tag2 = 0;
9320   u8 tag2_val[2];
9321   int len = 14;
9322   u8 ignore_tag1 = 0;
9323   u8 ignore_tag2 = 0;
9324   u8 cos1 = 0;
9325   u8 cos2 = 0;
9326   u32 cos1_val = 0;
9327   u32 cos2_val = 0;
9328
9329   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9330     {
9331       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9332         src = 1;
9333       else
9334         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9335         dst = 1;
9336       else if (unformat (input, "proto %U",
9337                          unformat_ethernet_type_host_byte_order, &proto_val))
9338         proto = 1;
9339       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9340         tag1 = 1;
9341       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9342         tag2 = 1;
9343       else if (unformat (input, "ignore-tag1"))
9344         ignore_tag1 = 1;
9345       else if (unformat (input, "ignore-tag2"))
9346         ignore_tag2 = 1;
9347       else if (unformat (input, "cos1 %d", &cos1_val))
9348         cos1 = 1;
9349       else if (unformat (input, "cos2 %d", &cos2_val))
9350         cos2 = 1;
9351       else
9352         break;
9353     }
9354   if ((src + dst + proto + tag1 + tag2 +
9355        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9356     return 0;
9357
9358   if (tag1 || ignore_tag1 || cos1)
9359     len = 18;
9360   if (tag2 || ignore_tag2 || cos2)
9361     len = 22;
9362
9363   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9364
9365   if (dst)
9366     clib_memcpy (match, dst_val, 6);
9367
9368   if (src)
9369     clib_memcpy (match + 6, src_val, 6);
9370
9371   if (tag2)
9372     {
9373       /* inner vlan tag */
9374       match[19] = tag2_val[1];
9375       match[18] = tag2_val[0];
9376       if (cos2)
9377         match[18] |= (cos2_val & 0x7) << 5;
9378       if (proto)
9379         {
9380           match[21] = proto_val & 0xff;
9381           match[20] = proto_val >> 8;
9382         }
9383       if (tag1)
9384         {
9385           match[15] = tag1_val[1];
9386           match[14] = tag1_val[0];
9387         }
9388       if (cos1)
9389         match[14] |= (cos1_val & 0x7) << 5;
9390       *matchp = match;
9391       return 1;
9392     }
9393   if (tag1)
9394     {
9395       match[15] = tag1_val[1];
9396       match[14] = tag1_val[0];
9397       if (proto)
9398         {
9399           match[17] = proto_val & 0xff;
9400           match[16] = proto_val >> 8;
9401         }
9402       if (cos1)
9403         match[14] |= (cos1_val & 0x7) << 5;
9404
9405       *matchp = match;
9406       return 1;
9407     }
9408   if (cos2)
9409     match[18] |= (cos2_val & 0x7) << 5;
9410   if (cos1)
9411     match[14] |= (cos1_val & 0x7) << 5;
9412   if (proto)
9413     {
9414       match[13] = proto_val & 0xff;
9415       match[12] = proto_val >> 8;
9416     }
9417
9418   *matchp = match;
9419   return 1;
9420 }
9421
9422
9423 uword
9424 unformat_classify_match (unformat_input_t * input, va_list * args)
9425 {
9426   u8 **matchp = va_arg (*args, u8 **);
9427   u32 skip_n_vectors = va_arg (*args, u32);
9428   u32 match_n_vectors = va_arg (*args, u32);
9429
9430   u8 *match = 0;
9431   u8 *l2 = 0;
9432   u8 *l3 = 0;
9433   u8 *l4 = 0;
9434
9435   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9436     {
9437       if (unformat (input, "hex %U", unformat_hex_string, &match))
9438         ;
9439       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9440         ;
9441       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9442         ;
9443       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9444         ;
9445       else
9446         break;
9447     }
9448
9449   if (l4 && !l3)
9450     {
9451       vec_free (match);
9452       vec_free (l2);
9453       vec_free (l4);
9454       return 0;
9455     }
9456
9457   if (match || l2 || l3 || l4)
9458     {
9459       if (l2 || l3 || l4)
9460         {
9461           /* "Win a free Ethernet header in every packet" */
9462           if (l2 == 0)
9463             vec_validate_aligned (l2, 13, sizeof (u32x4));
9464           match = l2;
9465           if (vec_len (l3))
9466             {
9467               vec_append_aligned (match, l3, sizeof (u32x4));
9468               vec_free (l3);
9469             }
9470           if (vec_len (l4))
9471             {
9472               vec_append_aligned (match, l4, sizeof (u32x4));
9473               vec_free (l4);
9474             }
9475         }
9476
9477       /* Make sure the vector is big enough even if key is all 0's */
9478       vec_validate_aligned
9479         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9480          sizeof (u32x4));
9481
9482       /* Set size, include skipped vectors */
9483       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9484
9485       *matchp = match;
9486
9487       return 1;
9488     }
9489
9490   return 0;
9491 }
9492
9493 static int
9494 api_classify_add_del_session (vat_main_t * vam)
9495 {
9496   unformat_input_t *i = vam->input;
9497   vl_api_classify_add_del_session_t *mp;
9498   int is_add = 1;
9499   u32 table_index = ~0;
9500   u32 hit_next_index = ~0;
9501   u32 opaque_index = ~0;
9502   u8 *match = 0;
9503   i32 advance = 0;
9504   f64 timeout;
9505   u32 skip_n_vectors = 0;
9506   u32 match_n_vectors = 0;
9507   u32 action = 0;
9508   u32 metadata = 0;
9509
9510   /*
9511    * Warning: you have to supply skip_n and match_n
9512    * because the API client cant simply look at the classify
9513    * table object.
9514    */
9515
9516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9517     {
9518       if (unformat (i, "del"))
9519         is_add = 0;
9520       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9521                          &hit_next_index))
9522         ;
9523       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9524                          &hit_next_index))
9525         ;
9526       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9527                          &hit_next_index))
9528         ;
9529       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9530         ;
9531       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9532         ;
9533       else if (unformat (i, "opaque-index %d", &opaque_index))
9534         ;
9535       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9536         ;
9537       else if (unformat (i, "match_n %d", &match_n_vectors))
9538         ;
9539       else if (unformat (i, "match %U", unformat_classify_match,
9540                          &match, skip_n_vectors, match_n_vectors))
9541         ;
9542       else if (unformat (i, "advance %d", &advance))
9543         ;
9544       else if (unformat (i, "table-index %d", &table_index))
9545         ;
9546       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9547         action = 1;
9548       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9549         action = 2;
9550       else if (unformat (i, "action %d", &action))
9551         ;
9552       else if (unformat (i, "metadata %d", &metadata))
9553         ;
9554       else
9555         break;
9556     }
9557
9558   if (table_index == ~0)
9559     {
9560       errmsg ("Table index required");
9561       return -99;
9562     }
9563
9564   if (is_add && match == 0)
9565     {
9566       errmsg ("Match value required");
9567       return -99;
9568     }
9569
9570   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9571
9572   mp->is_add = is_add;
9573   mp->table_index = ntohl (table_index);
9574   mp->hit_next_index = ntohl (hit_next_index);
9575   mp->opaque_index = ntohl (opaque_index);
9576   mp->advance = ntohl (advance);
9577   mp->action = action;
9578   mp->metadata = ntohl (metadata);
9579   clib_memcpy (mp->match, match, vec_len (match));
9580   vec_free (match);
9581
9582   S;
9583   W;
9584   /* NOTREACHED */
9585 }
9586
9587 static int
9588 api_classify_set_interface_ip_table (vat_main_t * vam)
9589 {
9590   unformat_input_t *i = vam->input;
9591   vl_api_classify_set_interface_ip_table_t *mp;
9592   f64 timeout;
9593   u32 sw_if_index;
9594   int sw_if_index_set;
9595   u32 table_index = ~0;
9596   u8 is_ipv6 = 0;
9597
9598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9599     {
9600       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9601         sw_if_index_set = 1;
9602       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9603         sw_if_index_set = 1;
9604       else if (unformat (i, "table %d", &table_index))
9605         ;
9606       else
9607         {
9608           clib_warning ("parse error '%U'", format_unformat_error, i);
9609           return -99;
9610         }
9611     }
9612
9613   if (sw_if_index_set == 0)
9614     {
9615       errmsg ("missing interface name or sw_if_index");
9616       return -99;
9617     }
9618
9619
9620   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9621
9622   mp->sw_if_index = ntohl (sw_if_index);
9623   mp->table_index = ntohl (table_index);
9624   mp->is_ipv6 = is_ipv6;
9625
9626   S;
9627   W;
9628   /* NOTREACHED */
9629   return 0;
9630 }
9631
9632 static int
9633 api_classify_set_interface_l2_tables (vat_main_t * vam)
9634 {
9635   unformat_input_t *i = vam->input;
9636   vl_api_classify_set_interface_l2_tables_t *mp;
9637   f64 timeout;
9638   u32 sw_if_index;
9639   int sw_if_index_set;
9640   u32 ip4_table_index = ~0;
9641   u32 ip6_table_index = ~0;
9642   u32 other_table_index = ~0;
9643   u32 is_input = 1;
9644
9645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9646     {
9647       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9648         sw_if_index_set = 1;
9649       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9650         sw_if_index_set = 1;
9651       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9652         ;
9653       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9654         ;
9655       else if (unformat (i, "other-table %d", &other_table_index))
9656         ;
9657       else if (unformat (i, "is-input %d", &is_input))
9658         ;
9659       else
9660         {
9661           clib_warning ("parse error '%U'", format_unformat_error, i);
9662           return -99;
9663         }
9664     }
9665
9666   if (sw_if_index_set == 0)
9667     {
9668       errmsg ("missing interface name or sw_if_index");
9669       return -99;
9670     }
9671
9672
9673   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9674
9675   mp->sw_if_index = ntohl (sw_if_index);
9676   mp->ip4_table_index = ntohl (ip4_table_index);
9677   mp->ip6_table_index = ntohl (ip6_table_index);
9678   mp->other_table_index = ntohl (other_table_index);
9679   mp->is_input = (u8) is_input;
9680
9681   S;
9682   W;
9683   /* NOTREACHED */
9684   return 0;
9685 }
9686
9687 static int
9688 api_set_ipfix_exporter (vat_main_t * vam)
9689 {
9690   unformat_input_t *i = vam->input;
9691   vl_api_set_ipfix_exporter_t *mp;
9692   ip4_address_t collector_address;
9693   u8 collector_address_set = 0;
9694   u32 collector_port = ~0;
9695   ip4_address_t src_address;
9696   u8 src_address_set = 0;
9697   u32 vrf_id = ~0;
9698   u32 path_mtu = ~0;
9699   u32 template_interval = ~0;
9700   u8 udp_checksum = 0;
9701   f64 timeout;
9702
9703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9704     {
9705       if (unformat (i, "collector_address %U", unformat_ip4_address,
9706                     &collector_address))
9707         collector_address_set = 1;
9708       else if (unformat (i, "collector_port %d", &collector_port))
9709         ;
9710       else if (unformat (i, "src_address %U", unformat_ip4_address,
9711                          &src_address))
9712         src_address_set = 1;
9713       else if (unformat (i, "vrf_id %d", &vrf_id))
9714         ;
9715       else if (unformat (i, "path_mtu %d", &path_mtu))
9716         ;
9717       else if (unformat (i, "template_interval %d", &template_interval))
9718         ;
9719       else if (unformat (i, "udp_checksum"))
9720         udp_checksum = 1;
9721       else
9722         break;
9723     }
9724
9725   if (collector_address_set == 0)
9726     {
9727       errmsg ("collector_address required");
9728       return -99;
9729     }
9730
9731   if (src_address_set == 0)
9732     {
9733       errmsg ("src_address required");
9734       return -99;
9735     }
9736
9737   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9738
9739   memcpy (mp->collector_address, collector_address.data,
9740           sizeof (collector_address.data));
9741   mp->collector_port = htons ((u16) collector_port);
9742   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9743   mp->vrf_id = htonl (vrf_id);
9744   mp->path_mtu = htonl (path_mtu);
9745   mp->template_interval = htonl (template_interval);
9746   mp->udp_checksum = udp_checksum;
9747
9748   S;
9749   W;
9750   /* NOTREACHED */
9751 }
9752
9753 static int
9754 api_set_ipfix_classify_stream (vat_main_t * vam)
9755 {
9756   unformat_input_t *i = vam->input;
9757   vl_api_set_ipfix_classify_stream_t *mp;
9758   u32 domain_id = 0;
9759   u32 src_port = UDP_DST_PORT_ipfix;
9760   f64 timeout;
9761
9762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9763     {
9764       if (unformat (i, "domain %d", &domain_id))
9765         ;
9766       else if (unformat (i, "src_port %d", &src_port))
9767         ;
9768       else
9769         {
9770           errmsg ("unknown input `%U'", format_unformat_error, i);
9771           return -99;
9772         }
9773     }
9774
9775   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9776
9777   mp->domain_id = htonl (domain_id);
9778   mp->src_port = htons ((u16) src_port);
9779
9780   S;
9781   W;
9782   /* NOTREACHED */
9783 }
9784
9785 static int
9786 api_ipfix_classify_table_add_del (vat_main_t * vam)
9787 {
9788   unformat_input_t *i = vam->input;
9789   vl_api_ipfix_classify_table_add_del_t *mp;
9790   int is_add = -1;
9791   u32 classify_table_index = ~0;
9792   u8 ip_version = 0;
9793   u8 transport_protocol = 255;
9794   f64 timeout;
9795
9796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9797     {
9798       if (unformat (i, "add"))
9799         is_add = 1;
9800       else if (unformat (i, "del"))
9801         is_add = 0;
9802       else if (unformat (i, "table %d", &classify_table_index))
9803         ;
9804       else if (unformat (i, "ip4"))
9805         ip_version = 4;
9806       else if (unformat (i, "ip6"))
9807         ip_version = 6;
9808       else if (unformat (i, "tcp"))
9809         transport_protocol = 6;
9810       else if (unformat (i, "udp"))
9811         transport_protocol = 17;
9812       else
9813         {
9814           errmsg ("unknown input `%U'", format_unformat_error, i);
9815           return -99;
9816         }
9817     }
9818
9819   if (is_add == -1)
9820     {
9821       errmsg ("expecting: add|del");
9822       return -99;
9823     }
9824   if (classify_table_index == ~0)
9825     {
9826       errmsg ("classifier table not specified");
9827       return -99;
9828     }
9829   if (ip_version == 0)
9830     {
9831       errmsg ("IP version not specified");
9832       return -99;
9833     }
9834
9835   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9836
9837   mp->is_add = is_add;
9838   mp->table_id = htonl (classify_table_index);
9839   mp->ip_version = ip_version;
9840   mp->transport_protocol = transport_protocol;
9841
9842   S;
9843   W;
9844   /* NOTREACHED */
9845 }
9846
9847 static int
9848 api_get_node_index (vat_main_t * vam)
9849 {
9850   unformat_input_t *i = vam->input;
9851   vl_api_get_node_index_t *mp;
9852   f64 timeout;
9853   u8 *name = 0;
9854
9855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9856     {
9857       if (unformat (i, "node %s", &name))
9858         ;
9859       else
9860         break;
9861     }
9862   if (name == 0)
9863     {
9864       errmsg ("node name required");
9865       return -99;
9866     }
9867   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9868     {
9869       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9870       return -99;
9871     }
9872
9873   M (GET_NODE_INDEX, get_node_index);
9874   clib_memcpy (mp->node_name, name, vec_len (name));
9875   vec_free (name);
9876
9877   S;
9878   W;
9879   /* NOTREACHED */
9880   return 0;
9881 }
9882
9883 static int
9884 api_get_next_index (vat_main_t * vam)
9885 {
9886   unformat_input_t *i = vam->input;
9887   vl_api_get_next_index_t *mp;
9888   f64 timeout;
9889   u8 *node_name = 0, *next_node_name = 0;
9890
9891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9892     {
9893       if (unformat (i, "node-name %s", &node_name))
9894         ;
9895       else if (unformat (i, "next-node-name %s", &next_node_name))
9896         break;
9897     }
9898
9899   if (node_name == 0)
9900     {
9901       errmsg ("node name required");
9902       return -99;
9903     }
9904   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9905     {
9906       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9907       return -99;
9908     }
9909
9910   if (next_node_name == 0)
9911     {
9912       errmsg ("next node name required");
9913       return -99;
9914     }
9915   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9916     {
9917       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9918       return -99;
9919     }
9920
9921   M (GET_NEXT_INDEX, get_next_index);
9922   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9923   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9924   vec_free (node_name);
9925   vec_free (next_node_name);
9926
9927   S;
9928   W;
9929   /* NOTREACHED */
9930   return 0;
9931 }
9932
9933 static int
9934 api_add_node_next (vat_main_t * vam)
9935 {
9936   unformat_input_t *i = vam->input;
9937   vl_api_add_node_next_t *mp;
9938   f64 timeout;
9939   u8 *name = 0;
9940   u8 *next = 0;
9941
9942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9943     {
9944       if (unformat (i, "node %s", &name))
9945         ;
9946       else if (unformat (i, "next %s", &next))
9947         ;
9948       else
9949         break;
9950     }
9951   if (name == 0)
9952     {
9953       errmsg ("node name required");
9954       return -99;
9955     }
9956   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9957     {
9958       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9959       return -99;
9960     }
9961   if (next == 0)
9962     {
9963       errmsg ("next node required");
9964       return -99;
9965     }
9966   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9967     {
9968       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9969       return -99;
9970     }
9971
9972   M (ADD_NODE_NEXT, add_node_next);
9973   clib_memcpy (mp->node_name, name, vec_len (name));
9974   clib_memcpy (mp->next_name, next, vec_len (next));
9975   vec_free (name);
9976   vec_free (next);
9977
9978   S;
9979   W;
9980   /* NOTREACHED */
9981   return 0;
9982 }
9983
9984 static int
9985 api_l2tpv3_create_tunnel (vat_main_t * vam)
9986 {
9987   unformat_input_t *i = vam->input;
9988   ip6_address_t client_address, our_address;
9989   int client_address_set = 0;
9990   int our_address_set = 0;
9991   u32 local_session_id = 0;
9992   u32 remote_session_id = 0;
9993   u64 local_cookie = 0;
9994   u64 remote_cookie = 0;
9995   u8 l2_sublayer_present = 0;
9996   vl_api_l2tpv3_create_tunnel_t *mp;
9997   f64 timeout;
9998
9999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10000     {
10001       if (unformat (i, "client_address %U", unformat_ip6_address,
10002                     &client_address))
10003         client_address_set = 1;
10004       else if (unformat (i, "our_address %U", unformat_ip6_address,
10005                          &our_address))
10006         our_address_set = 1;
10007       else if (unformat (i, "local_session_id %d", &local_session_id))
10008         ;
10009       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10010         ;
10011       else if (unformat (i, "local_cookie %lld", &local_cookie))
10012         ;
10013       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10014         ;
10015       else if (unformat (i, "l2-sublayer-present"))
10016         l2_sublayer_present = 1;
10017       else
10018         break;
10019     }
10020
10021   if (client_address_set == 0)
10022     {
10023       errmsg ("client_address required");
10024       return -99;
10025     }
10026
10027   if (our_address_set == 0)
10028     {
10029       errmsg ("our_address required");
10030       return -99;
10031     }
10032
10033   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
10034
10035   clib_memcpy (mp->client_address, client_address.as_u8,
10036                sizeof (mp->client_address));
10037
10038   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10039
10040   mp->local_session_id = ntohl (local_session_id);
10041   mp->remote_session_id = ntohl (remote_session_id);
10042   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10043   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10044   mp->l2_sublayer_present = l2_sublayer_present;
10045   mp->is_ipv6 = 1;
10046
10047   S;
10048   W;
10049   /* NOTREACHED */
10050   return 0;
10051 }
10052
10053 static int
10054 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10055 {
10056   unformat_input_t *i = vam->input;
10057   u32 sw_if_index;
10058   u8 sw_if_index_set = 0;
10059   u64 new_local_cookie = 0;
10060   u64 new_remote_cookie = 0;
10061   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10062   f64 timeout;
10063
10064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10065     {
10066       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10067         sw_if_index_set = 1;
10068       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10069         sw_if_index_set = 1;
10070       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10071         ;
10072       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10073         ;
10074       else
10075         break;
10076     }
10077
10078   if (sw_if_index_set == 0)
10079     {
10080       errmsg ("missing interface name or sw_if_index");
10081       return -99;
10082     }
10083
10084   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
10085
10086   mp->sw_if_index = ntohl (sw_if_index);
10087   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10088   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10089
10090   S;
10091   W;
10092   /* NOTREACHED */
10093   return 0;
10094 }
10095
10096 static int
10097 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10098 {
10099   unformat_input_t *i = vam->input;
10100   vl_api_l2tpv3_interface_enable_disable_t *mp;
10101   f64 timeout;
10102   u32 sw_if_index;
10103   u8 sw_if_index_set = 0;
10104   u8 enable_disable = 1;
10105
10106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10107     {
10108       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10109         sw_if_index_set = 1;
10110       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10111         sw_if_index_set = 1;
10112       else if (unformat (i, "enable"))
10113         enable_disable = 1;
10114       else if (unformat (i, "disable"))
10115         enable_disable = 0;
10116       else
10117         break;
10118     }
10119
10120   if (sw_if_index_set == 0)
10121     {
10122       errmsg ("missing interface name or sw_if_index");
10123       return -99;
10124     }
10125
10126   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
10127
10128   mp->sw_if_index = ntohl (sw_if_index);
10129   mp->enable_disable = enable_disable;
10130
10131   S;
10132   W;
10133   /* NOTREACHED */
10134   return 0;
10135 }
10136
10137 static int
10138 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10139 {
10140   unformat_input_t *i = vam->input;
10141   vl_api_l2tpv3_set_lookup_key_t *mp;
10142   f64 timeout;
10143   u8 key = ~0;
10144
10145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10146     {
10147       if (unformat (i, "lookup_v6_src"))
10148         key = L2T_LOOKUP_SRC_ADDRESS;
10149       else if (unformat (i, "lookup_v6_dst"))
10150         key = L2T_LOOKUP_DST_ADDRESS;
10151       else if (unformat (i, "lookup_session_id"))
10152         key = L2T_LOOKUP_SESSION_ID;
10153       else
10154         break;
10155     }
10156
10157   if (key == (u8) ~ 0)
10158     {
10159       errmsg ("l2tp session lookup key unset");
10160       return -99;
10161     }
10162
10163   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
10164
10165   mp->key = key;
10166
10167   S;
10168   W;
10169   /* NOTREACHED */
10170   return 0;
10171 }
10172
10173 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10174   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10175 {
10176   vat_main_t *vam = &vat_main;
10177
10178   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10179          format_ip6_address, mp->our_address,
10180          format_ip6_address, mp->client_address,
10181          clib_net_to_host_u32 (mp->sw_if_index));
10182
10183   print (vam->ofp,
10184          "   local cookies %016llx %016llx remote cookie %016llx",
10185          clib_net_to_host_u64 (mp->local_cookie[0]),
10186          clib_net_to_host_u64 (mp->local_cookie[1]),
10187          clib_net_to_host_u64 (mp->remote_cookie));
10188
10189   print (vam->ofp, "   local session-id %d remote session-id %d",
10190          clib_net_to_host_u32 (mp->local_session_id),
10191          clib_net_to_host_u32 (mp->remote_session_id));
10192
10193   print (vam->ofp, "   l2 specific sublayer %s\n",
10194          mp->l2_sublayer_present ? "preset" : "absent");
10195
10196 }
10197
10198 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10199   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10200 {
10201   vat_main_t *vam = &vat_main;
10202   vat_json_node_t *node = NULL;
10203   struct in6_addr addr;
10204
10205   if (VAT_JSON_ARRAY != vam->json_tree.type)
10206     {
10207       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10208       vat_json_init_array (&vam->json_tree);
10209     }
10210   node = vat_json_array_add (&vam->json_tree);
10211
10212   vat_json_init_object (node);
10213
10214   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10215   vat_json_object_add_ip6 (node, "our_address", addr);
10216   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10217   vat_json_object_add_ip6 (node, "client_address", addr);
10218
10219   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10220   vat_json_init_array (lc);
10221   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10222   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10223   vat_json_object_add_uint (node, "remote_cookie",
10224                             clib_net_to_host_u64 (mp->remote_cookie));
10225
10226   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10227   vat_json_object_add_uint (node, "local_session_id",
10228                             clib_net_to_host_u32 (mp->local_session_id));
10229   vat_json_object_add_uint (node, "remote_session_id",
10230                             clib_net_to_host_u32 (mp->remote_session_id));
10231   vat_json_object_add_string_copy (node, "l2_sublayer",
10232                                    mp->l2_sublayer_present ? (u8 *) "present"
10233                                    : (u8 *) "absent");
10234 }
10235
10236 static int
10237 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10238 {
10239   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10240   f64 timeout;
10241
10242   /* Get list of l2tpv3-tunnel interfaces */
10243   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10244   S;
10245
10246   /* Use a control ping for synchronization */
10247   {
10248     vl_api_control_ping_t *mp;
10249     M (CONTROL_PING, control_ping);
10250     S;
10251   }
10252   W;
10253 }
10254
10255
10256 static void vl_api_sw_interface_tap_details_t_handler
10257   (vl_api_sw_interface_tap_details_t * mp)
10258 {
10259   vat_main_t *vam = &vat_main;
10260
10261   print (vam->ofp, "%-16s %d",
10262          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10263 }
10264
10265 static void vl_api_sw_interface_tap_details_t_handler_json
10266   (vl_api_sw_interface_tap_details_t * mp)
10267 {
10268   vat_main_t *vam = &vat_main;
10269   vat_json_node_t *node = NULL;
10270
10271   if (VAT_JSON_ARRAY != vam->json_tree.type)
10272     {
10273       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10274       vat_json_init_array (&vam->json_tree);
10275     }
10276   node = vat_json_array_add (&vam->json_tree);
10277
10278   vat_json_init_object (node);
10279   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10280   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10281 }
10282
10283 static int
10284 api_sw_interface_tap_dump (vat_main_t * vam)
10285 {
10286   vl_api_sw_interface_tap_dump_t *mp;
10287   f64 timeout;
10288
10289   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10290   /* Get list of tap interfaces */
10291   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10292   S;
10293
10294   /* Use a control ping for synchronization */
10295   {
10296     vl_api_control_ping_t *mp;
10297     M (CONTROL_PING, control_ping);
10298     S;
10299   }
10300   W;
10301 }
10302
10303 static uword unformat_vxlan_decap_next
10304   (unformat_input_t * input, va_list * args)
10305 {
10306   u32 *result = va_arg (*args, u32 *);
10307   u32 tmp;
10308
10309   if (unformat (input, "l2"))
10310     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10311   else if (unformat (input, "%d", &tmp))
10312     *result = tmp;
10313   else
10314     return 0;
10315   return 1;
10316 }
10317
10318 static int
10319 api_vxlan_add_del_tunnel (vat_main_t * vam)
10320 {
10321   unformat_input_t *line_input = vam->input;
10322   vl_api_vxlan_add_del_tunnel_t *mp;
10323   f64 timeout;
10324   ip46_address_t src, dst;
10325   u8 is_add = 1;
10326   u8 ipv4_set = 0, ipv6_set = 0;
10327   u8 src_set = 0;
10328   u8 dst_set = 0;
10329   u8 grp_set = 0;
10330   u32 mcast_sw_if_index = ~0;
10331   u32 encap_vrf_id = 0;
10332   u32 decap_next_index = ~0;
10333   u32 vni = 0;
10334
10335   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10336   memset (&src, 0, sizeof src);
10337   memset (&dst, 0, sizeof dst);
10338
10339   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10340     {
10341       if (unformat (line_input, "del"))
10342         is_add = 0;
10343       else
10344         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10345         {
10346           ipv4_set = 1;
10347           src_set = 1;
10348         }
10349       else
10350         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10351         {
10352           ipv4_set = 1;
10353           dst_set = 1;
10354         }
10355       else
10356         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10357         {
10358           ipv6_set = 1;
10359           src_set = 1;
10360         }
10361       else
10362         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10363         {
10364           ipv6_set = 1;
10365           dst_set = 1;
10366         }
10367       else if (unformat (line_input, "group %U %U",
10368                          unformat_ip4_address, &dst.ip4,
10369                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10370         {
10371           grp_set = dst_set = 1;
10372           ipv4_set = 1;
10373         }
10374       else if (unformat (line_input, "group %U",
10375                          unformat_ip4_address, &dst.ip4))
10376         {
10377           grp_set = dst_set = 1;
10378           ipv4_set = 1;
10379         }
10380       else if (unformat (line_input, "group %U %U",
10381                          unformat_ip6_address, &dst.ip6,
10382                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10383         {
10384           grp_set = dst_set = 1;
10385           ipv6_set = 1;
10386         }
10387       else if (unformat (line_input, "group %U",
10388                          unformat_ip6_address, &dst.ip6))
10389         {
10390           grp_set = dst_set = 1;
10391           ipv6_set = 1;
10392         }
10393       else
10394         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10395         ;
10396       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10397         ;
10398       else if (unformat (line_input, "decap-next %U",
10399                          unformat_vxlan_decap_next, &decap_next_index))
10400         ;
10401       else if (unformat (line_input, "vni %d", &vni))
10402         ;
10403       else
10404         {
10405           errmsg ("parse error '%U'", format_unformat_error, line_input);
10406           return -99;
10407         }
10408     }
10409
10410   if (src_set == 0)
10411     {
10412       errmsg ("tunnel src address not specified");
10413       return -99;
10414     }
10415   if (dst_set == 0)
10416     {
10417       errmsg ("tunnel dst address not specified");
10418       return -99;
10419     }
10420
10421   if (grp_set && !ip46_address_is_multicast (&dst))
10422     {
10423       errmsg ("tunnel group address not multicast");
10424       return -99;
10425     }
10426   if (grp_set && mcast_sw_if_index == ~0)
10427     {
10428       errmsg ("tunnel nonexistent multicast device");
10429       return -99;
10430     }
10431   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10432     {
10433       errmsg ("tunnel dst address must be unicast");
10434       return -99;
10435     }
10436
10437
10438   if (ipv4_set && ipv6_set)
10439     {
10440       errmsg ("both IPv4 and IPv6 addresses specified");
10441       return -99;
10442     }
10443
10444   if ((vni == 0) || (vni >> 24))
10445     {
10446       errmsg ("vni not specified or out of range");
10447       return -99;
10448     }
10449
10450   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10451
10452   if (ipv6_set)
10453     {
10454       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10455       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10456     }
10457   else
10458     {
10459       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10460       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10461     }
10462   mp->encap_vrf_id = ntohl (encap_vrf_id);
10463   mp->decap_next_index = ntohl (decap_next_index);
10464   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10465   mp->vni = ntohl (vni);
10466   mp->is_add = is_add;
10467   mp->is_ipv6 = ipv6_set;
10468
10469   S;
10470   W;
10471   /* NOTREACHED */
10472   return 0;
10473 }
10474
10475 static void vl_api_vxlan_tunnel_details_t_handler
10476   (vl_api_vxlan_tunnel_details_t * mp)
10477 {
10478   vat_main_t *vam = &vat_main;
10479   ip46_address_t src, dst;
10480
10481   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10482   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10483
10484   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10485          ntohl (mp->sw_if_index),
10486          format_ip46_address, &src, IP46_TYPE_ANY,
10487          format_ip46_address, &dst, IP46_TYPE_ANY,
10488          ntohl (mp->encap_vrf_id),
10489          ntohl (mp->decap_next_index), ntohl (mp->vni),
10490          ntohl (mp->mcast_sw_if_index));
10491 }
10492
10493 static void vl_api_vxlan_tunnel_details_t_handler_json
10494   (vl_api_vxlan_tunnel_details_t * mp)
10495 {
10496   vat_main_t *vam = &vat_main;
10497   vat_json_node_t *node = NULL;
10498
10499   if (VAT_JSON_ARRAY != vam->json_tree.type)
10500     {
10501       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10502       vat_json_init_array (&vam->json_tree);
10503     }
10504   node = vat_json_array_add (&vam->json_tree);
10505
10506   vat_json_init_object (node);
10507   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10508   if (mp->is_ipv6)
10509     {
10510       struct in6_addr ip6;
10511
10512       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10513       vat_json_object_add_ip6 (node, "src_address", ip6);
10514       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10515       vat_json_object_add_ip6 (node, "dst_address", ip6);
10516     }
10517   else
10518     {
10519       struct in_addr ip4;
10520
10521       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10522       vat_json_object_add_ip4 (node, "src_address", ip4);
10523       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10524       vat_json_object_add_ip4 (node, "dst_address", ip4);
10525     }
10526   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10527   vat_json_object_add_uint (node, "decap_next_index",
10528                             ntohl (mp->decap_next_index));
10529   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10530   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10531   vat_json_object_add_uint (node, "mcast_sw_if_index",
10532                             ntohl (mp->mcast_sw_if_index));
10533 }
10534
10535 static int
10536 api_vxlan_tunnel_dump (vat_main_t * vam)
10537 {
10538   unformat_input_t *i = vam->input;
10539   vl_api_vxlan_tunnel_dump_t *mp;
10540   f64 timeout;
10541   u32 sw_if_index;
10542   u8 sw_if_index_set = 0;
10543
10544   /* Parse args required to build the message */
10545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10546     {
10547       if (unformat (i, "sw_if_index %d", &sw_if_index))
10548         sw_if_index_set = 1;
10549       else
10550         break;
10551     }
10552
10553   if (sw_if_index_set == 0)
10554     {
10555       sw_if_index = ~0;
10556     }
10557
10558   if (!vam->json_output)
10559     {
10560       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10561              "sw_if_index", "src_address", "dst_address",
10562              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10563     }
10564
10565   /* Get list of vxlan-tunnel interfaces */
10566   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10567
10568   mp->sw_if_index = htonl (sw_if_index);
10569
10570   S;
10571
10572   /* Use a control ping for synchronization */
10573   {
10574     vl_api_control_ping_t *mp;
10575     M (CONTROL_PING, control_ping);
10576     S;
10577   }
10578   W;
10579 }
10580
10581 static int
10582 api_gre_add_del_tunnel (vat_main_t * vam)
10583 {
10584   unformat_input_t *line_input = vam->input;
10585   vl_api_gre_add_del_tunnel_t *mp;
10586   f64 timeout;
10587   ip4_address_t src4, dst4;
10588   u8 is_add = 1;
10589   u8 teb = 0;
10590   u8 src_set = 0;
10591   u8 dst_set = 0;
10592   u32 outer_fib_id = 0;
10593
10594   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10595     {
10596       if (unformat (line_input, "del"))
10597         is_add = 0;
10598       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10599         src_set = 1;
10600       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10601         dst_set = 1;
10602       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10603         ;
10604       else if (unformat (line_input, "teb"))
10605         teb = 1;
10606       else
10607         {
10608           errmsg ("parse error '%U'", format_unformat_error, line_input);
10609           return -99;
10610         }
10611     }
10612
10613   if (src_set == 0)
10614     {
10615       errmsg ("tunnel src address not specified");
10616       return -99;
10617     }
10618   if (dst_set == 0)
10619     {
10620       errmsg ("tunnel dst address not specified");
10621       return -99;
10622     }
10623
10624
10625   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10626
10627   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10628   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10629   mp->outer_fib_id = ntohl (outer_fib_id);
10630   mp->is_add = is_add;
10631   mp->teb = teb;
10632
10633   S;
10634   W;
10635   /* NOTREACHED */
10636   return 0;
10637 }
10638
10639 static void vl_api_gre_tunnel_details_t_handler
10640   (vl_api_gre_tunnel_details_t * mp)
10641 {
10642   vat_main_t *vam = &vat_main;
10643
10644   print (vam->ofp, "%11d%15U%15U%6d%14d",
10645          ntohl (mp->sw_if_index),
10646          format_ip4_address, &mp->src_address,
10647          format_ip4_address, &mp->dst_address,
10648          mp->teb, ntohl (mp->outer_fib_id));
10649 }
10650
10651 static void vl_api_gre_tunnel_details_t_handler_json
10652   (vl_api_gre_tunnel_details_t * mp)
10653 {
10654   vat_main_t *vam = &vat_main;
10655   vat_json_node_t *node = NULL;
10656   struct in_addr ip4;
10657
10658   if (VAT_JSON_ARRAY != vam->json_tree.type)
10659     {
10660       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10661       vat_json_init_array (&vam->json_tree);
10662     }
10663   node = vat_json_array_add (&vam->json_tree);
10664
10665   vat_json_init_object (node);
10666   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10667   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10668   vat_json_object_add_ip4 (node, "src_address", ip4);
10669   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10670   vat_json_object_add_ip4 (node, "dst_address", ip4);
10671   vat_json_object_add_uint (node, "teb", mp->teb);
10672   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10673 }
10674
10675 static int
10676 api_gre_tunnel_dump (vat_main_t * vam)
10677 {
10678   unformat_input_t *i = vam->input;
10679   vl_api_gre_tunnel_dump_t *mp;
10680   f64 timeout;
10681   u32 sw_if_index;
10682   u8 sw_if_index_set = 0;
10683
10684   /* Parse args required to build the message */
10685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10686     {
10687       if (unformat (i, "sw_if_index %d", &sw_if_index))
10688         sw_if_index_set = 1;
10689       else
10690         break;
10691     }
10692
10693   if (sw_if_index_set == 0)
10694     {
10695       sw_if_index = ~0;
10696     }
10697
10698   if (!vam->json_output)
10699     {
10700       print (vam->ofp, "%11s%15s%15s%6s%14s",
10701              "sw_if_index", "src_address", "dst_address", "teb",
10702              "outer_fib_id");
10703     }
10704
10705   /* Get list of gre-tunnel interfaces */
10706   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10707
10708   mp->sw_if_index = htonl (sw_if_index);
10709
10710   S;
10711
10712   /* Use a control ping for synchronization */
10713   {
10714     vl_api_control_ping_t *mp;
10715     M (CONTROL_PING, control_ping);
10716     S;
10717   }
10718   W;
10719 }
10720
10721 static int
10722 api_l2_fib_clear_table (vat_main_t * vam)
10723 {
10724 //  unformat_input_t * i = vam->input;
10725   vl_api_l2_fib_clear_table_t *mp;
10726   f64 timeout;
10727
10728   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10729
10730   S;
10731   W;
10732   /* NOTREACHED */
10733   return 0;
10734 }
10735
10736 static int
10737 api_l2_interface_efp_filter (vat_main_t * vam)
10738 {
10739   unformat_input_t *i = vam->input;
10740   vl_api_l2_interface_efp_filter_t *mp;
10741   f64 timeout;
10742   u32 sw_if_index;
10743   u8 enable = 1;
10744   u8 sw_if_index_set = 0;
10745
10746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10747     {
10748       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10749         sw_if_index_set = 1;
10750       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10751         sw_if_index_set = 1;
10752       else if (unformat (i, "enable"))
10753         enable = 1;
10754       else if (unformat (i, "disable"))
10755         enable = 0;
10756       else
10757         {
10758           clib_warning ("parse error '%U'", format_unformat_error, i);
10759           return -99;
10760         }
10761     }
10762
10763   if (sw_if_index_set == 0)
10764     {
10765       errmsg ("missing sw_if_index");
10766       return -99;
10767     }
10768
10769   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10770
10771   mp->sw_if_index = ntohl (sw_if_index);
10772   mp->enable_disable = enable;
10773
10774   S;
10775   W;
10776   /* NOTREACHED */
10777   return 0;
10778 }
10779
10780 #define foreach_vtr_op                          \
10781 _("disable",  L2_VTR_DISABLED)                  \
10782 _("push-1",  L2_VTR_PUSH_1)                     \
10783 _("push-2",  L2_VTR_PUSH_2)                     \
10784 _("pop-1",  L2_VTR_POP_1)                       \
10785 _("pop-2",  L2_VTR_POP_2)                       \
10786 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10787 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10788 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10789 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10790
10791 static int
10792 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10793 {
10794   unformat_input_t *i = vam->input;
10795   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10796   f64 timeout;
10797   u32 sw_if_index;
10798   u8 sw_if_index_set = 0;
10799   u8 vtr_op_set = 0;
10800   u32 vtr_op = 0;
10801   u32 push_dot1q = 1;
10802   u32 tag1 = ~0;
10803   u32 tag2 = ~0;
10804
10805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10806     {
10807       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10808         sw_if_index_set = 1;
10809       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10810         sw_if_index_set = 1;
10811       else if (unformat (i, "vtr_op %d", &vtr_op))
10812         vtr_op_set = 1;
10813 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10814       foreach_vtr_op
10815 #undef _
10816         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10817         ;
10818       else if (unformat (i, "tag1 %d", &tag1))
10819         ;
10820       else if (unformat (i, "tag2 %d", &tag2))
10821         ;
10822       else
10823         {
10824           clib_warning ("parse error '%U'", format_unformat_error, i);
10825           return -99;
10826         }
10827     }
10828
10829   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10830     {
10831       errmsg ("missing vtr operation or sw_if_index");
10832       return -99;
10833     }
10834
10835   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10836     mp->sw_if_index = ntohl (sw_if_index);
10837   mp->vtr_op = ntohl (vtr_op);
10838   mp->push_dot1q = ntohl (push_dot1q);
10839   mp->tag1 = ntohl (tag1);
10840   mp->tag2 = ntohl (tag2);
10841
10842   S;
10843   W;
10844   /* NOTREACHED */
10845   return 0;
10846 }
10847
10848 static int
10849 api_create_vhost_user_if (vat_main_t * vam)
10850 {
10851   unformat_input_t *i = vam->input;
10852   vl_api_create_vhost_user_if_t *mp;
10853   f64 timeout;
10854   u8 *file_name;
10855   u8 is_server = 0;
10856   u8 file_name_set = 0;
10857   u32 custom_dev_instance = ~0;
10858   u8 hwaddr[6];
10859   u8 use_custom_mac = 0;
10860   u8 *tag = 0;
10861
10862   /* Shut up coverity */
10863   memset (hwaddr, 0, sizeof (hwaddr));
10864
10865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10866     {
10867       if (unformat (i, "socket %s", &file_name))
10868         {
10869           file_name_set = 1;
10870         }
10871       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10872         ;
10873       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10874         use_custom_mac = 1;
10875       else if (unformat (i, "server"))
10876         is_server = 1;
10877       else if (unformat (i, "tag %s", &tag))
10878         ;
10879       else
10880         break;
10881     }
10882
10883   if (file_name_set == 0)
10884     {
10885       errmsg ("missing socket file name");
10886       return -99;
10887     }
10888
10889   if (vec_len (file_name) > 255)
10890     {
10891       errmsg ("socket file name too long");
10892       return -99;
10893     }
10894   vec_add1 (file_name, 0);
10895
10896   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10897
10898   mp->is_server = is_server;
10899   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10900   vec_free (file_name);
10901   if (custom_dev_instance != ~0)
10902     {
10903       mp->renumber = 1;
10904       mp->custom_dev_instance = ntohl (custom_dev_instance);
10905     }
10906   mp->use_custom_mac = use_custom_mac;
10907   clib_memcpy (mp->mac_address, hwaddr, 6);
10908   if (tag)
10909     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10910   vec_free (tag);
10911
10912   S;
10913   W;
10914   /* NOTREACHED */
10915   return 0;
10916 }
10917
10918 static int
10919 api_modify_vhost_user_if (vat_main_t * vam)
10920 {
10921   unformat_input_t *i = vam->input;
10922   vl_api_modify_vhost_user_if_t *mp;
10923   f64 timeout;
10924   u8 *file_name;
10925   u8 is_server = 0;
10926   u8 file_name_set = 0;
10927   u32 custom_dev_instance = ~0;
10928   u8 sw_if_index_set = 0;
10929   u32 sw_if_index = (u32) ~ 0;
10930
10931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10932     {
10933       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10934         sw_if_index_set = 1;
10935       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10936         sw_if_index_set = 1;
10937       else if (unformat (i, "socket %s", &file_name))
10938         {
10939           file_name_set = 1;
10940         }
10941       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10942         ;
10943       else if (unformat (i, "server"))
10944         is_server = 1;
10945       else
10946         break;
10947     }
10948
10949   if (sw_if_index_set == 0)
10950     {
10951       errmsg ("missing sw_if_index or interface name");
10952       return -99;
10953     }
10954
10955   if (file_name_set == 0)
10956     {
10957       errmsg ("missing socket file name");
10958       return -99;
10959     }
10960
10961   if (vec_len (file_name) > 255)
10962     {
10963       errmsg ("socket file name too long");
10964       return -99;
10965     }
10966   vec_add1 (file_name, 0);
10967
10968   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10969
10970   mp->sw_if_index = ntohl (sw_if_index);
10971   mp->is_server = is_server;
10972   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10973   vec_free (file_name);
10974   if (custom_dev_instance != ~0)
10975     {
10976       mp->renumber = 1;
10977       mp->custom_dev_instance = ntohl (custom_dev_instance);
10978     }
10979
10980   S;
10981   W;
10982   /* NOTREACHED */
10983   return 0;
10984 }
10985
10986 static int
10987 api_delete_vhost_user_if (vat_main_t * vam)
10988 {
10989   unformat_input_t *i = vam->input;
10990   vl_api_delete_vhost_user_if_t *mp;
10991   f64 timeout;
10992   u32 sw_if_index = ~0;
10993   u8 sw_if_index_set = 0;
10994
10995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10996     {
10997       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10998         sw_if_index_set = 1;
10999       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11000         sw_if_index_set = 1;
11001       else
11002         break;
11003     }
11004
11005   if (sw_if_index_set == 0)
11006     {
11007       errmsg ("missing sw_if_index or interface name");
11008       return -99;
11009     }
11010
11011
11012   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
11013
11014   mp->sw_if_index = ntohl (sw_if_index);
11015
11016   S;
11017   W;
11018   /* NOTREACHED */
11019   return 0;
11020 }
11021
11022 static void vl_api_sw_interface_vhost_user_details_t_handler
11023   (vl_api_sw_interface_vhost_user_details_t * mp)
11024 {
11025   vat_main_t *vam = &vat_main;
11026
11027   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11028          (char *) mp->interface_name,
11029          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11030          clib_net_to_host_u64 (mp->features), mp->is_server,
11031          ntohl (mp->num_regions), (char *) mp->sock_filename);
11032   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11033 }
11034
11035 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11036   (vl_api_sw_interface_vhost_user_details_t * mp)
11037 {
11038   vat_main_t *vam = &vat_main;
11039   vat_json_node_t *node = NULL;
11040
11041   if (VAT_JSON_ARRAY != vam->json_tree.type)
11042     {
11043       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11044       vat_json_init_array (&vam->json_tree);
11045     }
11046   node = vat_json_array_add (&vam->json_tree);
11047
11048   vat_json_init_object (node);
11049   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11050   vat_json_object_add_string_copy (node, "interface_name",
11051                                    mp->interface_name);
11052   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11053                             ntohl (mp->virtio_net_hdr_sz));
11054   vat_json_object_add_uint (node, "features",
11055                             clib_net_to_host_u64 (mp->features));
11056   vat_json_object_add_uint (node, "is_server", mp->is_server);
11057   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11058   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11059   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11060 }
11061
11062 static int
11063 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11064 {
11065   vl_api_sw_interface_vhost_user_dump_t *mp;
11066   f64 timeout;
11067   print (vam->ofp,
11068          "Interface name           idx hdr_sz features server regions filename");
11069
11070   /* Get list of vhost-user interfaces */
11071   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
11072   S;
11073
11074   /* Use a control ping for synchronization */
11075   {
11076     vl_api_control_ping_t *mp;
11077     M (CONTROL_PING, control_ping);
11078     S;
11079   }
11080   W;
11081 }
11082
11083 static int
11084 api_show_version (vat_main_t * vam)
11085 {
11086   vl_api_show_version_t *mp;
11087   f64 timeout;
11088
11089   M (SHOW_VERSION, show_version);
11090
11091   S;
11092   W;
11093   /* NOTREACHED */
11094   return 0;
11095 }
11096
11097
11098 static int
11099 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11100 {
11101   unformat_input_t *line_input = vam->input;
11102   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11103   f64 timeout;
11104   ip4_address_t local4, remote4;
11105   ip6_address_t local6, remote6;
11106   u8 is_add = 1;
11107   u8 ipv4_set = 0, ipv6_set = 0;
11108   u8 local_set = 0;
11109   u8 remote_set = 0;
11110   u32 encap_vrf_id = 0;
11111   u32 decap_vrf_id = 0;
11112   u8 protocol = ~0;
11113   u32 vni;
11114   u8 vni_set = 0;
11115
11116   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11117     {
11118       if (unformat (line_input, "del"))
11119         is_add = 0;
11120       else if (unformat (line_input, "local %U",
11121                          unformat_ip4_address, &local4))
11122         {
11123           local_set = 1;
11124           ipv4_set = 1;
11125         }
11126       else if (unformat (line_input, "remote %U",
11127                          unformat_ip4_address, &remote4))
11128         {
11129           remote_set = 1;
11130           ipv4_set = 1;
11131         }
11132       else if (unformat (line_input, "local %U",
11133                          unformat_ip6_address, &local6))
11134         {
11135           local_set = 1;
11136           ipv6_set = 1;
11137         }
11138       else if (unformat (line_input, "remote %U",
11139                          unformat_ip6_address, &remote6))
11140         {
11141           remote_set = 1;
11142           ipv6_set = 1;
11143         }
11144       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11145         ;
11146       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11147         ;
11148       else if (unformat (line_input, "vni %d", &vni))
11149         vni_set = 1;
11150       else if (unformat (line_input, "next-ip4"))
11151         protocol = 1;
11152       else if (unformat (line_input, "next-ip6"))
11153         protocol = 2;
11154       else if (unformat (line_input, "next-ethernet"))
11155         protocol = 3;
11156       else if (unformat (line_input, "next-nsh"))
11157         protocol = 4;
11158       else
11159         {
11160           errmsg ("parse error '%U'", format_unformat_error, line_input);
11161           return -99;
11162         }
11163     }
11164
11165   if (local_set == 0)
11166     {
11167       errmsg ("tunnel local address not specified");
11168       return -99;
11169     }
11170   if (remote_set == 0)
11171     {
11172       errmsg ("tunnel remote address not specified");
11173       return -99;
11174     }
11175   if (ipv4_set && ipv6_set)
11176     {
11177       errmsg ("both IPv4 and IPv6 addresses specified");
11178       return -99;
11179     }
11180
11181   if (vni_set == 0)
11182     {
11183       errmsg ("vni not specified");
11184       return -99;
11185     }
11186
11187   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
11188
11189
11190   if (ipv6_set)
11191     {
11192       clib_memcpy (&mp->local, &local6, sizeof (local6));
11193       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11194     }
11195   else
11196     {
11197       clib_memcpy (&mp->local, &local4, sizeof (local4));
11198       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11199     }
11200
11201   mp->encap_vrf_id = ntohl (encap_vrf_id);
11202   mp->decap_vrf_id = ntohl (decap_vrf_id);
11203   mp->protocol = protocol;
11204   mp->vni = ntohl (vni);
11205   mp->is_add = is_add;
11206   mp->is_ipv6 = ipv6_set;
11207
11208   S;
11209   W;
11210   /* NOTREACHED */
11211   return 0;
11212 }
11213
11214 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11215   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11216 {
11217   vat_main_t *vam = &vat_main;
11218
11219   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11220          ntohl (mp->sw_if_index),
11221          format_ip46_address, &(mp->local[0]),
11222          format_ip46_address, &(mp->remote[0]),
11223          ntohl (mp->vni),
11224          ntohl (mp->protocol),
11225          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11226 }
11227
11228 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11229   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11230 {
11231   vat_main_t *vam = &vat_main;
11232   vat_json_node_t *node = NULL;
11233   struct in_addr ip4;
11234   struct in6_addr ip6;
11235
11236   if (VAT_JSON_ARRAY != vam->json_tree.type)
11237     {
11238       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11239       vat_json_init_array (&vam->json_tree);
11240     }
11241   node = vat_json_array_add (&vam->json_tree);
11242
11243   vat_json_init_object (node);
11244   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11245   if (mp->is_ipv6)
11246     {
11247       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11248       vat_json_object_add_ip6 (node, "local", ip6);
11249       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11250       vat_json_object_add_ip6 (node, "remote", ip6);
11251     }
11252   else
11253     {
11254       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11255       vat_json_object_add_ip4 (node, "local", ip4);
11256       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11257       vat_json_object_add_ip4 (node, "remote", ip4);
11258     }
11259   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11260   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11261   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11262   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11263   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11264 }
11265
11266 static int
11267 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11268 {
11269   unformat_input_t *i = vam->input;
11270   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11271   f64 timeout;
11272   u32 sw_if_index;
11273   u8 sw_if_index_set = 0;
11274
11275   /* Parse args required to build the message */
11276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11277     {
11278       if (unformat (i, "sw_if_index %d", &sw_if_index))
11279         sw_if_index_set = 1;
11280       else
11281         break;
11282     }
11283
11284   if (sw_if_index_set == 0)
11285     {
11286       sw_if_index = ~0;
11287     }
11288
11289   if (!vam->json_output)
11290     {
11291       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11292              "sw_if_index", "local", "remote", "vni",
11293              "protocol", "encap_vrf_id", "decap_vrf_id");
11294     }
11295
11296   /* Get list of vxlan-tunnel interfaces */
11297   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11298
11299   mp->sw_if_index = htonl (sw_if_index);
11300
11301   S;
11302
11303   /* Use a control ping for synchronization */
11304   {
11305     vl_api_control_ping_t *mp;
11306     M (CONTROL_PING, control_ping);
11307     S;
11308   }
11309   W;
11310 }
11311
11312 u8 *
11313 format_l2_fib_mac_address (u8 * s, va_list * args)
11314 {
11315   u8 *a = va_arg (*args, u8 *);
11316
11317   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11318                  a[2], a[3], a[4], a[5], a[6], a[7]);
11319 }
11320
11321 static void vl_api_l2_fib_table_entry_t_handler
11322   (vl_api_l2_fib_table_entry_t * mp)
11323 {
11324   vat_main_t *vam = &vat_main;
11325
11326   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11327          "       %d       %d     %d",
11328          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11329          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11330          mp->bvi_mac);
11331 }
11332
11333 static void vl_api_l2_fib_table_entry_t_handler_json
11334   (vl_api_l2_fib_table_entry_t * mp)
11335 {
11336   vat_main_t *vam = &vat_main;
11337   vat_json_node_t *node = NULL;
11338
11339   if (VAT_JSON_ARRAY != vam->json_tree.type)
11340     {
11341       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11342       vat_json_init_array (&vam->json_tree);
11343     }
11344   node = vat_json_array_add (&vam->json_tree);
11345
11346   vat_json_init_object (node);
11347   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11348   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11349   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11350   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11351   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11352   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11353 }
11354
11355 static int
11356 api_l2_fib_table_dump (vat_main_t * vam)
11357 {
11358   unformat_input_t *i = vam->input;
11359   vl_api_l2_fib_table_dump_t *mp;
11360   f64 timeout;
11361   u32 bd_id;
11362   u8 bd_id_set = 0;
11363
11364   /* Parse args required to build the message */
11365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11366     {
11367       if (unformat (i, "bd_id %d", &bd_id))
11368         bd_id_set = 1;
11369       else
11370         break;
11371     }
11372
11373   if (bd_id_set == 0)
11374     {
11375       errmsg ("missing bridge domain");
11376       return -99;
11377     }
11378
11379   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11380
11381   /* Get list of l2 fib entries */
11382   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11383
11384   mp->bd_id = ntohl (bd_id);
11385   S;
11386
11387   /* Use a control ping for synchronization */
11388   {
11389     vl_api_control_ping_t *mp;
11390     M (CONTROL_PING, control_ping);
11391     S;
11392   }
11393   W;
11394 }
11395
11396
11397 static int
11398 api_interface_name_renumber (vat_main_t * vam)
11399 {
11400   unformat_input_t *line_input = vam->input;
11401   vl_api_interface_name_renumber_t *mp;
11402   u32 sw_if_index = ~0;
11403   f64 timeout;
11404   u32 new_show_dev_instance = ~0;
11405
11406   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11407     {
11408       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11409                     &sw_if_index))
11410         ;
11411       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11412         ;
11413       else if (unformat (line_input, "new_show_dev_instance %d",
11414                          &new_show_dev_instance))
11415         ;
11416       else
11417         break;
11418     }
11419
11420   if (sw_if_index == ~0)
11421     {
11422       errmsg ("missing interface name or sw_if_index");
11423       return -99;
11424     }
11425
11426   if (new_show_dev_instance == ~0)
11427     {
11428       errmsg ("missing new_show_dev_instance");
11429       return -99;
11430     }
11431
11432   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11433
11434   mp->sw_if_index = ntohl (sw_if_index);
11435   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11436
11437   S;
11438   W;
11439 }
11440
11441 static int
11442 api_want_ip4_arp_events (vat_main_t * vam)
11443 {
11444   unformat_input_t *line_input = vam->input;
11445   vl_api_want_ip4_arp_events_t *mp;
11446   f64 timeout;
11447   ip4_address_t address;
11448   int address_set = 0;
11449   u32 enable_disable = 1;
11450
11451   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11452     {
11453       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11454         address_set = 1;
11455       else if (unformat (line_input, "del"))
11456         enable_disable = 0;
11457       else
11458         break;
11459     }
11460
11461   if (address_set == 0)
11462     {
11463       errmsg ("missing addresses");
11464       return -99;
11465     }
11466
11467   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11468   mp->enable_disable = enable_disable;
11469   mp->pid = getpid ();
11470   mp->address = address.as_u32;
11471
11472   S;
11473   W;
11474 }
11475
11476 static int
11477 api_want_ip6_nd_events (vat_main_t * vam)
11478 {
11479   unformat_input_t *line_input = vam->input;
11480   vl_api_want_ip6_nd_events_t *mp;
11481   f64 timeout;
11482   ip6_address_t address;
11483   int address_set = 0;
11484   u32 enable_disable = 1;
11485
11486   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11487     {
11488       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11489         address_set = 1;
11490       else if (unformat (line_input, "del"))
11491         enable_disable = 0;
11492       else
11493         break;
11494     }
11495
11496   if (address_set == 0)
11497     {
11498       errmsg ("missing addresses");
11499       return -99;
11500     }
11501
11502   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11503   mp->enable_disable = enable_disable;
11504   mp->pid = getpid ();
11505   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11506
11507   S;
11508   W;
11509 }
11510
11511 static int
11512 api_input_acl_set_interface (vat_main_t * vam)
11513 {
11514   unformat_input_t *i = vam->input;
11515   vl_api_input_acl_set_interface_t *mp;
11516   f64 timeout;
11517   u32 sw_if_index;
11518   int sw_if_index_set;
11519   u32 ip4_table_index = ~0;
11520   u32 ip6_table_index = ~0;
11521   u32 l2_table_index = ~0;
11522   u8 is_add = 1;
11523
11524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11525     {
11526       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11527         sw_if_index_set = 1;
11528       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11529         sw_if_index_set = 1;
11530       else if (unformat (i, "del"))
11531         is_add = 0;
11532       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11533         ;
11534       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11535         ;
11536       else if (unformat (i, "l2-table %d", &l2_table_index))
11537         ;
11538       else
11539         {
11540           clib_warning ("parse error '%U'", format_unformat_error, i);
11541           return -99;
11542         }
11543     }
11544
11545   if (sw_if_index_set == 0)
11546     {
11547       errmsg ("missing interface name or sw_if_index");
11548       return -99;
11549     }
11550
11551   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11552
11553   mp->sw_if_index = ntohl (sw_if_index);
11554   mp->ip4_table_index = ntohl (ip4_table_index);
11555   mp->ip6_table_index = ntohl (ip6_table_index);
11556   mp->l2_table_index = ntohl (l2_table_index);
11557   mp->is_add = is_add;
11558
11559   S;
11560   W;
11561   /* NOTREACHED */
11562   return 0;
11563 }
11564
11565 static int
11566 api_ip_address_dump (vat_main_t * vam)
11567 {
11568   unformat_input_t *i = vam->input;
11569   vl_api_ip_address_dump_t *mp;
11570   u32 sw_if_index = ~0;
11571   u8 sw_if_index_set = 0;
11572   u8 ipv4_set = 0;
11573   u8 ipv6_set = 0;
11574   f64 timeout;
11575
11576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11577     {
11578       if (unformat (i, "sw_if_index %d", &sw_if_index))
11579         sw_if_index_set = 1;
11580       else
11581         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11582         sw_if_index_set = 1;
11583       else if (unformat (i, "ipv4"))
11584         ipv4_set = 1;
11585       else if (unformat (i, "ipv6"))
11586         ipv6_set = 1;
11587       else
11588         break;
11589     }
11590
11591   if (ipv4_set && ipv6_set)
11592     {
11593       errmsg ("ipv4 and ipv6 flags cannot be both set");
11594       return -99;
11595     }
11596
11597   if ((!ipv4_set) && (!ipv6_set))
11598     {
11599       errmsg ("no ipv4 nor ipv6 flag set");
11600       return -99;
11601     }
11602
11603   if (sw_if_index_set == 0)
11604     {
11605       errmsg ("missing interface name or sw_if_index");
11606       return -99;
11607     }
11608
11609   vam->current_sw_if_index = sw_if_index;
11610   vam->is_ipv6 = ipv6_set;
11611
11612   M (IP_ADDRESS_DUMP, ip_address_dump);
11613   mp->sw_if_index = ntohl (sw_if_index);
11614   mp->is_ipv6 = ipv6_set;
11615   S;
11616
11617   /* Use a control ping for synchronization */
11618   {
11619     vl_api_control_ping_t *mp;
11620     M (CONTROL_PING, control_ping);
11621     S;
11622   }
11623   W;
11624 }
11625
11626 static int
11627 api_ip_dump (vat_main_t * vam)
11628 {
11629   vl_api_ip_dump_t *mp;
11630   unformat_input_t *in = vam->input;
11631   int ipv4_set = 0;
11632   int ipv6_set = 0;
11633   int is_ipv6;
11634   f64 timeout;
11635   int i;
11636
11637   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11638     {
11639       if (unformat (in, "ipv4"))
11640         ipv4_set = 1;
11641       else if (unformat (in, "ipv6"))
11642         ipv6_set = 1;
11643       else
11644         break;
11645     }
11646
11647   if (ipv4_set && ipv6_set)
11648     {
11649       errmsg ("ipv4 and ipv6 flags cannot be both set");
11650       return -99;
11651     }
11652
11653   if ((!ipv4_set) && (!ipv6_set))
11654     {
11655       errmsg ("no ipv4 nor ipv6 flag set");
11656       return -99;
11657     }
11658
11659   is_ipv6 = ipv6_set;
11660   vam->is_ipv6 = is_ipv6;
11661
11662   /* free old data */
11663   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11664     {
11665       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11666     }
11667   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11668
11669   M (IP_DUMP, ip_dump);
11670   mp->is_ipv6 = ipv6_set;
11671   S;
11672
11673   /* Use a control ping for synchronization */
11674   {
11675     vl_api_control_ping_t *mp;
11676     M (CONTROL_PING, control_ping);
11677     S;
11678   }
11679   W;
11680 }
11681
11682 static int
11683 api_ipsec_spd_add_del (vat_main_t * vam)
11684 {
11685   unformat_input_t *i = vam->input;
11686   vl_api_ipsec_spd_add_del_t *mp;
11687   f64 timeout;
11688   u32 spd_id = ~0;
11689   u8 is_add = 1;
11690
11691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11692     {
11693       if (unformat (i, "spd_id %d", &spd_id))
11694         ;
11695       else if (unformat (i, "del"))
11696         is_add = 0;
11697       else
11698         {
11699           clib_warning ("parse error '%U'", format_unformat_error, i);
11700           return -99;
11701         }
11702     }
11703   if (spd_id == ~0)
11704     {
11705       errmsg ("spd_id must be set");
11706       return -99;
11707     }
11708
11709   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11710
11711   mp->spd_id = ntohl (spd_id);
11712   mp->is_add = is_add;
11713
11714   S;
11715   W;
11716   /* NOTREACHED */
11717   return 0;
11718 }
11719
11720 static int
11721 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11722 {
11723   unformat_input_t *i = vam->input;
11724   vl_api_ipsec_interface_add_del_spd_t *mp;
11725   f64 timeout;
11726   u32 sw_if_index;
11727   u8 sw_if_index_set = 0;
11728   u32 spd_id = (u32) ~ 0;
11729   u8 is_add = 1;
11730
11731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11732     {
11733       if (unformat (i, "del"))
11734         is_add = 0;
11735       else if (unformat (i, "spd_id %d", &spd_id))
11736         ;
11737       else
11738         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11739         sw_if_index_set = 1;
11740       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11741         sw_if_index_set = 1;
11742       else
11743         {
11744           clib_warning ("parse error '%U'", format_unformat_error, i);
11745           return -99;
11746         }
11747
11748     }
11749
11750   if (spd_id == (u32) ~ 0)
11751     {
11752       errmsg ("spd_id must be set");
11753       return -99;
11754     }
11755
11756   if (sw_if_index_set == 0)
11757     {
11758       errmsg ("missing interface name or sw_if_index");
11759       return -99;
11760     }
11761
11762   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11763
11764   mp->spd_id = ntohl (spd_id);
11765   mp->sw_if_index = ntohl (sw_if_index);
11766   mp->is_add = is_add;
11767
11768   S;
11769   W;
11770   /* NOTREACHED */
11771   return 0;
11772 }
11773
11774 static int
11775 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11776 {
11777   unformat_input_t *i = vam->input;
11778   vl_api_ipsec_spd_add_del_entry_t *mp;
11779   f64 timeout;
11780   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11781   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11782   i32 priority = 0;
11783   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11784   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11785   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11786   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11787
11788   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11789   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11790   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11791   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11792   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11793   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11794
11795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11796     {
11797       if (unformat (i, "del"))
11798         is_add = 0;
11799       if (unformat (i, "outbound"))
11800         is_outbound = 1;
11801       if (unformat (i, "inbound"))
11802         is_outbound = 0;
11803       else if (unformat (i, "spd_id %d", &spd_id))
11804         ;
11805       else if (unformat (i, "sa_id %d", &sa_id))
11806         ;
11807       else if (unformat (i, "priority %d", &priority))
11808         ;
11809       else if (unformat (i, "protocol %d", &protocol))
11810         ;
11811       else if (unformat (i, "lport_start %d", &lport_start))
11812         ;
11813       else if (unformat (i, "lport_stop %d", &lport_stop))
11814         ;
11815       else if (unformat (i, "rport_start %d", &rport_start))
11816         ;
11817       else if (unformat (i, "rport_stop %d", &rport_stop))
11818         ;
11819       else
11820         if (unformat
11821             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11822         {
11823           is_ipv6 = 0;
11824           is_ip_any = 0;
11825         }
11826       else
11827         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11828         {
11829           is_ipv6 = 0;
11830           is_ip_any = 0;
11831         }
11832       else
11833         if (unformat
11834             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11835         {
11836           is_ipv6 = 0;
11837           is_ip_any = 0;
11838         }
11839       else
11840         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11841         {
11842           is_ipv6 = 0;
11843           is_ip_any = 0;
11844         }
11845       else
11846         if (unformat
11847             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11848         {
11849           is_ipv6 = 1;
11850           is_ip_any = 0;
11851         }
11852       else
11853         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11854         {
11855           is_ipv6 = 1;
11856           is_ip_any = 0;
11857         }
11858       else
11859         if (unformat
11860             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11861         {
11862           is_ipv6 = 1;
11863           is_ip_any = 0;
11864         }
11865       else
11866         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11867         {
11868           is_ipv6 = 1;
11869           is_ip_any = 0;
11870         }
11871       else
11872         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11873         {
11874           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11875             {
11876               clib_warning ("unsupported action: 'resolve'");
11877               return -99;
11878             }
11879         }
11880       else
11881         {
11882           clib_warning ("parse error '%U'", format_unformat_error, i);
11883           return -99;
11884         }
11885
11886     }
11887
11888   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11889
11890   mp->spd_id = ntohl (spd_id);
11891   mp->priority = ntohl (priority);
11892   mp->is_outbound = is_outbound;
11893
11894   mp->is_ipv6 = is_ipv6;
11895   if (is_ipv6 || is_ip_any)
11896     {
11897       clib_memcpy (mp->remote_address_start, &raddr6_start,
11898                    sizeof (ip6_address_t));
11899       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11900                    sizeof (ip6_address_t));
11901       clib_memcpy (mp->local_address_start, &laddr6_start,
11902                    sizeof (ip6_address_t));
11903       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11904                    sizeof (ip6_address_t));
11905     }
11906   else
11907     {
11908       clib_memcpy (mp->remote_address_start, &raddr4_start,
11909                    sizeof (ip4_address_t));
11910       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11911                    sizeof (ip4_address_t));
11912       clib_memcpy (mp->local_address_start, &laddr4_start,
11913                    sizeof (ip4_address_t));
11914       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11915                    sizeof (ip4_address_t));
11916     }
11917   mp->protocol = (u8) protocol;
11918   mp->local_port_start = ntohs ((u16) lport_start);
11919   mp->local_port_stop = ntohs ((u16) lport_stop);
11920   mp->remote_port_start = ntohs ((u16) rport_start);
11921   mp->remote_port_stop = ntohs ((u16) rport_stop);
11922   mp->policy = (u8) policy;
11923   mp->sa_id = ntohl (sa_id);
11924   mp->is_add = is_add;
11925   mp->is_ip_any = is_ip_any;
11926   S;
11927   W;
11928   /* NOTREACHED */
11929   return 0;
11930 }
11931
11932 static int
11933 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11934 {
11935   unformat_input_t *i = vam->input;
11936   vl_api_ipsec_sad_add_del_entry_t *mp;
11937   f64 timeout;
11938   u32 sad_id = 0, spi = 0;
11939   u8 *ck = 0, *ik = 0;
11940   u8 is_add = 1;
11941
11942   u8 protocol = IPSEC_PROTOCOL_AH;
11943   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11944   u32 crypto_alg = 0, integ_alg = 0;
11945   ip4_address_t tun_src4;
11946   ip4_address_t tun_dst4;
11947   ip6_address_t tun_src6;
11948   ip6_address_t tun_dst6;
11949
11950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11951     {
11952       if (unformat (i, "del"))
11953         is_add = 0;
11954       else if (unformat (i, "sad_id %d", &sad_id))
11955         ;
11956       else if (unformat (i, "spi %d", &spi))
11957         ;
11958       else if (unformat (i, "esp"))
11959         protocol = IPSEC_PROTOCOL_ESP;
11960       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11961         {
11962           is_tunnel = 1;
11963           is_tunnel_ipv6 = 0;
11964         }
11965       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11966         {
11967           is_tunnel = 1;
11968           is_tunnel_ipv6 = 0;
11969         }
11970       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11971         {
11972           is_tunnel = 1;
11973           is_tunnel_ipv6 = 1;
11974         }
11975       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11976         {
11977           is_tunnel = 1;
11978           is_tunnel_ipv6 = 1;
11979         }
11980       else
11981         if (unformat
11982             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11983         {
11984           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11985               crypto_alg >= IPSEC_CRYPTO_N_ALG)
11986             {
11987               clib_warning ("unsupported crypto-alg: '%U'",
11988                             format_ipsec_crypto_alg, crypto_alg);
11989               return -99;
11990             }
11991         }
11992       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11993         ;
11994       else
11995         if (unformat
11996             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11997         {
11998 #if DPDK_CRYPTO==1
11999           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
12000 #else
12001           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12002 #endif
12003               integ_alg >= IPSEC_INTEG_N_ALG)
12004             {
12005               clib_warning ("unsupported integ-alg: '%U'",
12006                             format_ipsec_integ_alg, integ_alg);
12007               return -99;
12008             }
12009         }
12010       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12011         ;
12012       else
12013         {
12014           clib_warning ("parse error '%U'", format_unformat_error, i);
12015           return -99;
12016         }
12017
12018     }
12019
12020 #if DPDK_CRYPTO==1
12021   /*Special cases, aes-gcm-128 encryption */
12022   if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
12023     {
12024       if (integ_alg != IPSEC_INTEG_ALG_NONE
12025           && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
12026         {
12027           clib_warning
12028             ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
12029           return -99;
12030         }
12031       else                      /*set integ-alg internally to aes-gcm-128 */
12032         integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
12033     }
12034   else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
12035     {
12036       clib_warning ("unsupported integ-alg: aes-gcm-128");
12037       return -99;
12038     }
12039   else if (integ_alg == IPSEC_INTEG_ALG_NONE)
12040     {
12041       clib_warning ("unsupported integ-alg: none");
12042       return -99;
12043     }
12044 #endif
12045
12046
12047   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
12048
12049   mp->sad_id = ntohl (sad_id);
12050   mp->is_add = is_add;
12051   mp->protocol = protocol;
12052   mp->spi = ntohl (spi);
12053   mp->is_tunnel = is_tunnel;
12054   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12055   mp->crypto_algorithm = crypto_alg;
12056   mp->integrity_algorithm = integ_alg;
12057   mp->crypto_key_length = vec_len (ck);
12058   mp->integrity_key_length = vec_len (ik);
12059
12060   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12061     mp->crypto_key_length = sizeof (mp->crypto_key);
12062
12063   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12064     mp->integrity_key_length = sizeof (mp->integrity_key);
12065
12066   if (ck)
12067     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12068   if (ik)
12069     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12070
12071   if (is_tunnel)
12072     {
12073       if (is_tunnel_ipv6)
12074         {
12075           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12076                        sizeof (ip6_address_t));
12077           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12078                        sizeof (ip6_address_t));
12079         }
12080       else
12081         {
12082           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12083                        sizeof (ip4_address_t));
12084           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12085                        sizeof (ip4_address_t));
12086         }
12087     }
12088
12089   S;
12090   W;
12091   /* NOTREACHED */
12092   return 0;
12093 }
12094
12095 static int
12096 api_ipsec_sa_set_key (vat_main_t * vam)
12097 {
12098   unformat_input_t *i = vam->input;
12099   vl_api_ipsec_sa_set_key_t *mp;
12100   f64 timeout;
12101   u32 sa_id;
12102   u8 *ck = 0, *ik = 0;
12103
12104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12105     {
12106       if (unformat (i, "sa_id %d", &sa_id))
12107         ;
12108       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12109         ;
12110       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12111         ;
12112       else
12113         {
12114           clib_warning ("parse error '%U'", format_unformat_error, i);
12115           return -99;
12116         }
12117     }
12118
12119   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
12120
12121   mp->sa_id = ntohl (sa_id);
12122   mp->crypto_key_length = vec_len (ck);
12123   mp->integrity_key_length = vec_len (ik);
12124
12125   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12126     mp->crypto_key_length = sizeof (mp->crypto_key);
12127
12128   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12129     mp->integrity_key_length = sizeof (mp->integrity_key);
12130
12131   if (ck)
12132     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12133   if (ik)
12134     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12135
12136   S;
12137   W;
12138   /* NOTREACHED */
12139   return 0;
12140 }
12141
12142 static int
12143 api_ikev2_profile_add_del (vat_main_t * vam)
12144 {
12145   unformat_input_t *i = vam->input;
12146   vl_api_ikev2_profile_add_del_t *mp;
12147   f64 timeout;
12148   u8 is_add = 1;
12149   u8 *name = 0;
12150
12151   const char *valid_chars = "a-zA-Z0-9_";
12152
12153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12154     {
12155       if (unformat (i, "del"))
12156         is_add = 0;
12157       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12158         vec_add1 (name, 0);
12159       else
12160         {
12161           errmsg ("parse error '%U'", format_unformat_error, i);
12162           return -99;
12163         }
12164     }
12165
12166   if (!vec_len (name))
12167     {
12168       errmsg ("profile name must be specified");
12169       return -99;
12170     }
12171
12172   if (vec_len (name) > 64)
12173     {
12174       errmsg ("profile name too long");
12175       return -99;
12176     }
12177
12178   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
12179
12180   clib_memcpy (mp->name, name, vec_len (name));
12181   mp->is_add = is_add;
12182   vec_free (name);
12183
12184   S;
12185   W;
12186   /* NOTREACHED */
12187   return 0;
12188 }
12189
12190 static int
12191 api_ikev2_profile_set_auth (vat_main_t * vam)
12192 {
12193   unformat_input_t *i = vam->input;
12194   vl_api_ikev2_profile_set_auth_t *mp;
12195   f64 timeout;
12196   u8 *name = 0;
12197   u8 *data = 0;
12198   u32 auth_method = 0;
12199   u8 is_hex = 0;
12200
12201   const char *valid_chars = "a-zA-Z0-9_";
12202
12203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12204     {
12205       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12206         vec_add1 (name, 0);
12207       else if (unformat (i, "auth_method %U",
12208                          unformat_ikev2_auth_method, &auth_method))
12209         ;
12210       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12211         is_hex = 1;
12212       else if (unformat (i, "auth_data %v", &data))
12213         ;
12214       else
12215         {
12216           errmsg ("parse error '%U'", format_unformat_error, i);
12217           return -99;
12218         }
12219     }
12220
12221   if (!vec_len (name))
12222     {
12223       errmsg ("profile name must be specified");
12224       return -99;
12225     }
12226
12227   if (vec_len (name) > 64)
12228     {
12229       errmsg ("profile name too long");
12230       return -99;
12231     }
12232
12233   if (!vec_len (data))
12234     {
12235       errmsg ("auth_data must be specified");
12236       return -99;
12237     }
12238
12239   if (!auth_method)
12240     {
12241       errmsg ("auth_method must be specified");
12242       return -99;
12243     }
12244
12245   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12246
12247   mp->is_hex = is_hex;
12248   mp->auth_method = (u8) auth_method;
12249   mp->data_len = vec_len (data);
12250   clib_memcpy (mp->name, name, vec_len (name));
12251   clib_memcpy (mp->data, data, vec_len (data));
12252   vec_free (name);
12253   vec_free (data);
12254
12255   S;
12256   W;
12257   /* NOTREACHED */
12258   return 0;
12259 }
12260
12261 static int
12262 api_ikev2_profile_set_id (vat_main_t * vam)
12263 {
12264   unformat_input_t *i = vam->input;
12265   vl_api_ikev2_profile_set_id_t *mp;
12266   f64 timeout;
12267   u8 *name = 0;
12268   u8 *data = 0;
12269   u8 is_local = 0;
12270   u32 id_type = 0;
12271   ip4_address_t ip4;
12272
12273   const char *valid_chars = "a-zA-Z0-9_";
12274
12275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12276     {
12277       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12278         vec_add1 (name, 0);
12279       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12280         ;
12281       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12282         {
12283           data = vec_new (u8, 4);
12284           clib_memcpy (data, ip4.as_u8, 4);
12285         }
12286       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12287         ;
12288       else if (unformat (i, "id_data %v", &data))
12289         ;
12290       else if (unformat (i, "local"))
12291         is_local = 1;
12292       else if (unformat (i, "remote"))
12293         is_local = 0;
12294       else
12295         {
12296           errmsg ("parse error '%U'", format_unformat_error, i);
12297           return -99;
12298         }
12299     }
12300
12301   if (!vec_len (name))
12302     {
12303       errmsg ("profile name must be specified");
12304       return -99;
12305     }
12306
12307   if (vec_len (name) > 64)
12308     {
12309       errmsg ("profile name too long");
12310       return -99;
12311     }
12312
12313   if (!vec_len (data))
12314     {
12315       errmsg ("id_data must be specified");
12316       return -99;
12317     }
12318
12319   if (!id_type)
12320     {
12321       errmsg ("id_type must be specified");
12322       return -99;
12323     }
12324
12325   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12326
12327   mp->is_local = is_local;
12328   mp->id_type = (u8) id_type;
12329   mp->data_len = vec_len (data);
12330   clib_memcpy (mp->name, name, vec_len (name));
12331   clib_memcpy (mp->data, data, vec_len (data));
12332   vec_free (name);
12333   vec_free (data);
12334
12335   S;
12336   W;
12337   /* NOTREACHED */
12338   return 0;
12339 }
12340
12341 static int
12342 api_ikev2_profile_set_ts (vat_main_t * vam)
12343 {
12344   unformat_input_t *i = vam->input;
12345   vl_api_ikev2_profile_set_ts_t *mp;
12346   f64 timeout;
12347   u8 *name = 0;
12348   u8 is_local = 0;
12349   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12350   ip4_address_t start_addr, end_addr;
12351
12352   const char *valid_chars = "a-zA-Z0-9_";
12353
12354   start_addr.as_u32 = 0;
12355   end_addr.as_u32 = (u32) ~ 0;
12356
12357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12358     {
12359       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12360         vec_add1 (name, 0);
12361       else if (unformat (i, "protocol %d", &proto))
12362         ;
12363       else if (unformat (i, "start_port %d", &start_port))
12364         ;
12365       else if (unformat (i, "end_port %d", &end_port))
12366         ;
12367       else
12368         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12369         ;
12370       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12371         ;
12372       else if (unformat (i, "local"))
12373         is_local = 1;
12374       else if (unformat (i, "remote"))
12375         is_local = 0;
12376       else
12377         {
12378           errmsg ("parse error '%U'", format_unformat_error, i);
12379           return -99;
12380         }
12381     }
12382
12383   if (!vec_len (name))
12384     {
12385       errmsg ("profile name must be specified");
12386       return -99;
12387     }
12388
12389   if (vec_len (name) > 64)
12390     {
12391       errmsg ("profile name too long");
12392       return -99;
12393     }
12394
12395   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12396
12397   mp->is_local = is_local;
12398   mp->proto = (u8) proto;
12399   mp->start_port = (u16) start_port;
12400   mp->end_port = (u16) end_port;
12401   mp->start_addr = start_addr.as_u32;
12402   mp->end_addr = end_addr.as_u32;
12403   clib_memcpy (mp->name, name, vec_len (name));
12404   vec_free (name);
12405
12406   S;
12407   W;
12408   /* NOTREACHED */
12409   return 0;
12410 }
12411
12412 static int
12413 api_ikev2_set_local_key (vat_main_t * vam)
12414 {
12415   unformat_input_t *i = vam->input;
12416   vl_api_ikev2_set_local_key_t *mp;
12417   f64 timeout;
12418   u8 *file = 0;
12419
12420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12421     {
12422       if (unformat (i, "file %v", &file))
12423         vec_add1 (file, 0);
12424       else
12425         {
12426           errmsg ("parse error '%U'", format_unformat_error, i);
12427           return -99;
12428         }
12429     }
12430
12431   if (!vec_len (file))
12432     {
12433       errmsg ("RSA key file must be specified");
12434       return -99;
12435     }
12436
12437   if (vec_len (file) > 256)
12438     {
12439       errmsg ("file name too long");
12440       return -99;
12441     }
12442
12443   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12444
12445   clib_memcpy (mp->key_file, file, vec_len (file));
12446   vec_free (file);
12447
12448   S;
12449   W;
12450   /* NOTREACHED */
12451   return 0;
12452 }
12453
12454 /*
12455  * MAP
12456  */
12457 static int
12458 api_map_add_domain (vat_main_t * vam)
12459 {
12460   unformat_input_t *i = vam->input;
12461   vl_api_map_add_domain_t *mp;
12462   f64 timeout;
12463
12464   ip4_address_t ip4_prefix;
12465   ip6_address_t ip6_prefix;
12466   ip6_address_t ip6_src;
12467   u32 num_m_args = 0;
12468   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12469     0, psid_length = 0;
12470   u8 is_translation = 0;
12471   u32 mtu = 0;
12472   u32 ip6_src_len = 128;
12473
12474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12475     {
12476       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12477                     &ip4_prefix, &ip4_prefix_len))
12478         num_m_args++;
12479       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12480                          &ip6_prefix, &ip6_prefix_len))
12481         num_m_args++;
12482       else
12483         if (unformat
12484             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12485              &ip6_src_len))
12486         num_m_args++;
12487       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12488         num_m_args++;
12489       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12490         num_m_args++;
12491       else if (unformat (i, "psid-offset %d", &psid_offset))
12492         num_m_args++;
12493       else if (unformat (i, "psid-len %d", &psid_length))
12494         num_m_args++;
12495       else if (unformat (i, "mtu %d", &mtu))
12496         num_m_args++;
12497       else if (unformat (i, "map-t"))
12498         is_translation = 1;
12499       else
12500         {
12501           clib_warning ("parse error '%U'", format_unformat_error, i);
12502           return -99;
12503         }
12504     }
12505
12506   if (num_m_args < 3)
12507     {
12508       errmsg ("mandatory argument(s) missing");
12509       return -99;
12510     }
12511
12512   /* Construct the API message */
12513   M (MAP_ADD_DOMAIN, map_add_domain);
12514
12515   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12516   mp->ip4_prefix_len = ip4_prefix_len;
12517
12518   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12519   mp->ip6_prefix_len = ip6_prefix_len;
12520
12521   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12522   mp->ip6_src_prefix_len = ip6_src_len;
12523
12524   mp->ea_bits_len = ea_bits_len;
12525   mp->psid_offset = psid_offset;
12526   mp->psid_length = psid_length;
12527   mp->is_translation = is_translation;
12528   mp->mtu = htons (mtu);
12529
12530   /* send it... */
12531   S;
12532
12533   /* Wait for a reply, return good/bad news  */
12534   W;
12535 }
12536
12537 static int
12538 api_map_del_domain (vat_main_t * vam)
12539 {
12540   unformat_input_t *i = vam->input;
12541   vl_api_map_del_domain_t *mp;
12542   f64 timeout;
12543
12544   u32 num_m_args = 0;
12545   u32 index;
12546
12547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12548     {
12549       if (unformat (i, "index %d", &index))
12550         num_m_args++;
12551       else
12552         {
12553           clib_warning ("parse error '%U'", format_unformat_error, i);
12554           return -99;
12555         }
12556     }
12557
12558   if (num_m_args != 1)
12559     {
12560       errmsg ("mandatory argument(s) missing");
12561       return -99;
12562     }
12563
12564   /* Construct the API message */
12565   M (MAP_DEL_DOMAIN, map_del_domain);
12566
12567   mp->index = ntohl (index);
12568
12569   /* send it... */
12570   S;
12571
12572   /* Wait for a reply, return good/bad news  */
12573   W;
12574 }
12575
12576 static int
12577 api_map_add_del_rule (vat_main_t * vam)
12578 {
12579   unformat_input_t *i = vam->input;
12580   vl_api_map_add_del_rule_t *mp;
12581   f64 timeout;
12582   u8 is_add = 1;
12583   ip6_address_t ip6_dst;
12584   u32 num_m_args = 0, index, psid = 0;
12585
12586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12587     {
12588       if (unformat (i, "index %d", &index))
12589         num_m_args++;
12590       else if (unformat (i, "psid %d", &psid))
12591         num_m_args++;
12592       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12593         num_m_args++;
12594       else if (unformat (i, "del"))
12595         {
12596           is_add = 0;
12597         }
12598       else
12599         {
12600           clib_warning ("parse error '%U'", format_unformat_error, i);
12601           return -99;
12602         }
12603     }
12604
12605   /* Construct the API message */
12606   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12607
12608   mp->index = ntohl (index);
12609   mp->is_add = is_add;
12610   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12611   mp->psid = ntohs (psid);
12612
12613   /* send it... */
12614   S;
12615
12616   /* Wait for a reply, return good/bad news  */
12617   W;
12618 }
12619
12620 static int
12621 api_map_domain_dump (vat_main_t * vam)
12622 {
12623   vl_api_map_domain_dump_t *mp;
12624   f64 timeout;
12625
12626   /* Construct the API message */
12627   M (MAP_DOMAIN_DUMP, map_domain_dump);
12628
12629   /* send it... */
12630   S;
12631
12632   /* Use a control ping for synchronization */
12633   {
12634     vl_api_control_ping_t *mp;
12635     M (CONTROL_PING, control_ping);
12636     S;
12637   }
12638   W;
12639 }
12640
12641 static int
12642 api_map_rule_dump (vat_main_t * vam)
12643 {
12644   unformat_input_t *i = vam->input;
12645   vl_api_map_rule_dump_t *mp;
12646   f64 timeout;
12647   u32 domain_index = ~0;
12648
12649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12650     {
12651       if (unformat (i, "index %u", &domain_index))
12652         ;
12653       else
12654         break;
12655     }
12656
12657   if (domain_index == ~0)
12658     {
12659       clib_warning ("parse error: domain index expected");
12660       return -99;
12661     }
12662
12663   /* Construct the API message */
12664   M (MAP_RULE_DUMP, map_rule_dump);
12665
12666   mp->domain_index = htonl (domain_index);
12667
12668   /* send it... */
12669   S;
12670
12671   /* Use a control ping for synchronization */
12672   {
12673     vl_api_control_ping_t *mp;
12674     M (CONTROL_PING, control_ping);
12675     S;
12676   }
12677   W;
12678 }
12679
12680 static void vl_api_map_add_domain_reply_t_handler
12681   (vl_api_map_add_domain_reply_t * mp)
12682 {
12683   vat_main_t *vam = &vat_main;
12684   i32 retval = ntohl (mp->retval);
12685
12686   if (vam->async_mode)
12687     {
12688       vam->async_errors += (retval < 0);
12689     }
12690   else
12691     {
12692       vam->retval = retval;
12693       vam->result_ready = 1;
12694     }
12695 }
12696
12697 static void vl_api_map_add_domain_reply_t_handler_json
12698   (vl_api_map_add_domain_reply_t * mp)
12699 {
12700   vat_main_t *vam = &vat_main;
12701   vat_json_node_t node;
12702
12703   vat_json_init_object (&node);
12704   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12705   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12706
12707   vat_json_print (vam->ofp, &node);
12708   vat_json_free (&node);
12709
12710   vam->retval = ntohl (mp->retval);
12711   vam->result_ready = 1;
12712 }
12713
12714 static int
12715 api_get_first_msg_id (vat_main_t * vam)
12716 {
12717   vl_api_get_first_msg_id_t *mp;
12718   f64 timeout;
12719   unformat_input_t *i = vam->input;
12720   u8 *name;
12721   u8 name_set = 0;
12722
12723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12724     {
12725       if (unformat (i, "client %s", &name))
12726         name_set = 1;
12727       else
12728         break;
12729     }
12730
12731   if (name_set == 0)
12732     {
12733       errmsg ("missing client name");
12734       return -99;
12735     }
12736   vec_add1 (name, 0);
12737
12738   if (vec_len (name) > 63)
12739     {
12740       errmsg ("client name too long");
12741       return -99;
12742     }
12743
12744   M (GET_FIRST_MSG_ID, get_first_msg_id);
12745   clib_memcpy (mp->name, name, vec_len (name));
12746   S;
12747   W;
12748   /* NOTREACHED */
12749   return 0;
12750 }
12751
12752 static int
12753 api_cop_interface_enable_disable (vat_main_t * vam)
12754 {
12755   unformat_input_t *line_input = vam->input;
12756   vl_api_cop_interface_enable_disable_t *mp;
12757   f64 timeout;
12758   u32 sw_if_index = ~0;
12759   u8 enable_disable = 1;
12760
12761   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12762     {
12763       if (unformat (line_input, "disable"))
12764         enable_disable = 0;
12765       if (unformat (line_input, "enable"))
12766         enable_disable = 1;
12767       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12768                          vam, &sw_if_index))
12769         ;
12770       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12771         ;
12772       else
12773         break;
12774     }
12775
12776   if (sw_if_index == ~0)
12777     {
12778       errmsg ("missing interface name or sw_if_index");
12779       return -99;
12780     }
12781
12782   /* Construct the API message */
12783   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12784   mp->sw_if_index = ntohl (sw_if_index);
12785   mp->enable_disable = enable_disable;
12786
12787   /* send it... */
12788   S;
12789   /* Wait for the reply */
12790   W;
12791 }
12792
12793 static int
12794 api_cop_whitelist_enable_disable (vat_main_t * vam)
12795 {
12796   unformat_input_t *line_input = vam->input;
12797   vl_api_cop_whitelist_enable_disable_t *mp;
12798   f64 timeout;
12799   u32 sw_if_index = ~0;
12800   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12801   u32 fib_id = 0;
12802
12803   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12804     {
12805       if (unformat (line_input, "ip4"))
12806         ip4 = 1;
12807       else if (unformat (line_input, "ip6"))
12808         ip6 = 1;
12809       else if (unformat (line_input, "default"))
12810         default_cop = 1;
12811       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12812                          vam, &sw_if_index))
12813         ;
12814       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12815         ;
12816       else if (unformat (line_input, "fib-id %d", &fib_id))
12817         ;
12818       else
12819         break;
12820     }
12821
12822   if (sw_if_index == ~0)
12823     {
12824       errmsg ("missing interface name or sw_if_index");
12825       return -99;
12826     }
12827
12828   /* Construct the API message */
12829   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12830   mp->sw_if_index = ntohl (sw_if_index);
12831   mp->fib_id = ntohl (fib_id);
12832   mp->ip4 = ip4;
12833   mp->ip6 = ip6;
12834   mp->default_cop = default_cop;
12835
12836   /* send it... */
12837   S;
12838   /* Wait for the reply */
12839   W;
12840 }
12841
12842 static int
12843 api_get_node_graph (vat_main_t * vam)
12844 {
12845   vl_api_get_node_graph_t *mp;
12846   f64 timeout;
12847
12848   M (GET_NODE_GRAPH, get_node_graph);
12849
12850   /* send it... */
12851   S;
12852   /* Wait for the reply */
12853   W;
12854 }
12855
12856 /* *INDENT-OFF* */
12857 /** Used for parsing LISP eids */
12858 typedef CLIB_PACKED(struct{
12859   u8 addr[16];   /**< eid address */
12860   u32 len;       /**< prefix length if IP */
12861   u8 type;      /**< type of eid */
12862 }) lisp_eid_vat_t;
12863 /* *INDENT-ON* */
12864
12865 static uword
12866 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12867 {
12868   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12869
12870   memset (a, 0, sizeof (a[0]));
12871
12872   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12873     {
12874       a->type = 0;              /* ipv4 type */
12875     }
12876   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12877     {
12878       a->type = 1;              /* ipv6 type */
12879     }
12880   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12881     {
12882       a->type = 2;              /* mac type */
12883     }
12884   else
12885     {
12886       return 0;
12887     }
12888
12889   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12890     {
12891       return 0;
12892     }
12893
12894   return 1;
12895 }
12896
12897 static int
12898 lisp_eid_size_vat (u8 type)
12899 {
12900   switch (type)
12901     {
12902     case 0:
12903       return 4;
12904     case 1:
12905       return 16;
12906     case 2:
12907       return 6;
12908     }
12909   return 0;
12910 }
12911
12912 static void
12913 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12914 {
12915   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12916 }
12917
12918 /* *INDENT-OFF* */
12919 /** Used for transferring locators via VPP API */
12920 typedef CLIB_PACKED(struct
12921 {
12922   u32 sw_if_index; /**< locator sw_if_index */
12923   u8 priority; /**< locator priority */
12924   u8 weight;   /**< locator weight */
12925 }) ls_locator_t;
12926 /* *INDENT-ON* */
12927
12928 static int
12929 api_lisp_add_del_locator_set (vat_main_t * vam)
12930 {
12931   unformat_input_t *input = vam->input;
12932   vl_api_lisp_add_del_locator_set_t *mp;
12933   f64 timeout = ~0;
12934   u8 is_add = 1;
12935   u8 *locator_set_name = NULL;
12936   u8 locator_set_name_set = 0;
12937   ls_locator_t locator, *locators = 0;
12938   u32 sw_if_index, priority, weight;
12939   u32 data_len = 0;
12940
12941   /* Parse args required to build the message */
12942   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12943     {
12944       if (unformat (input, "del"))
12945         {
12946           is_add = 0;
12947         }
12948       else if (unformat (input, "locator-set %s", &locator_set_name))
12949         {
12950           locator_set_name_set = 1;
12951         }
12952       else if (unformat (input, "sw_if_index %u p %u w %u",
12953                          &sw_if_index, &priority, &weight))
12954         {
12955           locator.sw_if_index = htonl (sw_if_index);
12956           locator.priority = priority;
12957           locator.weight = weight;
12958           vec_add1 (locators, locator);
12959         }
12960       else
12961         if (unformat
12962             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
12963              &sw_if_index, &priority, &weight))
12964         {
12965           locator.sw_if_index = htonl (sw_if_index);
12966           locator.priority = priority;
12967           locator.weight = weight;
12968           vec_add1 (locators, locator);
12969         }
12970       else
12971         break;
12972     }
12973
12974   if (locator_set_name_set == 0)
12975     {
12976       errmsg ("missing locator-set name");
12977       vec_free (locators);
12978       return -99;
12979     }
12980
12981   if (vec_len (locator_set_name) > 64)
12982     {
12983       errmsg ("locator-set name too long");
12984       vec_free (locator_set_name);
12985       vec_free (locators);
12986       return -99;
12987     }
12988   vec_add1 (locator_set_name, 0);
12989
12990   data_len = sizeof (ls_locator_t) * vec_len (locators);
12991
12992   /* Construct the API message */
12993   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12994
12995   mp->is_add = is_add;
12996   clib_memcpy (mp->locator_set_name, locator_set_name,
12997                vec_len (locator_set_name));
12998   vec_free (locator_set_name);
12999
13000   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13001   if (locators)
13002     clib_memcpy (mp->locators, locators, data_len);
13003   vec_free (locators);
13004
13005   /* send it... */
13006   S;
13007
13008   /* Wait for a reply... */
13009   W;
13010
13011   /* NOTREACHED */
13012   return 0;
13013 }
13014
13015 static int
13016 api_lisp_add_del_locator (vat_main_t * vam)
13017 {
13018   unformat_input_t *input = vam->input;
13019   vl_api_lisp_add_del_locator_t *mp;
13020   f64 timeout = ~0;
13021   u32 tmp_if_index = ~0;
13022   u32 sw_if_index = ~0;
13023   u8 sw_if_index_set = 0;
13024   u8 sw_if_index_if_name_set = 0;
13025   u32 priority = ~0;
13026   u8 priority_set = 0;
13027   u32 weight = ~0;
13028   u8 weight_set = 0;
13029   u8 is_add = 1;
13030   u8 *locator_set_name = NULL;
13031   u8 locator_set_name_set = 0;
13032
13033   /* Parse args required to build the message */
13034   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13035     {
13036       if (unformat (input, "del"))
13037         {
13038           is_add = 0;
13039         }
13040       else if (unformat (input, "locator-set %s", &locator_set_name))
13041         {
13042           locator_set_name_set = 1;
13043         }
13044       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13045                          &tmp_if_index))
13046         {
13047           sw_if_index_if_name_set = 1;
13048           sw_if_index = tmp_if_index;
13049         }
13050       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13051         {
13052           sw_if_index_set = 1;
13053           sw_if_index = tmp_if_index;
13054         }
13055       else if (unformat (input, "p %d", &priority))
13056         {
13057           priority_set = 1;
13058         }
13059       else if (unformat (input, "w %d", &weight))
13060         {
13061           weight_set = 1;
13062         }
13063       else
13064         break;
13065     }
13066
13067   if (locator_set_name_set == 0)
13068     {
13069       errmsg ("missing locator-set name");
13070       return -99;
13071     }
13072
13073   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13074     {
13075       errmsg ("missing sw_if_index");
13076       vec_free (locator_set_name);
13077       return -99;
13078     }
13079
13080   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13081     {
13082       errmsg ("cannot use both params interface name and sw_if_index");
13083       vec_free (locator_set_name);
13084       return -99;
13085     }
13086
13087   if (priority_set == 0)
13088     {
13089       errmsg ("missing locator-set priority");
13090       vec_free (locator_set_name);
13091       return -99;
13092     }
13093
13094   if (weight_set == 0)
13095     {
13096       errmsg ("missing locator-set weight");
13097       vec_free (locator_set_name);
13098       return -99;
13099     }
13100
13101   if (vec_len (locator_set_name) > 64)
13102     {
13103       errmsg ("locator-set name too long");
13104       vec_free (locator_set_name);
13105       return -99;
13106     }
13107   vec_add1 (locator_set_name, 0);
13108
13109   /* Construct the API message */
13110   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
13111
13112   mp->is_add = is_add;
13113   mp->sw_if_index = ntohl (sw_if_index);
13114   mp->priority = priority;
13115   mp->weight = weight;
13116   clib_memcpy (mp->locator_set_name, locator_set_name,
13117                vec_len (locator_set_name));
13118   vec_free (locator_set_name);
13119
13120   /* send it... */
13121   S;
13122
13123   /* Wait for a reply... */
13124   W;
13125
13126   /* NOTREACHED */
13127   return 0;
13128 }
13129
13130 uword
13131 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13132 {
13133   u32 *key_id = va_arg (*args, u32 *);
13134   u8 *s = 0;
13135
13136   if (unformat (input, "%s", &s))
13137     {
13138       if (!strcmp ((char *) s, "sha1"))
13139         key_id[0] = HMAC_SHA_1_96;
13140       else if (!strcmp ((char *) s, "sha256"))
13141         key_id[0] = HMAC_SHA_256_128;
13142       else
13143         {
13144           clib_warning ("invalid key_id: '%s'", s);
13145           key_id[0] = HMAC_NO_KEY;
13146         }
13147     }
13148   else
13149     return 0;
13150
13151   vec_free (s);
13152   return 1;
13153 }
13154
13155 static int
13156 api_lisp_add_del_local_eid (vat_main_t * vam)
13157 {
13158   unformat_input_t *input = vam->input;
13159   vl_api_lisp_add_del_local_eid_t *mp;
13160   f64 timeout = ~0;
13161   u8 is_add = 1;
13162   u8 eid_set = 0;
13163   lisp_eid_vat_t _eid, *eid = &_eid;
13164   u8 *locator_set_name = 0;
13165   u8 locator_set_name_set = 0;
13166   u32 vni = 0;
13167   u16 key_id = 0;
13168   u8 *key = 0;
13169
13170   /* Parse args required to build the message */
13171   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13172     {
13173       if (unformat (input, "del"))
13174         {
13175           is_add = 0;
13176         }
13177       else if (unformat (input, "vni %d", &vni))
13178         {
13179           ;
13180         }
13181       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13182         {
13183           eid_set = 1;
13184         }
13185       else if (unformat (input, "locator-set %s", &locator_set_name))
13186         {
13187           locator_set_name_set = 1;
13188         }
13189       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13190         ;
13191       else if (unformat (input, "secret-key %_%v%_", &key))
13192         ;
13193       else
13194         break;
13195     }
13196
13197   if (locator_set_name_set == 0)
13198     {
13199       errmsg ("missing locator-set name");
13200       return -99;
13201     }
13202
13203   if (0 == eid_set)
13204     {
13205       errmsg ("EID address not set!");
13206       vec_free (locator_set_name);
13207       return -99;
13208     }
13209
13210   if (key && (0 == key_id))
13211     {
13212       errmsg ("invalid key_id!");
13213       return -99;
13214     }
13215
13216   if (vec_len (key) > 64)
13217     {
13218       errmsg ("key too long");
13219       vec_free (key);
13220       return -99;
13221     }
13222
13223   if (vec_len (locator_set_name) > 64)
13224     {
13225       errmsg ("locator-set name too long");
13226       vec_free (locator_set_name);
13227       return -99;
13228     }
13229   vec_add1 (locator_set_name, 0);
13230
13231   /* Construct the API message */
13232   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
13233
13234   mp->is_add = is_add;
13235   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13236   mp->eid_type = eid->type;
13237   mp->prefix_len = eid->len;
13238   mp->vni = clib_host_to_net_u32 (vni);
13239   mp->key_id = clib_host_to_net_u16 (key_id);
13240   clib_memcpy (mp->locator_set_name, locator_set_name,
13241                vec_len (locator_set_name));
13242   clib_memcpy (mp->key, key, vec_len (key));
13243
13244   vec_free (locator_set_name);
13245   vec_free (key);
13246
13247   /* send it... */
13248   S;
13249
13250   /* Wait for a reply... */
13251   W;
13252
13253   /* NOTREACHED */
13254   return 0;
13255 }
13256
13257 /* *INDENT-OFF* */
13258 /** Used for transferring locators via VPP API */
13259 typedef CLIB_PACKED(struct
13260 {
13261   u8 is_ip4; /**< is locator an IPv4 address? */
13262   u8 priority; /**< locator priority */
13263   u8 weight;   /**< locator weight */
13264   u8 addr[16]; /**< IPv4/IPv6 address */
13265 }) rloc_t;
13266 /* *INDENT-ON* */
13267
13268 static int
13269 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13270 {
13271   unformat_input_t *input = vam->input;
13272   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13273   f64 timeout = ~0;
13274   u8 is_add = 1;
13275   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13276   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13277   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13278   u32 action = ~0, p, w;
13279   ip4_address_t rmt_rloc4, lcl_rloc4;
13280   ip6_address_t rmt_rloc6, lcl_rloc6;
13281   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13282
13283   memset (&rloc, 0, sizeof (rloc));
13284
13285   /* Parse args required to build the message */
13286   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13287     {
13288       if (unformat (input, "del"))
13289         {
13290           is_add = 0;
13291         }
13292       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
13293         {
13294           rmt_eid_set = 1;
13295         }
13296       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
13297         {
13298           lcl_eid_set = 1;
13299         }
13300       else if (unformat (input, "p %d w %d", &p, &w))
13301         {
13302           if (!curr_rloc)
13303             {
13304               errmsg ("No RLOC configured for setting priority/weight!");
13305               return -99;
13306             }
13307           curr_rloc->priority = p;
13308           curr_rloc->weight = w;
13309         }
13310       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13311                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13312         {
13313           rloc.is_ip4 = 1;
13314
13315           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13316           rloc.priority = rloc.weight = 0;
13317           vec_add1 (lcl_locs, rloc);
13318
13319           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13320           vec_add1 (rmt_locs, rloc);
13321           /* priority and weight saved in rmt loc */
13322           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13323         }
13324       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13325                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13326         {
13327           rloc.is_ip4 = 0;
13328           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13329           rloc.priority = rloc.weight = 0;
13330           vec_add1 (lcl_locs, rloc);
13331
13332           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13333           vec_add1 (rmt_locs, rloc);
13334           /* priority and weight saved in rmt loc */
13335           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13336         }
13337       else if (unformat (input, "action %d", &action))
13338         {
13339           ;
13340         }
13341       else
13342         {
13343           clib_warning ("parse error '%U'", format_unformat_error, input);
13344           return -99;
13345         }
13346     }
13347
13348   if (!rmt_eid_set)
13349     {
13350       errmsg ("remote eid addresses not set");
13351       return -99;
13352     }
13353
13354   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13355     {
13356       errmsg ("eid types don't match");
13357       return -99;
13358     }
13359
13360   if (0 == rmt_locs && (u32) ~ 0 == action)
13361     {
13362       errmsg ("action not set for negative mapping");
13363       return -99;
13364     }
13365
13366   /* Construct the API message */
13367   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13368
13369   mp->is_add = is_add;
13370   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13371   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13372   mp->eid_type = rmt_eid->type;
13373   mp->rmt_len = rmt_eid->len;
13374   mp->lcl_len = lcl_eid->len;
13375   mp->action = action;
13376
13377   if (0 != rmt_locs && 0 != lcl_locs)
13378     {
13379       mp->loc_num = vec_len (rmt_locs);
13380       clib_memcpy (mp->lcl_locs, lcl_locs,
13381                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13382       clib_memcpy (mp->rmt_locs, rmt_locs,
13383                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13384     }
13385   vec_free (lcl_locs);
13386   vec_free (rmt_locs);
13387
13388   /* send it... */
13389   S;
13390
13391   /* Wait for a reply... */
13392   W;
13393
13394   /* NOTREACHED */
13395   return 0;
13396 }
13397
13398 static int
13399 api_lisp_add_del_map_server (vat_main_t * vam)
13400 {
13401   unformat_input_t *input = vam->input;
13402   vl_api_lisp_add_del_map_server_t *mp;
13403   f64 timeout = ~0;
13404   u8 is_add = 1;
13405   u8 ipv4_set = 0;
13406   u8 ipv6_set = 0;
13407   ip4_address_t ipv4;
13408   ip6_address_t ipv6;
13409
13410   /* Parse args required to build the message */
13411   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13412     {
13413       if (unformat (input, "del"))
13414         {
13415           is_add = 0;
13416         }
13417       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13418         {
13419           ipv4_set = 1;
13420         }
13421       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13422         {
13423           ipv6_set = 1;
13424         }
13425       else
13426         break;
13427     }
13428
13429   if (ipv4_set && ipv6_set)
13430     {
13431       errmsg ("both eid v4 and v6 addresses set");
13432       return -99;
13433     }
13434
13435   if (!ipv4_set && !ipv6_set)
13436     {
13437       errmsg ("eid addresses not set");
13438       return -99;
13439     }
13440
13441   /* Construct the API message */
13442   M (LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server);
13443
13444   mp->is_add = is_add;
13445   if (ipv6_set)
13446     {
13447       mp->is_ipv6 = 1;
13448       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13449     }
13450   else
13451     {
13452       mp->is_ipv6 = 0;
13453       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13454     }
13455
13456   /* send it... */
13457   S;
13458
13459   /* Wait for a reply... */
13460   W;
13461
13462   /* NOTREACHED */
13463   return 0;
13464 }
13465
13466 static int
13467 api_lisp_add_del_map_resolver (vat_main_t * vam)
13468 {
13469   unformat_input_t *input = vam->input;
13470   vl_api_lisp_add_del_map_resolver_t *mp;
13471   f64 timeout = ~0;
13472   u8 is_add = 1;
13473   u8 ipv4_set = 0;
13474   u8 ipv6_set = 0;
13475   ip4_address_t ipv4;
13476   ip6_address_t ipv6;
13477
13478   /* Parse args required to build the message */
13479   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13480     {
13481       if (unformat (input, "del"))
13482         {
13483           is_add = 0;
13484         }
13485       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13486         {
13487           ipv4_set = 1;
13488         }
13489       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13490         {
13491           ipv6_set = 1;
13492         }
13493       else
13494         break;
13495     }
13496
13497   if (ipv4_set && ipv6_set)
13498     {
13499       errmsg ("both eid v4 and v6 addresses set");
13500       return -99;
13501     }
13502
13503   if (!ipv4_set && !ipv6_set)
13504     {
13505       errmsg ("eid addresses not set");
13506       return -99;
13507     }
13508
13509   /* Construct the API message */
13510   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13511
13512   mp->is_add = is_add;
13513   if (ipv6_set)
13514     {
13515       mp->is_ipv6 = 1;
13516       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13517     }
13518   else
13519     {
13520       mp->is_ipv6 = 0;
13521       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13522     }
13523
13524   /* send it... */
13525   S;
13526
13527   /* Wait for a reply... */
13528   W;
13529
13530   /* NOTREACHED */
13531   return 0;
13532 }
13533
13534 static int
13535 api_lisp_gpe_enable_disable (vat_main_t * vam)
13536 {
13537   unformat_input_t *input = vam->input;
13538   vl_api_lisp_gpe_enable_disable_t *mp;
13539   f64 timeout = ~0;
13540   u8 is_set = 0;
13541   u8 is_en = 1;
13542
13543   /* Parse args required to build the message */
13544   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13545     {
13546       if (unformat (input, "enable"))
13547         {
13548           is_set = 1;
13549           is_en = 1;
13550         }
13551       else if (unformat (input, "disable"))
13552         {
13553           is_set = 1;
13554           is_en = 0;
13555         }
13556       else
13557         break;
13558     }
13559
13560   if (is_set == 0)
13561     {
13562       errmsg ("Value not set");
13563       return -99;
13564     }
13565
13566   /* Construct the API message */
13567   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13568
13569   mp->is_en = is_en;
13570
13571   /* send it... */
13572   S;
13573
13574   /* Wait for a reply... */
13575   W;
13576
13577   /* NOTREACHED */
13578   return 0;
13579 }
13580
13581 static int
13582 api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
13583 {
13584   unformat_input_t *input = vam->input;
13585   vl_api_lisp_rloc_probe_enable_disable_t *mp;
13586   f64 timeout = ~0;
13587   u8 is_set = 0;
13588   u8 is_en = 0;
13589
13590   /* Parse args required to build the message */
13591   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13592     {
13593       if (unformat (input, "enable"))
13594         {
13595           is_set = 1;
13596           is_en = 1;
13597         }
13598       else if (unformat (input, "disable"))
13599         is_set = 1;
13600       else
13601         break;
13602     }
13603
13604   if (!is_set)
13605     {
13606       errmsg ("Value not set");
13607       return -99;
13608     }
13609
13610   /* Construct the API message */
13611   M (LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable);
13612
13613   mp->is_enabled = is_en;
13614
13615   /* send it... */
13616   S;
13617
13618   /* Wait for a reply... */
13619   W;
13620
13621   /* NOTREACHED */
13622   return 0;
13623 }
13624
13625 static int
13626 api_lisp_map_register_enable_disable (vat_main_t * vam)
13627 {
13628   unformat_input_t *input = vam->input;
13629   vl_api_lisp_map_register_enable_disable_t *mp;
13630   f64 timeout = ~0;
13631   u8 is_set = 0;
13632   u8 is_en = 0;
13633
13634   /* Parse args required to build the message */
13635   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13636     {
13637       if (unformat (input, "enable"))
13638         {
13639           is_set = 1;
13640           is_en = 1;
13641         }
13642       else if (unformat (input, "disable"))
13643         is_set = 1;
13644       else
13645         break;
13646     }
13647
13648   if (!is_set)
13649     {
13650       errmsg ("Value not set");
13651       return -99;
13652     }
13653
13654   /* Construct the API message */
13655   M (LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable);
13656
13657   mp->is_enabled = is_en;
13658
13659   /* send it... */
13660   S;
13661
13662   /* Wait for a reply... */
13663   W;
13664
13665   /* NOTREACHED */
13666   return 0;
13667 }
13668
13669 static int
13670 api_lisp_enable_disable (vat_main_t * vam)
13671 {
13672   unformat_input_t *input = vam->input;
13673   vl_api_lisp_enable_disable_t *mp;
13674   f64 timeout = ~0;
13675   u8 is_set = 0;
13676   u8 is_en = 0;
13677
13678   /* Parse args required to build the message */
13679   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13680     {
13681       if (unformat (input, "enable"))
13682         {
13683           is_set = 1;
13684           is_en = 1;
13685         }
13686       else if (unformat (input, "disable"))
13687         {
13688           is_set = 1;
13689         }
13690       else
13691         break;
13692     }
13693
13694   if (!is_set)
13695     {
13696       errmsg ("Value not set");
13697       return -99;
13698     }
13699
13700   /* Construct the API message */
13701   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13702
13703   mp->is_en = is_en;
13704
13705   /* send it... */
13706   S;
13707
13708   /* Wait for a reply... */
13709   W;
13710
13711   /* NOTREACHED */
13712   return 0;
13713 }
13714
13715 static int
13716 api_show_lisp_map_register_state (vat_main_t * vam)
13717 {
13718   f64 timeout = ~0;
13719   vl_api_show_lisp_map_register_state_t *mp;
13720
13721   M (SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state);
13722
13723   /* send */
13724   S;
13725
13726   /* wait for reply */
13727   W;
13728
13729   return 0;
13730 }
13731
13732 static int
13733 api_show_lisp_rloc_probe_state (vat_main_t * vam)
13734 {
13735   f64 timeout = ~0;
13736   vl_api_show_lisp_rloc_probe_state_t *mp;
13737
13738   M (SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state);
13739
13740   /* send */
13741   S;
13742
13743   /* wait for reply */
13744   W;
13745
13746   return 0;
13747 }
13748
13749 static int
13750 api_show_lisp_map_request_mode (vat_main_t * vam)
13751 {
13752   f64 timeout = ~0;
13753   vl_api_show_lisp_map_request_mode_t *mp;
13754
13755   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13756
13757   /* send */
13758   S;
13759
13760   /* wait for reply */
13761   W;
13762
13763   return 0;
13764 }
13765
13766 static int
13767 api_lisp_map_request_mode (vat_main_t * vam)
13768 {
13769   f64 timeout = ~0;
13770   unformat_input_t *input = vam->input;
13771   vl_api_lisp_map_request_mode_t *mp;
13772   u8 mode = 0;
13773
13774   /* Parse args required to build the message */
13775   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13776     {
13777       if (unformat (input, "dst-only"))
13778         mode = 0;
13779       else if (unformat (input, "src-dst"))
13780         mode = 1;
13781       else
13782         {
13783           errmsg ("parse error '%U'", format_unformat_error, input);
13784           return -99;
13785         }
13786     }
13787
13788   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13789
13790   mp->mode = mode;
13791
13792   /* send */
13793   S;
13794
13795   /* wait for reply */
13796   W;
13797
13798   /* notreached */
13799   return 0;
13800 }
13801
13802 /**
13803  * Enable/disable LISP proxy ITR.
13804  *
13805  * @param vam vpp API test context
13806  * @return return code
13807  */
13808 static int
13809 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13810 {
13811   f64 timeout = ~0;
13812   u8 ls_name_set = 0;
13813   unformat_input_t *input = vam->input;
13814   vl_api_lisp_pitr_set_locator_set_t *mp;
13815   u8 is_add = 1;
13816   u8 *ls_name = 0;
13817
13818   /* Parse args required to build the message */
13819   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13820     {
13821       if (unformat (input, "del"))
13822         is_add = 0;
13823       else if (unformat (input, "locator-set %s", &ls_name))
13824         ls_name_set = 1;
13825       else
13826         {
13827           errmsg ("parse error '%U'", format_unformat_error, input);
13828           return -99;
13829         }
13830     }
13831
13832   if (!ls_name_set)
13833     {
13834       errmsg ("locator-set name not set!");
13835       return -99;
13836     }
13837
13838   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13839
13840   mp->is_add = is_add;
13841   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13842   vec_free (ls_name);
13843
13844   /* send */
13845   S;
13846
13847   /* wait for reply */
13848   W;
13849
13850   /* notreached */
13851   return 0;
13852 }
13853
13854 static int
13855 api_show_lisp_pitr (vat_main_t * vam)
13856 {
13857   vl_api_show_lisp_pitr_t *mp;
13858   f64 timeout = ~0;
13859
13860   if (!vam->json_output)
13861     {
13862       print (vam->ofp, "%=20s", "lisp status:");
13863     }
13864
13865   M (SHOW_LISP_PITR, show_lisp_pitr);
13866   /* send it... */
13867   S;
13868
13869   /* Wait for a reply... */
13870   W;
13871
13872   /* NOTREACHED */
13873   return 0;
13874 }
13875
13876 /**
13877  * Add/delete mapping between vni and vrf
13878  */
13879 static int
13880 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13881 {
13882   f64 timeout = ~0;
13883   unformat_input_t *input = vam->input;
13884   vl_api_lisp_eid_table_add_del_map_t *mp;
13885   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13886   u32 vni, vrf, bd_index;
13887
13888   /* Parse args required to build the message */
13889   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13890     {
13891       if (unformat (input, "del"))
13892         is_add = 0;
13893       else if (unformat (input, "vrf %d", &vrf))
13894         vrf_set = 1;
13895       else if (unformat (input, "bd_index %d", &bd_index))
13896         bd_index_set = 1;
13897       else if (unformat (input, "vni %d", &vni))
13898         vni_set = 1;
13899       else
13900         break;
13901     }
13902
13903   if (!vni_set || (!vrf_set && !bd_index_set))
13904     {
13905       errmsg ("missing arguments!");
13906       return -99;
13907     }
13908
13909   if (vrf_set && bd_index_set)
13910     {
13911       errmsg ("error: both vrf and bd entered!");
13912       return -99;
13913     }
13914
13915   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13916
13917   mp->is_add = is_add;
13918   mp->vni = htonl (vni);
13919   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13920   mp->is_l2 = bd_index_set;
13921
13922   /* send */
13923   S;
13924
13925   /* wait for reply */
13926   W;
13927
13928   /* notreached */
13929   return 0;
13930 }
13931
13932 uword
13933 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13934 {
13935   u32 *action = va_arg (*args, u32 *);
13936   u8 *s = 0;
13937
13938   if (unformat (input, "%s", &s))
13939     {
13940       if (!strcmp ((char *) s, "no-action"))
13941         action[0] = 0;
13942       else if (!strcmp ((char *) s, "natively-forward"))
13943         action[0] = 1;
13944       else if (!strcmp ((char *) s, "send-map-request"))
13945         action[0] = 2;
13946       else if (!strcmp ((char *) s, "drop"))
13947         action[0] = 3;
13948       else
13949         {
13950           clib_warning ("invalid action: '%s'", s);
13951           action[0] = 3;
13952         }
13953     }
13954   else
13955     return 0;
13956
13957   vec_free (s);
13958   return 1;
13959 }
13960
13961 /**
13962  * Add/del remote mapping to/from LISP control plane
13963  *
13964  * @param vam vpp API test context
13965  * @return return code
13966  */
13967 static int
13968 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13969 {
13970   unformat_input_t *input = vam->input;
13971   vl_api_lisp_add_del_remote_mapping_t *mp;
13972   f64 timeout = ~0;
13973   u32 vni = 0;
13974   lisp_eid_vat_t _eid, *eid = &_eid;
13975   lisp_eid_vat_t _seid, *seid = &_seid;
13976   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13977   u32 action = ~0, p, w, data_len;
13978   ip4_address_t rloc4;
13979   ip6_address_t rloc6;
13980   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13981
13982   memset (&rloc, 0, sizeof (rloc));
13983
13984   /* Parse args required to build the message */
13985   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13986     {
13987       if (unformat (input, "del-all"))
13988         {
13989           del_all = 1;
13990         }
13991       else if (unformat (input, "del"))
13992         {
13993           is_add = 0;
13994         }
13995       else if (unformat (input, "add"))
13996         {
13997           is_add = 1;
13998         }
13999       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14000         {
14001           eid_set = 1;
14002         }
14003       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14004         {
14005           seid_set = 1;
14006         }
14007       else if (unformat (input, "vni %d", &vni))
14008         {
14009           ;
14010         }
14011       else if (unformat (input, "p %d w %d", &p, &w))
14012         {
14013           if (!curr_rloc)
14014             {
14015               errmsg ("No RLOC configured for setting priority/weight!");
14016               return -99;
14017             }
14018           curr_rloc->priority = p;
14019           curr_rloc->weight = w;
14020         }
14021       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14022         {
14023           rloc.is_ip4 = 1;
14024           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14025           vec_add1 (rlocs, rloc);
14026           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14027         }
14028       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14029         {
14030           rloc.is_ip4 = 0;
14031           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14032           vec_add1 (rlocs, rloc);
14033           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14034         }
14035       else if (unformat (input, "action %U",
14036                          unformat_negative_mapping_action, &action))
14037         {
14038           ;
14039         }
14040       else
14041         {
14042           clib_warning ("parse error '%U'", format_unformat_error, input);
14043           return -99;
14044         }
14045     }
14046
14047   if (0 == eid_set)
14048     {
14049       errmsg ("missing params!");
14050       return -99;
14051     }
14052
14053   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14054     {
14055       errmsg ("no action set for negative map-reply!");
14056       return -99;
14057     }
14058
14059   data_len = vec_len (rlocs) * sizeof (rloc_t);
14060
14061   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
14062   mp->is_add = is_add;
14063   mp->vni = htonl (vni);
14064   mp->action = (u8) action;
14065   mp->is_src_dst = seid_set;
14066   mp->eid_len = eid->len;
14067   mp->seid_len = seid->len;
14068   mp->del_all = del_all;
14069   mp->eid_type = eid->type;
14070   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14071   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14072
14073   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14074   clib_memcpy (mp->rlocs, rlocs, data_len);
14075   vec_free (rlocs);
14076
14077   /* send it... */
14078   S;
14079
14080   /* Wait for a reply... */
14081   W;
14082
14083   /* NOTREACHED */
14084   return 0;
14085 }
14086
14087 /**
14088  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14089  * forwarding entries in data-plane accordingly.
14090  *
14091  * @param vam vpp API test context
14092  * @return return code
14093  */
14094 static int
14095 api_lisp_add_del_adjacency (vat_main_t * vam)
14096 {
14097   unformat_input_t *input = vam->input;
14098   vl_api_lisp_add_del_adjacency_t *mp;
14099   f64 timeout = ~0;
14100   u32 vni = 0;
14101   ip4_address_t leid4, reid4;
14102   ip6_address_t leid6, reid6;
14103   u8 reid_mac[6] = { 0 };
14104   u8 leid_mac[6] = { 0 };
14105   u8 reid_type, leid_type;
14106   u32 leid_len = 0, reid_len = 0, len;
14107   u8 is_add = 1;
14108
14109   leid_type = reid_type = (u8) ~ 0;
14110
14111   /* Parse args required to build the message */
14112   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14113     {
14114       if (unformat (input, "del"))
14115         {
14116           is_add = 0;
14117         }
14118       else if (unformat (input, "add"))
14119         {
14120           is_add = 1;
14121         }
14122       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14123                          &reid4, &len))
14124         {
14125           reid_type = 0;        /* ipv4 */
14126           reid_len = len;
14127         }
14128       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14129                          &reid6, &len))
14130         {
14131           reid_type = 1;        /* ipv6 */
14132           reid_len = len;
14133         }
14134       else if (unformat (input, "reid %U", unformat_ethernet_address,
14135                          reid_mac))
14136         {
14137           reid_type = 2;        /* mac */
14138         }
14139       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14140                          &leid4, &len))
14141         {
14142           leid_type = 0;        /* ipv4 */
14143           leid_len = len;
14144         }
14145       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14146                          &leid6, &len))
14147         {
14148           leid_type = 1;        /* ipv6 */
14149           leid_len = len;
14150         }
14151       else if (unformat (input, "leid %U", unformat_ethernet_address,
14152                          leid_mac))
14153         {
14154           leid_type = 2;        /* mac */
14155         }
14156       else if (unformat (input, "vni %d", &vni))
14157         {
14158           ;
14159         }
14160       else
14161         {
14162           errmsg ("parse error '%U'", format_unformat_error, input);
14163           return -99;
14164         }
14165     }
14166
14167   if ((u8) ~ 0 == reid_type)
14168     {
14169       errmsg ("missing params!");
14170       return -99;
14171     }
14172
14173   if (leid_type != reid_type)
14174     {
14175       errmsg ("remote and local EIDs are of different types!");
14176       return -99;
14177     }
14178
14179   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
14180   mp->is_add = is_add;
14181   mp->vni = htonl (vni);
14182   mp->leid_len = leid_len;
14183   mp->reid_len = reid_len;
14184   mp->eid_type = reid_type;
14185
14186   switch (mp->eid_type)
14187     {
14188     case 0:
14189       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14190       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14191       break;
14192     case 1:
14193       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14194       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14195       break;
14196     case 2:
14197       clib_memcpy (mp->leid, leid_mac, 6);
14198       clib_memcpy (mp->reid, reid_mac, 6);
14199       break;
14200     default:
14201       errmsg ("unknown EID type %d!", mp->eid_type);
14202       return 0;
14203     }
14204
14205   /* send it... */
14206   S;
14207
14208   /* Wait for a reply... */
14209   W;
14210
14211   /* NOTREACHED */
14212   return 0;
14213 }
14214
14215 static int
14216 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14217 {
14218   unformat_input_t *input = vam->input;
14219   vl_api_lisp_gpe_add_del_iface_t *mp;
14220   f64 timeout = ~0;
14221   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14222   u32 dp_table = 0, vni = 0;
14223
14224   /* Parse args required to build the message */
14225   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14226     {
14227       if (unformat (input, "up"))
14228         {
14229           action_set = 1;
14230           is_add = 1;
14231         }
14232       else if (unformat (input, "down"))
14233         {
14234           action_set = 1;
14235           is_add = 0;
14236         }
14237       else if (unformat (input, "table_id %d", &dp_table))
14238         {
14239           dp_table_set = 1;
14240         }
14241       else if (unformat (input, "bd_id %d", &dp_table))
14242         {
14243           dp_table_set = 1;
14244           is_l2 = 1;
14245         }
14246       else if (unformat (input, "vni %d", &vni))
14247         {
14248           vni_set = 1;
14249         }
14250       else
14251         break;
14252     }
14253
14254   if (action_set == 0)
14255     {
14256       errmsg ("Action not set");
14257       return -99;
14258     }
14259   if (dp_table_set == 0 || vni_set == 0)
14260     {
14261       errmsg ("vni and dp_table must be set");
14262       return -99;
14263     }
14264
14265   /* Construct the API message */
14266   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
14267
14268   mp->is_add = is_add;
14269   mp->dp_table = dp_table;
14270   mp->is_l2 = is_l2;
14271   mp->vni = vni;
14272
14273   /* send it... */
14274   S;
14275
14276   /* Wait for a reply... */
14277   W;
14278
14279   /* NOTREACHED */
14280   return 0;
14281 }
14282
14283 /**
14284  * Add/del map request itr rlocs from LISP control plane and updates
14285  *
14286  * @param vam vpp API test context
14287  * @return return code
14288  */
14289 static int
14290 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14291 {
14292   unformat_input_t *input = vam->input;
14293   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14294   f64 timeout = ~0;
14295   u8 *locator_set_name = 0;
14296   u8 locator_set_name_set = 0;
14297   u8 is_add = 1;
14298
14299   /* Parse args required to build the message */
14300   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14301     {
14302       if (unformat (input, "del"))
14303         {
14304           is_add = 0;
14305         }
14306       else if (unformat (input, "%_%v%_", &locator_set_name))
14307         {
14308           locator_set_name_set = 1;
14309         }
14310       else
14311         {
14312           clib_warning ("parse error '%U'", format_unformat_error, input);
14313           return -99;
14314         }
14315     }
14316
14317   if (is_add && !locator_set_name_set)
14318     {
14319       errmsg ("itr-rloc is not set!");
14320       return -99;
14321     }
14322
14323   if (is_add && vec_len (locator_set_name) > 64)
14324     {
14325       errmsg ("itr-rloc locator-set name too long");
14326       vec_free (locator_set_name);
14327       return -99;
14328     }
14329
14330   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
14331   mp->is_add = is_add;
14332   if (is_add)
14333     {
14334       clib_memcpy (mp->locator_set_name, locator_set_name,
14335                    vec_len (locator_set_name));
14336     }
14337   else
14338     {
14339       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14340     }
14341   vec_free (locator_set_name);
14342
14343   /* send it... */
14344   S;
14345
14346   /* Wait for a reply... */
14347   W;
14348
14349   /* NOTREACHED */
14350   return 0;
14351 }
14352
14353 static int
14354 api_lisp_locator_dump (vat_main_t * vam)
14355 {
14356   unformat_input_t *input = vam->input;
14357   vl_api_lisp_locator_dump_t *mp;
14358   f64 timeout = ~0;
14359   u8 is_index_set = 0, is_name_set = 0;
14360   u8 *ls_name = 0;
14361   u32 ls_index = ~0;
14362
14363   /* Parse args required to build the message */
14364   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14365     {
14366       if (unformat (input, "ls_name %_%v%_", &ls_name))
14367         {
14368           is_name_set = 1;
14369         }
14370       else if (unformat (input, "ls_index %d", &ls_index))
14371         {
14372           is_index_set = 1;
14373         }
14374       else
14375         {
14376           errmsg ("parse error '%U'", format_unformat_error, input);
14377           return -99;
14378         }
14379     }
14380
14381   if (!is_index_set && !is_name_set)
14382     {
14383       errmsg ("error: expected one of index or name!");
14384       return -99;
14385     }
14386
14387   if (is_index_set && is_name_set)
14388     {
14389       errmsg ("error: only one param expected!");
14390       return -99;
14391     }
14392
14393   if (vec_len (ls_name) > 62)
14394     {
14395       errmsg ("error: locator set name too long!");
14396       return -99;
14397     }
14398
14399   if (!vam->json_output)
14400     {
14401       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14402     }
14403
14404   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
14405   mp->is_index_set = is_index_set;
14406
14407   if (is_index_set)
14408     mp->ls_index = clib_host_to_net_u32 (ls_index);
14409   else
14410     {
14411       vec_add1 (ls_name, 0);
14412       strncpy ((char *) mp->ls_name, (char *) ls_name,
14413                sizeof (mp->ls_name) - 1);
14414     }
14415
14416   /* send it... */
14417   S;
14418
14419   /* Use a control ping for synchronization */
14420   {
14421     vl_api_control_ping_t *mp;
14422     M (CONTROL_PING, control_ping);
14423     S;
14424   }
14425   /* Wait for a reply... */
14426   W;
14427
14428   /* NOTREACHED */
14429   return 0;
14430 }
14431
14432 static int
14433 api_lisp_locator_set_dump (vat_main_t * vam)
14434 {
14435   vl_api_lisp_locator_set_dump_t *mp;
14436   unformat_input_t *input = vam->input;
14437   f64 timeout = ~0;
14438   u8 filter = 0;
14439
14440   /* Parse args required to build the message */
14441   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14442     {
14443       if (unformat (input, "local"))
14444         {
14445           filter = 1;
14446         }
14447       else if (unformat (input, "remote"))
14448         {
14449           filter = 2;
14450         }
14451       else
14452         {
14453           errmsg ("parse error '%U'", format_unformat_error, input);
14454           return -99;
14455         }
14456     }
14457
14458   if (!vam->json_output)
14459     {
14460       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14461     }
14462
14463   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14464
14465   mp->filter = filter;
14466
14467   /* send it... */
14468   S;
14469
14470   /* Use a control ping for synchronization */
14471   {
14472     vl_api_control_ping_t *mp;
14473     M (CONTROL_PING, control_ping);
14474     S;
14475   }
14476   /* Wait for a reply... */
14477   W;
14478
14479   /* NOTREACHED */
14480   return 0;
14481 }
14482
14483 static int
14484 api_lisp_eid_table_map_dump (vat_main_t * vam)
14485 {
14486   u8 is_l2 = 0;
14487   u8 mode_set = 0;
14488   unformat_input_t *input = vam->input;
14489   vl_api_lisp_eid_table_map_dump_t *mp;
14490   f64 timeout = ~0;
14491
14492   /* Parse args required to build the message */
14493   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14494     {
14495       if (unformat (input, "l2"))
14496         {
14497           is_l2 = 1;
14498           mode_set = 1;
14499         }
14500       else if (unformat (input, "l3"))
14501         {
14502           is_l2 = 0;
14503           mode_set = 1;
14504         }
14505       else
14506         {
14507           errmsg ("parse error '%U'", format_unformat_error, input);
14508           return -99;
14509         }
14510     }
14511
14512   if (!mode_set)
14513     {
14514       errmsg ("expected one of 'l2' or 'l3' parameter!");
14515       return -99;
14516     }
14517
14518   if (!vam->json_output)
14519     {
14520       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
14521     }
14522
14523   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14524   mp->is_l2 = is_l2;
14525
14526   /* send it... */
14527   S;
14528
14529   /* Use a control ping for synchronization */
14530   {
14531     vl_api_control_ping_t *mp;
14532     M (CONTROL_PING, control_ping);
14533     S;
14534   }
14535   /* Wait for a reply... */
14536   W;
14537
14538   /* NOTREACHED */
14539   return 0;
14540 }
14541
14542 static int
14543 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14544 {
14545   vl_api_lisp_eid_table_vni_dump_t *mp;
14546   f64 timeout = ~0;
14547
14548   if (!vam->json_output)
14549     {
14550       print (vam->ofp, "VNI");
14551     }
14552
14553   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14554
14555   /* send it... */
14556   S;
14557
14558   /* Use a control ping for synchronization */
14559   {
14560     vl_api_control_ping_t *mp;
14561     M (CONTROL_PING, control_ping);
14562     S;
14563   }
14564   /* Wait for a reply... */
14565   W;
14566
14567   /* NOTREACHED */
14568   return 0;
14569 }
14570
14571 static int
14572 api_lisp_eid_table_dump (vat_main_t * vam)
14573 {
14574   unformat_input_t *i = vam->input;
14575   vl_api_lisp_eid_table_dump_t *mp;
14576   f64 timeout = ~0;
14577   struct in_addr ip4;
14578   struct in6_addr ip6;
14579   u8 mac[6];
14580   u8 eid_type = ~0, eid_set = 0;
14581   u32 prefix_length = ~0, t, vni = 0;
14582   u8 filter = 0;
14583
14584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14585     {
14586       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14587         {
14588           eid_set = 1;
14589           eid_type = 0;
14590           prefix_length = t;
14591         }
14592       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14593         {
14594           eid_set = 1;
14595           eid_type = 1;
14596           prefix_length = t;
14597         }
14598       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14599         {
14600           eid_set = 1;
14601           eid_type = 2;
14602         }
14603       else if (unformat (i, "vni %d", &t))
14604         {
14605           vni = t;
14606         }
14607       else if (unformat (i, "local"))
14608         {
14609           filter = 1;
14610         }
14611       else if (unformat (i, "remote"))
14612         {
14613           filter = 2;
14614         }
14615       else
14616         {
14617           errmsg ("parse error '%U'", format_unformat_error, i);
14618           return -99;
14619         }
14620     }
14621
14622   if (!vam->json_output)
14623     {
14624       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
14625              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14626     }
14627
14628   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14629
14630   mp->filter = filter;
14631   if (eid_set)
14632     {
14633       mp->eid_set = 1;
14634       mp->vni = htonl (vni);
14635       mp->eid_type = eid_type;
14636       switch (eid_type)
14637         {
14638         case 0:
14639           mp->prefix_length = prefix_length;
14640           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14641           break;
14642         case 1:
14643           mp->prefix_length = prefix_length;
14644           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14645           break;
14646         case 2:
14647           clib_memcpy (mp->eid, mac, sizeof (mac));
14648           break;
14649         default:
14650           errmsg ("unknown EID type %d!", eid_type);
14651           return -99;
14652         }
14653     }
14654
14655   /* send it... */
14656   S;
14657
14658   /* Use a control ping for synchronization */
14659   {
14660     vl_api_control_ping_t *mp;
14661     M (CONTROL_PING, control_ping);
14662     S;
14663   }
14664
14665   /* Wait for a reply... */
14666   W;
14667
14668   /* NOTREACHED */
14669   return 0;
14670 }
14671
14672 static int
14673 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14674 {
14675   vl_api_lisp_gpe_tunnel_dump_t *mp;
14676   f64 timeout = ~0;
14677
14678   if (!vam->json_output)
14679     {
14680       print (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14681              "%=16s%=16s%=16s%=16s%=16s",
14682              "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14683              "Decap next", "Lisp version", "Flags", "Next protocol",
14684              "ver_res", "res", "iid");
14685     }
14686
14687   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14688   /* send it... */
14689   S;
14690
14691   /* Use a control ping for synchronization */
14692   {
14693     vl_api_control_ping_t *mp;
14694     M (CONTROL_PING, control_ping);
14695     S;
14696   }
14697   /* Wait for a reply... */
14698   W;
14699
14700   /* NOTREACHED */
14701   return 0;
14702 }
14703
14704 static int
14705 api_lisp_adjacencies_get (vat_main_t * vam)
14706 {
14707   unformat_input_t *i = vam->input;
14708   vl_api_lisp_adjacencies_get_t *mp;
14709   f64 timeout = ~0;
14710   u8 vni_set = 0;
14711   u32 vni = ~0;
14712
14713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14714     {
14715       if (unformat (i, "vni %d", &vni))
14716         {
14717           vni_set = 1;
14718         }
14719       else
14720         {
14721           errmsg ("parse error '%U'", format_unformat_error, i);
14722           return -99;
14723         }
14724     }
14725
14726   if (!vni_set)
14727     {
14728       errmsg ("vni not set!");
14729       return -99;
14730     }
14731
14732   if (!vam->json_output)
14733     {
14734       print (vam->ofp, "%s %40s", "leid", "reid");
14735     }
14736
14737   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14738   mp->vni = clib_host_to_net_u32 (vni);
14739
14740   /* send it... */
14741   S;
14742
14743   /* Wait for a reply... */
14744   W;
14745
14746   /* NOTREACHED */
14747   return 0;
14748 }
14749
14750 static int
14751 api_lisp_map_server_dump (vat_main_t * vam)
14752 {
14753   vl_api_lisp_map_server_dump_t *mp;
14754   f64 timeout = ~0;
14755
14756   if (!vam->json_output)
14757     {
14758       print (vam->ofp, "%=20s", "Map server");
14759     }
14760
14761   M (LISP_MAP_SERVER_DUMP, lisp_map_server_dump);
14762   /* send it... */
14763   S;
14764
14765   /* Use a control ping for synchronization */
14766   {
14767     vl_api_control_ping_t *mp;
14768     M (CONTROL_PING, control_ping);
14769     S;
14770   }
14771   /* Wait for a reply... */
14772   W;
14773
14774   /* NOTREACHED */
14775   return 0;
14776 }
14777
14778 static int
14779 api_lisp_map_resolver_dump (vat_main_t * vam)
14780 {
14781   vl_api_lisp_map_resolver_dump_t *mp;
14782   f64 timeout = ~0;
14783
14784   if (!vam->json_output)
14785     {
14786       print (vam->ofp, "%=20s", "Map resolver");
14787     }
14788
14789   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14790   /* send it... */
14791   S;
14792
14793   /* Use a control ping for synchronization */
14794   {
14795     vl_api_control_ping_t *mp;
14796     M (CONTROL_PING, control_ping);
14797     S;
14798   }
14799   /* Wait for a reply... */
14800   W;
14801
14802   /* NOTREACHED */
14803   return 0;
14804 }
14805
14806 static int
14807 api_show_lisp_status (vat_main_t * vam)
14808 {
14809   vl_api_show_lisp_status_t *mp;
14810   f64 timeout = ~0;
14811
14812   if (!vam->json_output)
14813     {
14814       print (vam->ofp, "%-20s%-16s", "lisp status", "locator-set");
14815     }
14816
14817   M (SHOW_LISP_STATUS, show_lisp_status);
14818   /* send it... */
14819   S;
14820   /* Wait for a reply... */
14821   W;
14822
14823   /* NOTREACHED */
14824   return 0;
14825 }
14826
14827 static int
14828 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14829 {
14830   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14831   f64 timeout = ~0;
14832
14833   if (!vam->json_output)
14834     {
14835       print (vam->ofp, "%=20s", "itr-rlocs:");
14836     }
14837
14838   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14839   /* send it... */
14840   S;
14841   /* Wait for a reply... */
14842   W;
14843
14844   /* NOTREACHED */
14845   return 0;
14846 }
14847
14848 static int
14849 api_af_packet_create (vat_main_t * vam)
14850 {
14851   unformat_input_t *i = vam->input;
14852   vl_api_af_packet_create_t *mp;
14853   f64 timeout;
14854   u8 *host_if_name = 0;
14855   u8 hw_addr[6];
14856   u8 random_hw_addr = 1;
14857
14858   memset (hw_addr, 0, sizeof (hw_addr));
14859
14860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14861     {
14862       if (unformat (i, "name %s", &host_if_name))
14863         vec_add1 (host_if_name, 0);
14864       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14865         random_hw_addr = 0;
14866       else
14867         break;
14868     }
14869
14870   if (!vec_len (host_if_name))
14871     {
14872       errmsg ("host-interface name must be specified");
14873       return -99;
14874     }
14875
14876   if (vec_len (host_if_name) > 64)
14877     {
14878       errmsg ("host-interface name too long");
14879       return -99;
14880     }
14881
14882   M (AF_PACKET_CREATE, af_packet_create);
14883
14884   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14885   clib_memcpy (mp->hw_addr, hw_addr, 6);
14886   mp->use_random_hw_addr = random_hw_addr;
14887   vec_free (host_if_name);
14888
14889   S;
14890   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14891   /* NOTREACHED */
14892   return 0;
14893 }
14894
14895 static int
14896 api_af_packet_delete (vat_main_t * vam)
14897 {
14898   unformat_input_t *i = vam->input;
14899   vl_api_af_packet_delete_t *mp;
14900   f64 timeout;
14901   u8 *host_if_name = 0;
14902
14903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14904     {
14905       if (unformat (i, "name %s", &host_if_name))
14906         vec_add1 (host_if_name, 0);
14907       else
14908         break;
14909     }
14910
14911   if (!vec_len (host_if_name))
14912     {
14913       errmsg ("host-interface name must be specified");
14914       return -99;
14915     }
14916
14917   if (vec_len (host_if_name) > 64)
14918     {
14919       errmsg ("host-interface name too long");
14920       return -99;
14921     }
14922
14923   M (AF_PACKET_DELETE, af_packet_delete);
14924
14925   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14926   vec_free (host_if_name);
14927
14928   S;
14929   W;
14930   /* NOTREACHED */
14931   return 0;
14932 }
14933
14934 static int
14935 api_policer_add_del (vat_main_t * vam)
14936 {
14937   unformat_input_t *i = vam->input;
14938   vl_api_policer_add_del_t *mp;
14939   f64 timeout;
14940   u8 is_add = 1;
14941   u8 *name = 0;
14942   u32 cir = 0;
14943   u32 eir = 0;
14944   u64 cb = 0;
14945   u64 eb = 0;
14946   u8 rate_type = 0;
14947   u8 round_type = 0;
14948   u8 type = 0;
14949   u8 color_aware = 0;
14950   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14951
14952   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14953   conform_action.dscp = 0;
14954   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14955   exceed_action.dscp = 0;
14956   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14957   violate_action.dscp = 0;
14958
14959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14960     {
14961       if (unformat (i, "del"))
14962         is_add = 0;
14963       else if (unformat (i, "name %s", &name))
14964         vec_add1 (name, 0);
14965       else if (unformat (i, "cir %u", &cir))
14966         ;
14967       else if (unformat (i, "eir %u", &eir))
14968         ;
14969       else if (unformat (i, "cb %u", &cb))
14970         ;
14971       else if (unformat (i, "eb %u", &eb))
14972         ;
14973       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14974                          &rate_type))
14975         ;
14976       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14977                          &round_type))
14978         ;
14979       else if (unformat (i, "type %U", unformat_policer_type, &type))
14980         ;
14981       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14982                          &conform_action))
14983         ;
14984       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14985                          &exceed_action))
14986         ;
14987       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14988                          &violate_action))
14989         ;
14990       else if (unformat (i, "color-aware"))
14991         color_aware = 1;
14992       else
14993         break;
14994     }
14995
14996   if (!vec_len (name))
14997     {
14998       errmsg ("policer name must be specified");
14999       return -99;
15000     }
15001
15002   if (vec_len (name) > 64)
15003     {
15004       errmsg ("policer name too long");
15005       return -99;
15006     }
15007
15008   M (POLICER_ADD_DEL, policer_add_del);
15009
15010   clib_memcpy (mp->name, name, vec_len (name));
15011   vec_free (name);
15012   mp->is_add = is_add;
15013   mp->cir = cir;
15014   mp->eir = eir;
15015   mp->cb = cb;
15016   mp->eb = eb;
15017   mp->rate_type = rate_type;
15018   mp->round_type = round_type;
15019   mp->type = type;
15020   mp->conform_action_type = conform_action.action_type;
15021   mp->conform_dscp = conform_action.dscp;
15022   mp->exceed_action_type = exceed_action.action_type;
15023   mp->exceed_dscp = exceed_action.dscp;
15024   mp->violate_action_type = violate_action.action_type;
15025   mp->violate_dscp = violate_action.dscp;
15026   mp->color_aware = color_aware;
15027
15028   S;
15029   W;
15030   /* NOTREACHED */
15031   return 0;
15032 }
15033
15034 static int
15035 api_policer_dump (vat_main_t * vam)
15036 {
15037   unformat_input_t *i = vam->input;
15038   vl_api_policer_dump_t *mp;
15039   f64 timeout = ~0;
15040   u8 *match_name = 0;
15041   u8 match_name_valid = 0;
15042
15043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15044     {
15045       if (unformat (i, "name %s", &match_name))
15046         {
15047           vec_add1 (match_name, 0);
15048           match_name_valid = 1;
15049         }
15050       else
15051         break;
15052     }
15053
15054   M (POLICER_DUMP, policer_dump);
15055   mp->match_name_valid = match_name_valid;
15056   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15057   vec_free (match_name);
15058   /* send it... */
15059   S;
15060
15061   /* Use a control ping for synchronization */
15062   {
15063     vl_api_control_ping_t *mp;
15064     M (CONTROL_PING, control_ping);
15065     S;
15066   }
15067   /* Wait for a reply... */
15068   W;
15069
15070   /* NOTREACHED */
15071   return 0;
15072 }
15073
15074 static int
15075 api_policer_classify_set_interface (vat_main_t * vam)
15076 {
15077   unformat_input_t *i = vam->input;
15078   vl_api_policer_classify_set_interface_t *mp;
15079   f64 timeout;
15080   u32 sw_if_index;
15081   int sw_if_index_set;
15082   u32 ip4_table_index = ~0;
15083   u32 ip6_table_index = ~0;
15084   u32 l2_table_index = ~0;
15085   u8 is_add = 1;
15086
15087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15088     {
15089       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15090         sw_if_index_set = 1;
15091       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15092         sw_if_index_set = 1;
15093       else if (unformat (i, "del"))
15094         is_add = 0;
15095       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15096         ;
15097       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15098         ;
15099       else if (unformat (i, "l2-table %d", &l2_table_index))
15100         ;
15101       else
15102         {
15103           clib_warning ("parse error '%U'", format_unformat_error, i);
15104           return -99;
15105         }
15106     }
15107
15108   if (sw_if_index_set == 0)
15109     {
15110       errmsg ("missing interface name or sw_if_index");
15111       return -99;
15112     }
15113
15114   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
15115
15116   mp->sw_if_index = ntohl (sw_if_index);
15117   mp->ip4_table_index = ntohl (ip4_table_index);
15118   mp->ip6_table_index = ntohl (ip6_table_index);
15119   mp->l2_table_index = ntohl (l2_table_index);
15120   mp->is_add = is_add;
15121
15122   S;
15123   W;
15124   /* NOTREACHED */
15125   return 0;
15126 }
15127
15128 static int
15129 api_policer_classify_dump (vat_main_t * vam)
15130 {
15131   unformat_input_t *i = vam->input;
15132   vl_api_policer_classify_dump_t *mp;
15133   f64 timeout = ~0;
15134   u8 type = POLICER_CLASSIFY_N_TABLES;
15135
15136   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15137     ;
15138   else
15139     {
15140       errmsg ("classify table type must be specified");
15141       return -99;
15142     }
15143
15144   if (!vam->json_output)
15145     {
15146       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15147     }
15148
15149   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
15150   mp->type = type;
15151   /* send it... */
15152   S;
15153
15154   /* Use a control ping for synchronization */
15155   {
15156     vl_api_control_ping_t *mp;
15157     M (CONTROL_PING, control_ping);
15158     S;
15159   }
15160   /* Wait for a reply... */
15161   W;
15162
15163   /* NOTREACHED */
15164   return 0;
15165 }
15166
15167 static int
15168 api_netmap_create (vat_main_t * vam)
15169 {
15170   unformat_input_t *i = vam->input;
15171   vl_api_netmap_create_t *mp;
15172   f64 timeout;
15173   u8 *if_name = 0;
15174   u8 hw_addr[6];
15175   u8 random_hw_addr = 1;
15176   u8 is_pipe = 0;
15177   u8 is_master = 0;
15178
15179   memset (hw_addr, 0, sizeof (hw_addr));
15180
15181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15182     {
15183       if (unformat (i, "name %s", &if_name))
15184         vec_add1 (if_name, 0);
15185       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15186         random_hw_addr = 0;
15187       else if (unformat (i, "pipe"))
15188         is_pipe = 1;
15189       else if (unformat (i, "master"))
15190         is_master = 1;
15191       else if (unformat (i, "slave"))
15192         is_master = 0;
15193       else
15194         break;
15195     }
15196
15197   if (!vec_len (if_name))
15198     {
15199       errmsg ("interface name must be specified");
15200       return -99;
15201     }
15202
15203   if (vec_len (if_name) > 64)
15204     {
15205       errmsg ("interface name too long");
15206       return -99;
15207     }
15208
15209   M (NETMAP_CREATE, netmap_create);
15210
15211   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15212   clib_memcpy (mp->hw_addr, hw_addr, 6);
15213   mp->use_random_hw_addr = random_hw_addr;
15214   mp->is_pipe = is_pipe;
15215   mp->is_master = is_master;
15216   vec_free (if_name);
15217
15218   S;
15219   W;
15220   /* NOTREACHED */
15221   return 0;
15222 }
15223
15224 static int
15225 api_netmap_delete (vat_main_t * vam)
15226 {
15227   unformat_input_t *i = vam->input;
15228   vl_api_netmap_delete_t *mp;
15229   f64 timeout;
15230   u8 *if_name = 0;
15231
15232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15233     {
15234       if (unformat (i, "name %s", &if_name))
15235         vec_add1 (if_name, 0);
15236       else
15237         break;
15238     }
15239
15240   if (!vec_len (if_name))
15241     {
15242       errmsg ("interface name must be specified");
15243       return -99;
15244     }
15245
15246   if (vec_len (if_name) > 64)
15247     {
15248       errmsg ("interface name too long");
15249       return -99;
15250     }
15251
15252   M (NETMAP_DELETE, netmap_delete);
15253
15254   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15255   vec_free (if_name);
15256
15257   S;
15258   W;
15259   /* NOTREACHED */
15260   return 0;
15261 }
15262
15263 static void vl_api_mpls_tunnel_details_t_handler
15264   (vl_api_mpls_tunnel_details_t * mp)
15265 {
15266   vat_main_t *vam = &vat_main;
15267   i32 len = mp->mt_next_hop_n_labels;
15268   i32 i;
15269
15270   print (vam->ofp, "[%d]: via %U %d labels ",
15271          mp->tunnel_index,
15272          format_ip4_address, mp->mt_next_hop,
15273          ntohl (mp->mt_next_hop_sw_if_index));
15274   for (i = 0; i < len; i++)
15275     {
15276       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15277     }
15278   print (vam->ofp, "");
15279 }
15280
15281 static void vl_api_mpls_tunnel_details_t_handler_json
15282   (vl_api_mpls_tunnel_details_t * mp)
15283 {
15284   vat_main_t *vam = &vat_main;
15285   vat_json_node_t *node = NULL;
15286   struct in_addr ip4;
15287   i32 i;
15288   i32 len = mp->mt_next_hop_n_labels;
15289
15290   if (VAT_JSON_ARRAY != vam->json_tree.type)
15291     {
15292       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15293       vat_json_init_array (&vam->json_tree);
15294     }
15295   node = vat_json_array_add (&vam->json_tree);
15296
15297   vat_json_init_object (node);
15298   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15299   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15300   vat_json_object_add_ip4 (node, "next_hop", ip4);
15301   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15302                             ntohl (mp->mt_next_hop_sw_if_index));
15303   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15304   vat_json_object_add_uint (node, "label_count", len);
15305   for (i = 0; i < len; i++)
15306     {
15307       vat_json_object_add_uint (node, "label",
15308                                 ntohl (mp->mt_next_hop_out_labels[i]));
15309     }
15310 }
15311
15312 static int
15313 api_mpls_tunnel_dump (vat_main_t * vam)
15314 {
15315   vl_api_mpls_tunnel_dump_t *mp;
15316   f64 timeout;
15317   i32 index = -1;
15318
15319   /* Parse args required to build the message */
15320   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15321     {
15322       if (!unformat (vam->input, "tunnel_index %d", &index))
15323         {
15324           index = -1;
15325           break;
15326         }
15327     }
15328
15329   print (vam->ofp, "  tunnel_index %d", index);
15330
15331   M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
15332   mp->tunnel_index = htonl (index);
15333   S;
15334
15335   /* Use a control ping for synchronization */
15336   {
15337     vl_api_control_ping_t *mp;
15338     M (CONTROL_PING, control_ping);
15339     S;
15340   }
15341   W;
15342 }
15343
15344 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15345 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15346
15347 static void
15348 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15349 {
15350   vat_main_t *vam = &vat_main;
15351   int count = ntohl (mp->count);
15352   vl_api_fib_path2_t *fp;
15353   int i;
15354
15355   print (vam->ofp,
15356          "table-id %d, label %u, ess_bit %u",
15357          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15358   fp = mp->path;
15359   for (i = 0; i < count; i++)
15360     {
15361       if (fp->afi == IP46_TYPE_IP6)
15362         print (vam->ofp,
15363                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15364                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15365                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15366                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15367                format_ip6_address, fp->next_hop);
15368       else if (fp->afi == IP46_TYPE_IP4)
15369         print (vam->ofp,
15370                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15371                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15372                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15373                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15374                format_ip4_address, fp->next_hop);
15375       fp++;
15376     }
15377 }
15378
15379 static void vl_api_mpls_fib_details_t_handler_json
15380   (vl_api_mpls_fib_details_t * mp)
15381 {
15382   vat_main_t *vam = &vat_main;
15383   int count = ntohl (mp->count);
15384   vat_json_node_t *node = NULL;
15385   struct in_addr ip4;
15386   struct in6_addr ip6;
15387   vl_api_fib_path2_t *fp;
15388   int i;
15389
15390   if (VAT_JSON_ARRAY != vam->json_tree.type)
15391     {
15392       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15393       vat_json_init_array (&vam->json_tree);
15394     }
15395   node = vat_json_array_add (&vam->json_tree);
15396
15397   vat_json_init_object (node);
15398   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15399   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15400   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15401   vat_json_object_add_uint (node, "path_count", count);
15402   fp = mp->path;
15403   for (i = 0; i < count; i++)
15404     {
15405       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15406       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15407       vat_json_object_add_uint (node, "is_local", fp->is_local);
15408       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15409       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15410       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15411       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15412       if (fp->afi == IP46_TYPE_IP4)
15413         {
15414           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15415           vat_json_object_add_ip4 (node, "next_hop", ip4);
15416         }
15417       else if (fp->afi == IP46_TYPE_IP6)
15418         {
15419           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15420           vat_json_object_add_ip6 (node, "next_hop", ip6);
15421         }
15422     }
15423 }
15424
15425 static int
15426 api_mpls_fib_dump (vat_main_t * vam)
15427 {
15428   vl_api_mpls_fib_dump_t *mp;
15429   f64 timeout;
15430
15431   M (MPLS_FIB_DUMP, mpls_fib_dump);
15432   S;
15433
15434   /* Use a control ping for synchronization */
15435   {
15436     vl_api_control_ping_t *mp;
15437     M (CONTROL_PING, control_ping);
15438     S;
15439   }
15440   W;
15441 }
15442
15443 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15444 #define vl_api_ip_fib_details_t_print vl_noop_handler
15445
15446 static void
15447 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15448 {
15449   vat_main_t *vam = &vat_main;
15450   int count = ntohl (mp->count);
15451   vl_api_fib_path_t *fp;
15452   int i;
15453
15454   print (vam->ofp,
15455          "table-id %d, prefix %U/%d",
15456          ntohl (mp->table_id), format_ip4_address, mp->address,
15457          mp->address_length);
15458   fp = mp->path;
15459   for (i = 0; i < count; i++)
15460     {
15461       if (fp->afi == IP46_TYPE_IP6)
15462         print (vam->ofp,
15463                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15464                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15465                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15466                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15467                format_ip6_address, fp->next_hop);
15468       else if (fp->afi == IP46_TYPE_IP4)
15469         print (vam->ofp,
15470                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15471                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15472                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15473                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15474                format_ip4_address, fp->next_hop);
15475       fp++;
15476     }
15477 }
15478
15479 static void vl_api_ip_fib_details_t_handler_json
15480   (vl_api_ip_fib_details_t * mp)
15481 {
15482   vat_main_t *vam = &vat_main;
15483   int count = ntohl (mp->count);
15484   vat_json_node_t *node = NULL;
15485   struct in_addr ip4;
15486   struct in6_addr ip6;
15487   vl_api_fib_path_t *fp;
15488   int i;
15489
15490   if (VAT_JSON_ARRAY != vam->json_tree.type)
15491     {
15492       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15493       vat_json_init_array (&vam->json_tree);
15494     }
15495   node = vat_json_array_add (&vam->json_tree);
15496
15497   vat_json_init_object (node);
15498   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15499   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15500   vat_json_object_add_ip4 (node, "prefix", ip4);
15501   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15502   vat_json_object_add_uint (node, "path_count", count);
15503   fp = mp->path;
15504   for (i = 0; i < count; i++)
15505     {
15506       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15507       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15508       vat_json_object_add_uint (node, "is_local", fp->is_local);
15509       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15510       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15511       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15512       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15513       if (fp->afi == IP46_TYPE_IP4)
15514         {
15515           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15516           vat_json_object_add_ip4 (node, "next_hop", ip4);
15517         }
15518       else if (fp->afi == IP46_TYPE_IP6)
15519         {
15520           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15521           vat_json_object_add_ip6 (node, "next_hop", ip6);
15522         }
15523     }
15524 }
15525
15526 static int
15527 api_ip_fib_dump (vat_main_t * vam)
15528 {
15529   vl_api_ip_fib_dump_t *mp;
15530   f64 timeout;
15531
15532   M (IP_FIB_DUMP, ip_fib_dump);
15533   S;
15534
15535   /* Use a control ping for synchronization */
15536   {
15537     vl_api_control_ping_t *mp;
15538     M (CONTROL_PING, control_ping);
15539     S;
15540   }
15541   W;
15542 }
15543
15544 static void vl_api_ip_neighbor_details_t_handler
15545   (vl_api_ip_neighbor_details_t * mp)
15546 {
15547   vat_main_t *vam = &vat_main;
15548
15549   print (vam->ofp, "%c %U %U",
15550          (mp->is_static) ? 'S' : 'D',
15551          format_ethernet_address, &mp->mac_address,
15552          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15553          &mp->ip_address);
15554 }
15555
15556 static void vl_api_ip_neighbor_details_t_handler_json
15557   (vl_api_ip_neighbor_details_t * mp)
15558 {
15559
15560   vat_main_t *vam = &vat_main;
15561   vat_json_node_t *node;
15562   struct in_addr ip4;
15563   struct in6_addr ip6;
15564
15565   if (VAT_JSON_ARRAY != vam->json_tree.type)
15566     {
15567       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15568       vat_json_init_array (&vam->json_tree);
15569     }
15570   node = vat_json_array_add (&vam->json_tree);
15571
15572   vat_json_init_object (node);
15573   vat_json_object_add_string_copy (node, "flag",
15574                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15575                                    "dynamic");
15576
15577   vat_json_object_add_string_copy (node, "link_layer",
15578                                    format (0, "%U", format_ethernet_address,
15579                                            &mp->mac_address));
15580
15581   if (mp->is_ipv6)
15582     {
15583       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15584       vat_json_object_add_ip6 (node, "ip_address", ip6);
15585     }
15586   else
15587     {
15588       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15589       vat_json_object_add_ip4 (node, "ip_address", ip4);
15590     }
15591 }
15592
15593 static int
15594 api_ip_neighbor_dump (vat_main_t * vam)
15595 {
15596   unformat_input_t *i = vam->input;
15597   vl_api_ip_neighbor_dump_t *mp;
15598   f64 timeout;
15599   u8 is_ipv6 = 0;
15600   u32 sw_if_index = ~0;
15601
15602   /* Parse args required to build the message */
15603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15604     {
15605       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15606         ;
15607       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15608         ;
15609       else if (unformat (i, "ip6"))
15610         is_ipv6 = 1;
15611       else
15612         break;
15613     }
15614
15615   if (sw_if_index == ~0)
15616     {
15617       errmsg ("missing interface name or sw_if_index");
15618       return -99;
15619     }
15620
15621   M (IP_NEIGHBOR_DUMP, ip_neighbor_dump);
15622   mp->is_ipv6 = (u8) is_ipv6;
15623   mp->sw_if_index = ntohl (sw_if_index);
15624   S;
15625
15626   /* Use a control ping for synchronization */
15627   {
15628     vl_api_control_ping_t *mp;
15629     M (CONTROL_PING, control_ping);
15630     S;
15631   }
15632   W;
15633 }
15634
15635 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15636 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15637
15638 static void
15639 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15640 {
15641   vat_main_t *vam = &vat_main;
15642   int count = ntohl (mp->count);
15643   vl_api_fib_path_t *fp;
15644   int i;
15645
15646   print (vam->ofp,
15647          "table-id %d, prefix %U/%d",
15648          ntohl (mp->table_id), format_ip6_address, mp->address,
15649          mp->address_length);
15650   fp = mp->path;
15651   for (i = 0; i < count; i++)
15652     {
15653       if (fp->afi == IP46_TYPE_IP6)
15654         print (vam->ofp,
15655                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15656                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15657                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15658                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15659                format_ip6_address, fp->next_hop);
15660       else if (fp->afi == IP46_TYPE_IP4)
15661         print (vam->ofp,
15662                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15663                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15664                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15665                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15666                format_ip4_address, fp->next_hop);
15667       fp++;
15668     }
15669 }
15670
15671 static void vl_api_ip6_fib_details_t_handler_json
15672   (vl_api_ip6_fib_details_t * mp)
15673 {
15674   vat_main_t *vam = &vat_main;
15675   int count = ntohl (mp->count);
15676   vat_json_node_t *node = NULL;
15677   struct in_addr ip4;
15678   struct in6_addr ip6;
15679   vl_api_fib_path_t *fp;
15680   int i;
15681
15682   if (VAT_JSON_ARRAY != vam->json_tree.type)
15683     {
15684       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15685       vat_json_init_array (&vam->json_tree);
15686     }
15687   node = vat_json_array_add (&vam->json_tree);
15688
15689   vat_json_init_object (node);
15690   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15691   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15692   vat_json_object_add_ip6 (node, "prefix", ip6);
15693   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15694   vat_json_object_add_uint (node, "path_count", count);
15695   fp = mp->path;
15696   for (i = 0; i < count; i++)
15697     {
15698       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15699       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15700       vat_json_object_add_uint (node, "is_local", fp->is_local);
15701       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15702       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15703       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15704       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15705       if (fp->afi == IP46_TYPE_IP4)
15706         {
15707           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15708           vat_json_object_add_ip4 (node, "next_hop", ip4);
15709         }
15710       else if (fp->afi == IP46_TYPE_IP6)
15711         {
15712           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15713           vat_json_object_add_ip6 (node, "next_hop", ip6);
15714         }
15715     }
15716 }
15717
15718 static int
15719 api_ip6_fib_dump (vat_main_t * vam)
15720 {
15721   vl_api_ip6_fib_dump_t *mp;
15722   f64 timeout;
15723
15724   M (IP6_FIB_DUMP, ip6_fib_dump);
15725   S;
15726
15727   /* Use a control ping for synchronization */
15728   {
15729     vl_api_control_ping_t *mp;
15730     M (CONTROL_PING, control_ping);
15731     S;
15732   }
15733   W;
15734 }
15735
15736 int
15737 api_classify_table_ids (vat_main_t * vam)
15738 {
15739   vl_api_classify_table_ids_t *mp;
15740   f64 timeout;
15741
15742   /* Construct the API message */
15743   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15744   mp->context = 0;
15745
15746   S;
15747   W;
15748   /* NOTREACHED */
15749   return 0;
15750 }
15751
15752 int
15753 api_classify_table_by_interface (vat_main_t * vam)
15754 {
15755   unformat_input_t *input = vam->input;
15756   vl_api_classify_table_by_interface_t *mp;
15757   f64 timeout;
15758
15759   u32 sw_if_index = ~0;
15760   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15761     {
15762       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15763         ;
15764       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15765         ;
15766       else
15767         break;
15768     }
15769   if (sw_if_index == ~0)
15770     {
15771       errmsg ("missing interface name or sw_if_index");
15772       return -99;
15773     }
15774
15775   /* Construct the API message */
15776   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15777   mp->context = 0;
15778   mp->sw_if_index = ntohl (sw_if_index);
15779
15780   S;
15781   W;
15782   /* NOTREACHED */
15783   return 0;
15784 }
15785
15786 int
15787 api_classify_table_info (vat_main_t * vam)
15788 {
15789   unformat_input_t *input = vam->input;
15790   vl_api_classify_table_info_t *mp;
15791   f64 timeout;
15792
15793   u32 table_id = ~0;
15794   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15795     {
15796       if (unformat (input, "table_id %d", &table_id))
15797         ;
15798       else
15799         break;
15800     }
15801   if (table_id == ~0)
15802     {
15803       errmsg ("missing table id");
15804       return -99;
15805     }
15806
15807   /* Construct the API message */
15808   M (CLASSIFY_TABLE_INFO, classify_table_info);
15809   mp->context = 0;
15810   mp->table_id = ntohl (table_id);
15811
15812   S;
15813   W;
15814   /* NOTREACHED */
15815   return 0;
15816 }
15817
15818 int
15819 api_classify_session_dump (vat_main_t * vam)
15820 {
15821   unformat_input_t *input = vam->input;
15822   vl_api_classify_session_dump_t *mp;
15823   f64 timeout;
15824
15825   u32 table_id = ~0;
15826   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15827     {
15828       if (unformat (input, "table_id %d", &table_id))
15829         ;
15830       else
15831         break;
15832     }
15833   if (table_id == ~0)
15834     {
15835       errmsg ("missing table id");
15836       return -99;
15837     }
15838
15839   /* Construct the API message */
15840   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15841   mp->context = 0;
15842   mp->table_id = ntohl (table_id);
15843   S;
15844
15845   /* Use a control ping for synchronization */
15846   {
15847     vl_api_control_ping_t *mp;
15848     M (CONTROL_PING, control_ping);
15849     S;
15850   }
15851   W;
15852   /* NOTREACHED */
15853   return 0;
15854 }
15855
15856 static void
15857 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15858 {
15859   vat_main_t *vam = &vat_main;
15860
15861   print (vam->ofp, "collector_address %U, collector_port %d, "
15862          "src_address %U, vrf_id %d, path_mtu %u, "
15863          "template_interval %u, udp_checksum %d",
15864          format_ip4_address, mp->collector_address,
15865          ntohs (mp->collector_port),
15866          format_ip4_address, mp->src_address,
15867          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15868          ntohl (mp->template_interval), mp->udp_checksum);
15869
15870   vam->retval = 0;
15871   vam->result_ready = 1;
15872 }
15873
15874 static void
15875   vl_api_ipfix_exporter_details_t_handler_json
15876   (vl_api_ipfix_exporter_details_t * mp)
15877 {
15878   vat_main_t *vam = &vat_main;
15879   vat_json_node_t node;
15880   struct in_addr collector_address;
15881   struct in_addr src_address;
15882
15883   vat_json_init_object (&node);
15884   clib_memcpy (&collector_address, &mp->collector_address,
15885                sizeof (collector_address));
15886   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15887   vat_json_object_add_uint (&node, "collector_port",
15888                             ntohs (mp->collector_port));
15889   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15890   vat_json_object_add_ip4 (&node, "src_address", src_address);
15891   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15892   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15893   vat_json_object_add_uint (&node, "template_interval",
15894                             ntohl (mp->template_interval));
15895   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15896
15897   vat_json_print (vam->ofp, &node);
15898   vat_json_free (&node);
15899   vam->retval = 0;
15900   vam->result_ready = 1;
15901 }
15902
15903 int
15904 api_ipfix_exporter_dump (vat_main_t * vam)
15905 {
15906   vl_api_ipfix_exporter_dump_t *mp;
15907   f64 timeout;
15908
15909   /* Construct the API message */
15910   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15911   mp->context = 0;
15912
15913   S;
15914   W;
15915   /* NOTREACHED */
15916   return 0;
15917 }
15918
15919 static int
15920 api_ipfix_classify_stream_dump (vat_main_t * vam)
15921 {
15922   vl_api_ipfix_classify_stream_dump_t *mp;
15923   f64 timeout;
15924
15925   /* Construct the API message */
15926   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15927   mp->context = 0;
15928
15929   S;
15930   W;
15931   /* NOTREACHED */
15932   return 0;
15933 }
15934
15935 static void
15936   vl_api_ipfix_classify_stream_details_t_handler
15937   (vl_api_ipfix_classify_stream_details_t * mp)
15938 {
15939   vat_main_t *vam = &vat_main;
15940   print (vam->ofp, "domain_id %d, src_port %d",
15941          ntohl (mp->domain_id), ntohs (mp->src_port));
15942   vam->retval = 0;
15943   vam->result_ready = 1;
15944 }
15945
15946 static void
15947   vl_api_ipfix_classify_stream_details_t_handler_json
15948   (vl_api_ipfix_classify_stream_details_t * mp)
15949 {
15950   vat_main_t *vam = &vat_main;
15951   vat_json_node_t node;
15952
15953   vat_json_init_object (&node);
15954   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15955   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15956
15957   vat_json_print (vam->ofp, &node);
15958   vat_json_free (&node);
15959   vam->retval = 0;
15960   vam->result_ready = 1;
15961 }
15962
15963 static int
15964 api_ipfix_classify_table_dump (vat_main_t * vam)
15965 {
15966   vl_api_ipfix_classify_table_dump_t *mp;
15967   f64 timeout;
15968
15969   if (!vam->json_output)
15970     {
15971       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
15972              "transport_protocol");
15973     }
15974
15975   /* Construct the API message */
15976   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15977
15978   /* send it... */
15979   S;
15980
15981   /* Use a control ping for synchronization */
15982   {
15983     vl_api_control_ping_t *mp;
15984     M (CONTROL_PING, control_ping);
15985     S;
15986   }
15987   W;
15988 }
15989
15990 static void
15991   vl_api_ipfix_classify_table_details_t_handler
15992   (vl_api_ipfix_classify_table_details_t * mp)
15993 {
15994   vat_main_t *vam = &vat_main;
15995   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
15996          mp->transport_protocol);
15997 }
15998
15999 static void
16000   vl_api_ipfix_classify_table_details_t_handler_json
16001   (vl_api_ipfix_classify_table_details_t * mp)
16002 {
16003   vat_json_node_t *node = NULL;
16004   vat_main_t *vam = &vat_main;
16005
16006   if (VAT_JSON_ARRAY != vam->json_tree.type)
16007     {
16008       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16009       vat_json_init_array (&vam->json_tree);
16010     }
16011
16012   node = vat_json_array_add (&vam->json_tree);
16013   vat_json_init_object (node);
16014
16015   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16016   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16017   vat_json_object_add_uint (node, "transport_protocol",
16018                             mp->transport_protocol);
16019 }
16020
16021 static int
16022 api_sw_interface_span_enable_disable (vat_main_t * vam)
16023 {
16024   unformat_input_t *i = vam->input;
16025   vl_api_sw_interface_span_enable_disable_t *mp;
16026   f64 timeout;
16027   u32 src_sw_if_index = ~0;
16028   u32 dst_sw_if_index = ~0;
16029   u8 state = 3;
16030
16031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16032     {
16033       if (unformat
16034           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16035         ;
16036       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16037         ;
16038       else
16039         if (unformat
16040             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16041         ;
16042       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16043         ;
16044       else if (unformat (i, "disable"))
16045         state = 0;
16046       else if (unformat (i, "rx"))
16047         state = 1;
16048       else if (unformat (i, "tx"))
16049         state = 2;
16050       else if (unformat (i, "both"))
16051         state = 3;
16052       else
16053         break;
16054     }
16055
16056   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
16057
16058   mp->sw_if_index_from = htonl (src_sw_if_index);
16059   mp->sw_if_index_to = htonl (dst_sw_if_index);
16060   mp->state = state;
16061
16062   S;
16063   W;
16064   /* NOTREACHED */
16065   return 0;
16066 }
16067
16068 static void
16069 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16070                                             * mp)
16071 {
16072   vat_main_t *vam = &vat_main;
16073   u8 *sw_if_from_name = 0;
16074   u8 *sw_if_to_name = 0;
16075   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16076   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16077   char *states[] = { "none", "rx", "tx", "both" };
16078   hash_pair_t *p;
16079
16080   /* *INDENT-OFF* */
16081   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16082   ({
16083     if ((u32) p->value[0] == sw_if_index_from)
16084       {
16085         sw_if_from_name = (u8 *)(p->key);
16086         if (sw_if_to_name)
16087           break;
16088       }
16089     if ((u32) p->value[0] == sw_if_index_to)
16090       {
16091         sw_if_to_name = (u8 *)(p->key);
16092         if (sw_if_from_name)
16093           break;
16094       }
16095   }));
16096   /* *INDENT-ON* */
16097   print (vam->ofp, "%20s => %20s (%s)",
16098          sw_if_from_name, sw_if_to_name, states[mp->state]);
16099 }
16100
16101 static void
16102   vl_api_sw_interface_span_details_t_handler_json
16103   (vl_api_sw_interface_span_details_t * mp)
16104 {
16105   vat_main_t *vam = &vat_main;
16106   vat_json_node_t *node = NULL;
16107   u8 *sw_if_from_name = 0;
16108   u8 *sw_if_to_name = 0;
16109   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16110   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16111   hash_pair_t *p;
16112
16113   /* *INDENT-OFF* */
16114   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16115   ({
16116     if ((u32) p->value[0] == sw_if_index_from)
16117       {
16118         sw_if_from_name = (u8 *)(p->key);
16119         if (sw_if_to_name)
16120           break;
16121       }
16122     if ((u32) p->value[0] == sw_if_index_to)
16123       {
16124         sw_if_to_name = (u8 *)(p->key);
16125         if (sw_if_from_name)
16126           break;
16127       }
16128   }));
16129   /* *INDENT-ON* */
16130
16131   if (VAT_JSON_ARRAY != vam->json_tree.type)
16132     {
16133       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16134       vat_json_init_array (&vam->json_tree);
16135     }
16136   node = vat_json_array_add (&vam->json_tree);
16137
16138   vat_json_init_object (node);
16139   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16140   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16141   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16142   vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16143   vat_json_object_add_uint (node, "state", mp->state);
16144 }
16145
16146 static int
16147 api_sw_interface_span_dump (vat_main_t * vam)
16148 {
16149   vl_api_sw_interface_span_dump_t *mp;
16150   f64 timeout;
16151
16152   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
16153   S;
16154
16155   /* Use a control ping for synchronization */
16156   {
16157     vl_api_control_ping_t *mp;
16158     M (CONTROL_PING, control_ping);
16159     S;
16160   }
16161   W;
16162 }
16163
16164 int
16165 api_pg_create_interface (vat_main_t * vam)
16166 {
16167   unformat_input_t *input = vam->input;
16168   vl_api_pg_create_interface_t *mp;
16169   f64 timeout;
16170
16171   u32 if_id = ~0;
16172   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16173     {
16174       if (unformat (input, "if_id %d", &if_id))
16175         ;
16176       else
16177         break;
16178     }
16179   if (if_id == ~0)
16180     {
16181       errmsg ("missing pg interface index");
16182       return -99;
16183     }
16184
16185   /* Construct the API message */
16186   M (PG_CREATE_INTERFACE, pg_create_interface);
16187   mp->context = 0;
16188   mp->interface_id = ntohl (if_id);
16189
16190   S;
16191   W;
16192   /* NOTREACHED */
16193   return 0;
16194 }
16195
16196 int
16197 api_pg_capture (vat_main_t * vam)
16198 {
16199   unformat_input_t *input = vam->input;
16200   vl_api_pg_capture_t *mp;
16201   f64 timeout;
16202
16203   u32 if_id = ~0;
16204   u8 enable = 1;
16205   u32 count = 1;
16206   u8 pcap_file_set = 0;
16207   u8 *pcap_file = 0;
16208   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16209     {
16210       if (unformat (input, "if_id %d", &if_id))
16211         ;
16212       else if (unformat (input, "pcap %s", &pcap_file))
16213         pcap_file_set = 1;
16214       else if (unformat (input, "count %d", &count))
16215         ;
16216       else if (unformat (input, "disable"))
16217         enable = 0;
16218       else
16219         break;
16220     }
16221   if (if_id == ~0)
16222     {
16223       errmsg ("missing pg interface index");
16224       return -99;
16225     }
16226   if (pcap_file_set > 0)
16227     {
16228       if (vec_len (pcap_file) > 255)
16229         {
16230           errmsg ("pcap file name is too long");
16231           return -99;
16232         }
16233     }
16234
16235   u32 name_len = vec_len (pcap_file);
16236   /* Construct the API message */
16237   M (PG_CAPTURE, pg_capture);
16238   mp->context = 0;
16239   mp->interface_id = ntohl (if_id);
16240   mp->is_enabled = enable;
16241   mp->count = ntohl (count);
16242   mp->pcap_name_length = ntohl (name_len);
16243   if (pcap_file_set != 0)
16244     {
16245       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16246     }
16247   vec_free (pcap_file);
16248
16249   S;
16250   W;
16251   /* NOTREACHED */
16252   return 0;
16253 }
16254
16255 int
16256 api_pg_enable_disable (vat_main_t * vam)
16257 {
16258   unformat_input_t *input = vam->input;
16259   vl_api_pg_enable_disable_t *mp;
16260   f64 timeout;
16261
16262   u8 enable = 1;
16263   u8 stream_name_set = 0;
16264   u8 *stream_name = 0;
16265   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16266     {
16267       if (unformat (input, "stream %s", &stream_name))
16268         stream_name_set = 1;
16269       else if (unformat (input, "disable"))
16270         enable = 0;
16271       else
16272         break;
16273     }
16274
16275   if (stream_name_set > 0)
16276     {
16277       if (vec_len (stream_name) > 255)
16278         {
16279           errmsg ("stream name too long");
16280           return -99;
16281         }
16282     }
16283
16284   u32 name_len = vec_len (stream_name);
16285   /* Construct the API message */
16286   M (PG_ENABLE_DISABLE, pg_enable_disable);
16287   mp->context = 0;
16288   mp->is_enabled = enable;
16289   if (stream_name_set != 0)
16290     {
16291       mp->stream_name_length = ntohl (name_len);
16292       clib_memcpy (mp->stream_name, stream_name, name_len);
16293     }
16294   vec_free (stream_name);
16295
16296   S;
16297   W;
16298   /* NOTREACHED */
16299   return 0;
16300 }
16301
16302 int
16303 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16304 {
16305   unformat_input_t *input = vam->input;
16306   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16307   f64 timeout;
16308
16309   u16 *low_ports = 0;
16310   u16 *high_ports = 0;
16311   u16 this_low;
16312   u16 this_hi;
16313   ip4_address_t ip4_addr;
16314   ip6_address_t ip6_addr;
16315   u32 length;
16316   u32 tmp, tmp2;
16317   u8 prefix_set = 0;
16318   u32 vrf_id = ~0;
16319   u8 is_add = 1;
16320   u8 is_ipv6 = 0;
16321
16322   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16323     {
16324       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16325         {
16326           prefix_set = 1;
16327         }
16328       else
16329         if (unformat
16330             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16331         {
16332           prefix_set = 1;
16333           is_ipv6 = 1;
16334         }
16335       else if (unformat (input, "vrf %d", &vrf_id))
16336         ;
16337       else if (unformat (input, "del"))
16338         is_add = 0;
16339       else if (unformat (input, "port %d", &tmp))
16340         {
16341           if (tmp == 0 || tmp > 65535)
16342             {
16343               errmsg ("port %d out of range", tmp);
16344               return -99;
16345             }
16346           this_low = tmp;
16347           this_hi = this_low + 1;
16348           vec_add1 (low_ports, this_low);
16349           vec_add1 (high_ports, this_hi);
16350         }
16351       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16352         {
16353           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16354             {
16355               errmsg ("incorrect range parameters");
16356               return -99;
16357             }
16358           this_low = tmp;
16359           /* Note: in debug CLI +1 is added to high before
16360              passing to real fn that does "the work"
16361              (ip_source_and_port_range_check_add_del).
16362              This fn is a wrapper around the binary API fn a
16363              control plane will call, which expects this increment
16364              to have occurred. Hence letting the binary API control
16365              plane fn do the increment for consistency between VAT
16366              and other control planes.
16367            */
16368           this_hi = tmp2;
16369           vec_add1 (low_ports, this_low);
16370           vec_add1 (high_ports, this_hi);
16371         }
16372       else
16373         break;
16374     }
16375
16376   if (prefix_set == 0)
16377     {
16378       errmsg ("<address>/<mask> not specified");
16379       return -99;
16380     }
16381
16382   if (vrf_id == ~0)
16383     {
16384       errmsg ("VRF ID required, not specified");
16385       return -99;
16386     }
16387
16388   if (vrf_id == 0)
16389     {
16390       errmsg
16391         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16392       return -99;
16393     }
16394
16395   if (vec_len (low_ports) == 0)
16396     {
16397       errmsg ("At least one port or port range required");
16398       return -99;
16399     }
16400
16401   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
16402      ip_source_and_port_range_check_add_del);
16403
16404   mp->is_add = is_add;
16405
16406   if (is_ipv6)
16407     {
16408       mp->is_ipv6 = 1;
16409       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16410     }
16411   else
16412     {
16413       mp->is_ipv6 = 0;
16414       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16415     }
16416
16417   mp->mask_length = length;
16418   mp->number_of_ranges = vec_len (low_ports);
16419
16420   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16421   vec_free (low_ports);
16422
16423   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16424   vec_free (high_ports);
16425
16426   mp->vrf_id = ntohl (vrf_id);
16427
16428   S;
16429   W;
16430   /* NOTREACHED */
16431   return 0;
16432 }
16433
16434 int
16435 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16436 {
16437   unformat_input_t *input = vam->input;
16438   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16439   f64 timeout;
16440   u32 sw_if_index = ~0;
16441   int vrf_set = 0;
16442   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16443   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16444   u8 is_add = 1;
16445
16446   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16447     {
16448       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16449         ;
16450       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16451         ;
16452       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16453         vrf_set = 1;
16454       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16455         vrf_set = 1;
16456       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16457         vrf_set = 1;
16458       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16459         vrf_set = 1;
16460       else if (unformat (input, "del"))
16461         is_add = 0;
16462       else
16463         break;
16464     }
16465
16466   if (sw_if_index == ~0)
16467     {
16468       errmsg ("Interface required but not specified");
16469       return -99;
16470     }
16471
16472   if (vrf_set == 0)
16473     {
16474       errmsg ("VRF ID required but not specified");
16475       return -99;
16476     }
16477
16478   if (tcp_out_vrf_id == 0
16479       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16480     {
16481       errmsg
16482         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16483       return -99;
16484     }
16485
16486   /* Construct the API message */
16487   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
16488      ip_source_and_port_range_check_interface_add_del);
16489
16490   mp->sw_if_index = ntohl (sw_if_index);
16491   mp->is_add = is_add;
16492   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16493   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16494   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16495   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16496
16497   /* send it... */
16498   S;
16499
16500   /* Wait for a reply... */
16501   W;
16502 }
16503
16504 static int
16505 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16506 {
16507   unformat_input_t *i = vam->input;
16508   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16509   f64 timeout;
16510   u32 local_sa_id = 0;
16511   u32 remote_sa_id = 0;
16512   ip4_address_t src_address;
16513   ip4_address_t dst_address;
16514   u8 is_add = 1;
16515
16516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16517     {
16518       if (unformat (i, "local_sa %d", &local_sa_id))
16519         ;
16520       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16521         ;
16522       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16523         ;
16524       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16525         ;
16526       else if (unformat (i, "del"))
16527         is_add = 0;
16528       else
16529         {
16530           clib_warning ("parse error '%U'", format_unformat_error, i);
16531           return -99;
16532         }
16533     }
16534
16535   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
16536
16537   mp->local_sa_id = ntohl (local_sa_id);
16538   mp->remote_sa_id = ntohl (remote_sa_id);
16539   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16540   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16541   mp->is_add = is_add;
16542
16543   S;
16544   W;
16545   /* NOTREACHED */
16546   return 0;
16547 }
16548
16549 static int
16550 api_punt (vat_main_t * vam)
16551 {
16552   unformat_input_t *i = vam->input;
16553   vl_api_punt_t *mp;
16554   f64 timeout;
16555   u32 ipv = ~0;
16556   u32 protocol = ~0;
16557   u32 port = ~0;
16558   int is_add = 1;
16559
16560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16561     {
16562       if (unformat (i, "ip %d", &ipv))
16563         ;
16564       else if (unformat (i, "protocol %d", &protocol))
16565         ;
16566       else if (unformat (i, "port %d", &port))
16567         ;
16568       else if (unformat (i, "del"))
16569         is_add = 0;
16570       else
16571         {
16572           clib_warning ("parse error '%U'", format_unformat_error, i);
16573           return -99;
16574         }
16575     }
16576
16577   M (PUNT, punt);
16578
16579   mp->is_add = (u8) is_add;
16580   mp->ipv = (u8) ipv;
16581   mp->l4_protocol = (u8) protocol;
16582   mp->l4_port = htons ((u16) port);
16583
16584   S;
16585   W;
16586   /* NOTREACHED */
16587   return 0;
16588 }
16589
16590 static void vl_api_ipsec_gre_tunnel_details_t_handler
16591   (vl_api_ipsec_gre_tunnel_details_t * mp)
16592 {
16593   vat_main_t *vam = &vat_main;
16594
16595   print (vam->ofp, "%11d%15U%15U%14d%14d",
16596          ntohl (mp->sw_if_index),
16597          format_ip4_address, &mp->src_address,
16598          format_ip4_address, &mp->dst_address,
16599          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16600 }
16601
16602 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16603   (vl_api_ipsec_gre_tunnel_details_t * mp)
16604 {
16605   vat_main_t *vam = &vat_main;
16606   vat_json_node_t *node = NULL;
16607   struct in_addr ip4;
16608
16609   if (VAT_JSON_ARRAY != vam->json_tree.type)
16610     {
16611       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16612       vat_json_init_array (&vam->json_tree);
16613     }
16614   node = vat_json_array_add (&vam->json_tree);
16615
16616   vat_json_init_object (node);
16617   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16618   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16619   vat_json_object_add_ip4 (node, "src_address", ip4);
16620   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16621   vat_json_object_add_ip4 (node, "dst_address", ip4);
16622   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16623   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16624 }
16625
16626 static int
16627 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16628 {
16629   unformat_input_t *i = vam->input;
16630   vl_api_ipsec_gre_tunnel_dump_t *mp;
16631   f64 timeout;
16632   u32 sw_if_index;
16633   u8 sw_if_index_set = 0;
16634
16635   /* Parse args required to build the message */
16636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16637     {
16638       if (unformat (i, "sw_if_index %d", &sw_if_index))
16639         sw_if_index_set = 1;
16640       else
16641         break;
16642     }
16643
16644   if (sw_if_index_set == 0)
16645     {
16646       sw_if_index = ~0;
16647     }
16648
16649   if (!vam->json_output)
16650     {
16651       print (vam->ofp, "%11s%15s%15s%14s%14s",
16652              "sw_if_index", "src_address", "dst_address",
16653              "local_sa_id", "remote_sa_id");
16654     }
16655
16656   /* Get list of gre-tunnel interfaces */
16657   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16658
16659   mp->sw_if_index = htonl (sw_if_index);
16660
16661   S;
16662
16663   /* Use a control ping for synchronization */
16664   {
16665     vl_api_control_ping_t *mp;
16666     M (CONTROL_PING, control_ping);
16667     S;
16668   }
16669   W;
16670 }
16671
16672 static int
16673 api_delete_subif (vat_main_t * vam)
16674 {
16675   unformat_input_t *i = vam->input;
16676   vl_api_delete_subif_t *mp;
16677   f64 timeout;
16678   u32 sw_if_index = ~0;
16679
16680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16681     {
16682       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16683         ;
16684       if (unformat (i, "sw_if_index %d", &sw_if_index))
16685         ;
16686       else
16687         break;
16688     }
16689
16690   if (sw_if_index == ~0)
16691     {
16692       errmsg ("missing sw_if_index");
16693       return -99;
16694     }
16695
16696   /* Construct the API message */
16697   M (DELETE_SUBIF, delete_subif);
16698   mp->sw_if_index = ntohl (sw_if_index);
16699
16700   S;
16701   W;
16702 }
16703
16704 #define foreach_pbb_vtr_op      \
16705 _("disable",  L2_VTR_DISABLED)  \
16706 _("pop",  L2_VTR_POP_2)         \
16707 _("push",  L2_VTR_PUSH_2)
16708
16709 static int
16710 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16711 {
16712   unformat_input_t *i = vam->input;
16713   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16714   f64 timeout;
16715   u32 sw_if_index = ~0, vtr_op = ~0;
16716   u16 outer_tag = ~0;
16717   u8 dmac[6], smac[6];
16718   u8 dmac_set = 0, smac_set = 0;
16719   u16 vlanid = 0;
16720   u32 sid = ~0;
16721   u32 tmp;
16722
16723   /* Shut up coverity */
16724   memset (dmac, 0, sizeof (dmac));
16725   memset (smac, 0, sizeof (smac));
16726
16727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16728     {
16729       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16730         ;
16731       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16732         ;
16733       else if (unformat (i, "vtr_op %d", &vtr_op))
16734         ;
16735 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16736       foreach_pbb_vtr_op
16737 #undef _
16738         else if (unformat (i, "translate_pbb_stag"))
16739         {
16740           if (unformat (i, "%d", &tmp))
16741             {
16742               vtr_op = L2_VTR_TRANSLATE_2_1;
16743               outer_tag = tmp;
16744             }
16745           else
16746             {
16747               errmsg
16748                 ("translate_pbb_stag operation requires outer tag definition");
16749               return -99;
16750             }
16751         }
16752       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16753         dmac_set++;
16754       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16755         smac_set++;
16756       else if (unformat (i, "sid %d", &sid))
16757         ;
16758       else if (unformat (i, "vlanid %d", &tmp))
16759         vlanid = tmp;
16760       else
16761         {
16762           clib_warning ("parse error '%U'", format_unformat_error, i);
16763           return -99;
16764         }
16765     }
16766
16767   if ((sw_if_index == ~0) || (vtr_op == ~0))
16768     {
16769       errmsg ("missing sw_if_index or vtr operation");
16770       return -99;
16771     }
16772   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16773       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16774     {
16775       errmsg
16776         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
16777       return -99;
16778     }
16779
16780   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16781   mp->sw_if_index = ntohl (sw_if_index);
16782   mp->vtr_op = ntohl (vtr_op);
16783   mp->outer_tag = ntohs (outer_tag);
16784   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16785   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16786   mp->b_vlanid = ntohs (vlanid);
16787   mp->i_sid = ntohl (sid);
16788
16789   S;
16790   W;
16791   /* NOTREACHED */
16792   return 0;
16793 }
16794
16795 static int
16796 api_flow_classify_set_interface (vat_main_t * vam)
16797 {
16798   unformat_input_t *i = vam->input;
16799   vl_api_flow_classify_set_interface_t *mp;
16800   f64 timeout;
16801   u32 sw_if_index;
16802   int sw_if_index_set;
16803   u32 ip4_table_index = ~0;
16804   u32 ip6_table_index = ~0;
16805   u8 is_add = 1;
16806
16807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16808     {
16809       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16810         sw_if_index_set = 1;
16811       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16812         sw_if_index_set = 1;
16813       else if (unformat (i, "del"))
16814         is_add = 0;
16815       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16816         ;
16817       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16818         ;
16819       else
16820         {
16821           clib_warning ("parse error '%U'", format_unformat_error, i);
16822           return -99;
16823         }
16824     }
16825
16826   if (sw_if_index_set == 0)
16827     {
16828       errmsg ("missing interface name or sw_if_index");
16829       return -99;
16830     }
16831
16832   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16833
16834   mp->sw_if_index = ntohl (sw_if_index);
16835   mp->ip4_table_index = ntohl (ip4_table_index);
16836   mp->ip6_table_index = ntohl (ip6_table_index);
16837   mp->is_add = is_add;
16838
16839   S;
16840   W;
16841   /* NOTREACHED */
16842   return 0;
16843 }
16844
16845 static int
16846 api_flow_classify_dump (vat_main_t * vam)
16847 {
16848   unformat_input_t *i = vam->input;
16849   vl_api_flow_classify_dump_t *mp;
16850   f64 timeout = ~0;
16851   u8 type = FLOW_CLASSIFY_N_TABLES;
16852
16853   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16854     ;
16855   else
16856     {
16857       errmsg ("classify table type must be specified");
16858       return -99;
16859     }
16860
16861   if (!vam->json_output)
16862     {
16863       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16864     }
16865
16866   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16867   mp->type = type;
16868   /* send it... */
16869   S;
16870
16871   /* Use a control ping for synchronization */
16872   {
16873     vl_api_control_ping_t *mp;
16874     M (CONTROL_PING, control_ping);
16875     S;
16876   }
16877   /* Wait for a reply... */
16878   W;
16879
16880   /* NOTREACHED */
16881   return 0;
16882 }
16883
16884 static int
16885 api_feature_enable_disable (vat_main_t * vam)
16886 {
16887   unformat_input_t *i = vam->input;
16888   vl_api_feature_enable_disable_t *mp;
16889   f64 timeout;
16890   u8 *arc_name = 0;
16891   u8 *feature_name = 0;
16892   u32 sw_if_index = ~0;
16893   u8 enable = 1;
16894
16895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16896     {
16897       if (unformat (i, "arc_name %s", &arc_name))
16898         ;
16899       else if (unformat (i, "feature_name %s", &feature_name))
16900         ;
16901       else
16902         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16903         ;
16904       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16905         ;
16906       else if (unformat (i, "disable"))
16907         enable = 0;
16908       else
16909         break;
16910     }
16911
16912   if (arc_name == 0)
16913     {
16914       errmsg ("missing arc name");
16915       return -99;
16916     }
16917   if (vec_len (arc_name) > 63)
16918     {
16919       errmsg ("arc name too long");
16920     }
16921
16922   if (feature_name == 0)
16923     {
16924       errmsg ("missing feature name");
16925       return -99;
16926     }
16927   if (vec_len (feature_name) > 63)
16928     {
16929       errmsg ("feature name too long");
16930     }
16931
16932   if (sw_if_index == ~0)
16933     {
16934       errmsg ("missing interface name or sw_if_index");
16935       return -99;
16936     }
16937
16938   /* Construct the API message */
16939   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16940   mp->sw_if_index = ntohl (sw_if_index);
16941   mp->enable = enable;
16942   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16943   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16944   vec_free (arc_name);
16945   vec_free (feature_name);
16946
16947   S;
16948   W;
16949 }
16950
16951 static int
16952 api_sw_interface_tag_add_del (vat_main_t * vam)
16953 {
16954   unformat_input_t *i = vam->input;
16955   vl_api_sw_interface_tag_add_del_t *mp;
16956   f64 timeout;
16957   u32 sw_if_index = ~0;
16958   u8 *tag = 0;
16959   u8 enable = 1;
16960
16961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16962     {
16963       if (unformat (i, "tag %s", &tag))
16964         ;
16965       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16966         ;
16967       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16968         ;
16969       else if (unformat (i, "del"))
16970         enable = 0;
16971       else
16972         break;
16973     }
16974
16975   if (sw_if_index == ~0)
16976     {
16977       errmsg ("missing interface name or sw_if_index");
16978       return -99;
16979     }
16980
16981   if (enable && (tag == 0))
16982     {
16983       errmsg ("no tag specified");
16984       return -99;
16985     }
16986
16987   /* Construct the API message */
16988   M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
16989   mp->sw_if_index = ntohl (sw_if_index);
16990   mp->is_add = enable;
16991   if (enable)
16992     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
16993   vec_free (tag);
16994
16995   S;
16996   W;
16997 }
16998
16999 static void vl_api_l2_xconnect_details_t_handler
17000   (vl_api_l2_xconnect_details_t * mp)
17001 {
17002   vat_main_t *vam = &vat_main;
17003
17004   print (vam->ofp, "%15d%15d",
17005          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17006 }
17007
17008 static void vl_api_l2_xconnect_details_t_handler_json
17009   (vl_api_l2_xconnect_details_t * mp)
17010 {
17011   vat_main_t *vam = &vat_main;
17012   vat_json_node_t *node = NULL;
17013
17014   if (VAT_JSON_ARRAY != vam->json_tree.type)
17015     {
17016       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17017       vat_json_init_array (&vam->json_tree);
17018     }
17019   node = vat_json_array_add (&vam->json_tree);
17020
17021   vat_json_init_object (node);
17022   vat_json_object_add_uint (node, "rx_sw_if_index",
17023                             ntohl (mp->rx_sw_if_index));
17024   vat_json_object_add_uint (node, "tx_sw_if_index",
17025                             ntohl (mp->tx_sw_if_index));
17026 }
17027
17028 static int
17029 api_l2_xconnect_dump (vat_main_t * vam)
17030 {
17031   vl_api_l2_xconnect_dump_t *mp;
17032   f64 timeout;
17033
17034   if (!vam->json_output)
17035     {
17036       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17037     }
17038
17039   M (L2_XCONNECT_DUMP, l2_xconnect_dump);
17040
17041   S;
17042
17043   /* Use a control ping for synchronization */
17044   {
17045     vl_api_control_ping_t *mp;
17046     M (CONTROL_PING, control_ping);
17047     S;
17048   }
17049   W;
17050 }
17051
17052 static int
17053 api_sw_interface_set_mtu (vat_main_t * vam)
17054 {
17055   unformat_input_t *i = vam->input;
17056   vl_api_sw_interface_set_mtu_t *mp;
17057   f64 timeout;
17058   u32 sw_if_index = ~0;
17059   u32 mtu = 0;
17060
17061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17062     {
17063       if (unformat (i, "mtu %d", &mtu))
17064         ;
17065       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17066         ;
17067       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17068         ;
17069       else
17070         break;
17071     }
17072
17073   if (sw_if_index == ~0)
17074     {
17075       errmsg ("missing interface name or sw_if_index");
17076       return -99;
17077     }
17078
17079   if (mtu == 0)
17080     {
17081       errmsg ("no mtu specified");
17082       return -99;
17083     }
17084
17085   /* Construct the API message */
17086   M (SW_INTERFACE_SET_MTU, sw_interface_set_mtu);
17087   mp->sw_if_index = ntohl (sw_if_index);
17088   mp->mtu = ntohs ((u16) mtu);
17089
17090   S;
17091   W;
17092 }
17093
17094
17095 static int
17096 q_or_quit (vat_main_t * vam)
17097 {
17098   longjmp (vam->jump_buf, 1);
17099   return 0;                     /* not so much */
17100 }
17101
17102 static int
17103 q (vat_main_t * vam)
17104 {
17105   return q_or_quit (vam);
17106 }
17107
17108 static int
17109 quit (vat_main_t * vam)
17110 {
17111   return q_or_quit (vam);
17112 }
17113
17114 static int
17115 comment (vat_main_t * vam)
17116 {
17117   return 0;
17118 }
17119
17120 static int
17121 cmd_cmp (void *a1, void *a2)
17122 {
17123   u8 **c1 = a1;
17124   u8 **c2 = a2;
17125
17126   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17127 }
17128
17129 static int
17130 help (vat_main_t * vam)
17131 {
17132   u8 **cmds = 0;
17133   u8 *name = 0;
17134   hash_pair_t *p;
17135   unformat_input_t *i = vam->input;
17136   int j;
17137
17138   if (unformat (i, "%s", &name))
17139     {
17140       uword *hs;
17141
17142       vec_add1 (name, 0);
17143
17144       hs = hash_get_mem (vam->help_by_name, name);
17145       if (hs)
17146         print (vam->ofp, "usage: %s %s", name, hs[0]);
17147       else
17148         print (vam->ofp, "No such msg / command '%s'", name);
17149       vec_free (name);
17150       return 0;
17151     }
17152
17153   print (vam->ofp, "Help is available for the following:");
17154
17155     /* *INDENT-OFF* */
17156     hash_foreach_pair (p, vam->function_by_name,
17157     ({
17158       vec_add1 (cmds, (u8 *)(p->key));
17159     }));
17160     /* *INDENT-ON* */
17161
17162   vec_sort_with_function (cmds, cmd_cmp);
17163
17164   for (j = 0; j < vec_len (cmds); j++)
17165     print (vam->ofp, "%s", cmds[j]);
17166
17167   vec_free (cmds);
17168   return 0;
17169 }
17170
17171 static int
17172 set (vat_main_t * vam)
17173 {
17174   u8 *name = 0, *value = 0;
17175   unformat_input_t *i = vam->input;
17176
17177   if (unformat (i, "%s", &name))
17178     {
17179       /* The input buffer is a vector, not a string. */
17180       value = vec_dup (i->buffer);
17181       vec_delete (value, i->index, 0);
17182       /* Almost certainly has a trailing newline */
17183       if (value[vec_len (value) - 1] == '\n')
17184         value[vec_len (value) - 1] = 0;
17185       /* Make sure it's a proper string, one way or the other */
17186       vec_add1 (value, 0);
17187       (void) clib_macro_set_value (&vam->macro_main,
17188                                    (char *) name, (char *) value);
17189     }
17190   else
17191     errmsg ("usage: set <name> <value>");
17192
17193   vec_free (name);
17194   vec_free (value);
17195   return 0;
17196 }
17197
17198 static int
17199 unset (vat_main_t * vam)
17200 {
17201   u8 *name = 0;
17202
17203   if (unformat (vam->input, "%s", &name))
17204     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17205       errmsg ("unset: %s wasn't set", name);
17206   vec_free (name);
17207   return 0;
17208 }
17209
17210 typedef struct
17211 {
17212   u8 *name;
17213   u8 *value;
17214 } macro_sort_t;
17215
17216
17217 static int
17218 macro_sort_cmp (void *a1, void *a2)
17219 {
17220   macro_sort_t *s1 = a1;
17221   macro_sort_t *s2 = a2;
17222
17223   return strcmp ((char *) (s1->name), (char *) (s2->name));
17224 }
17225
17226 static int
17227 dump_macro_table (vat_main_t * vam)
17228 {
17229   macro_sort_t *sort_me = 0, *sm;
17230   int i;
17231   hash_pair_t *p;
17232
17233     /* *INDENT-OFF* */
17234     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17235     ({
17236       vec_add2 (sort_me, sm, 1);
17237       sm->name = (u8 *)(p->key);
17238       sm->value = (u8 *) (p->value[0]);
17239     }));
17240     /* *INDENT-ON* */
17241
17242   vec_sort_with_function (sort_me, macro_sort_cmp);
17243
17244   if (vec_len (sort_me))
17245     print (vam->ofp, "%-15s%s", "Name", "Value");
17246   else
17247     print (vam->ofp, "The macro table is empty...");
17248
17249   for (i = 0; i < vec_len (sort_me); i++)
17250     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17251   return 0;
17252 }
17253
17254 static int
17255 dump_node_table (vat_main_t * vam)
17256 {
17257   int i, j;
17258   vlib_node_t *node, *next_node;
17259
17260   if (vec_len (vam->graph_nodes) == 0)
17261     {
17262       print (vam->ofp, "Node table empty, issue get_node_graph...");
17263       return 0;
17264     }
17265
17266   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17267     {
17268       node = vam->graph_nodes[i];
17269       print (vam->ofp, "[%d] %s", i, node->name);
17270       for (j = 0; j < vec_len (node->next_nodes); j++)
17271         {
17272           if (node->next_nodes[j] != ~0)
17273             {
17274               next_node = vam->graph_nodes[node->next_nodes[j]];
17275               print (vam->ofp, "  [%d] %s", j, next_node->name);
17276             }
17277         }
17278     }
17279   return 0;
17280 }
17281
17282 static int
17283 value_sort_cmp (void *a1, void *a2)
17284 {
17285   name_sort_t *n1 = a1;
17286   name_sort_t *n2 = a2;
17287
17288   if (n1->value < n2->value)
17289     return -1;
17290   if (n1->value > n2->value)
17291     return 1;
17292   return 0;
17293 }
17294
17295
17296 static int
17297 dump_msg_api_table (vat_main_t * vam)
17298 {
17299   api_main_t *am = &api_main;
17300   name_sort_t *nses = 0, *ns;
17301   hash_pair_t *hp;
17302   int i;
17303
17304   /* *INDENT-OFF* */
17305   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17306   ({
17307     vec_add2 (nses, ns, 1);
17308     ns->name = (u8 *)(hp->key);
17309     ns->value = (u32) hp->value[0];
17310   }));
17311   /* *INDENT-ON* */
17312
17313   vec_sort_with_function (nses, value_sort_cmp);
17314
17315   for (i = 0; i < vec_len (nses); i++)
17316     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17317   vec_free (nses);
17318   return 0;
17319 }
17320
17321 static int
17322 get_msg_id (vat_main_t * vam)
17323 {
17324   u8 *name_and_crc;
17325   u32 message_index;
17326
17327   if (unformat (vam->input, "%s", &name_and_crc))
17328     {
17329       message_index = vl_api_get_msg_index (name_and_crc);
17330       if (message_index == ~0)
17331         {
17332           print (vam->ofp, " '%s' not found", name_and_crc);
17333           return 0;
17334         }
17335       print (vam->ofp, " '%s' has message index %d",
17336              name_and_crc, message_index);
17337       return 0;
17338     }
17339   errmsg ("name_and_crc required...");
17340   return 0;
17341 }
17342
17343 static int
17344 search_node_table (vat_main_t * vam)
17345 {
17346   unformat_input_t *line_input = vam->input;
17347   u8 *node_to_find;
17348   int j;
17349   vlib_node_t *node, *next_node;
17350   uword *p;
17351
17352   if (vam->graph_node_index_by_name == 0)
17353     {
17354       print (vam->ofp, "Node table empty, issue get_node_graph...");
17355       return 0;
17356     }
17357
17358   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17359     {
17360       if (unformat (line_input, "%s", &node_to_find))
17361         {
17362           vec_add1 (node_to_find, 0);
17363           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17364           if (p == 0)
17365             {
17366               print (vam->ofp, "%s not found...", node_to_find);
17367               goto out;
17368             }
17369           node = vam->graph_nodes[p[0]];
17370           print (vam->ofp, "[%d] %s", p[0], node->name);
17371           for (j = 0; j < vec_len (node->next_nodes); j++)
17372             {
17373               if (node->next_nodes[j] != ~0)
17374                 {
17375                   next_node = vam->graph_nodes[node->next_nodes[j]];
17376                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17377                 }
17378             }
17379         }
17380
17381       else
17382         {
17383           clib_warning ("parse error '%U'", format_unformat_error,
17384                         line_input);
17385           return -99;
17386         }
17387
17388     out:
17389       vec_free (node_to_find);
17390
17391     }
17392
17393   return 0;
17394 }
17395
17396
17397 static int
17398 script (vat_main_t * vam)
17399 {
17400 #if (VPP_API_TEST_BUILTIN==0)
17401   u8 *s = 0;
17402   char *save_current_file;
17403   unformat_input_t save_input;
17404   jmp_buf save_jump_buf;
17405   u32 save_line_number;
17406
17407   FILE *new_fp, *save_ifp;
17408
17409   if (unformat (vam->input, "%s", &s))
17410     {
17411       new_fp = fopen ((char *) s, "r");
17412       if (new_fp == 0)
17413         {
17414           errmsg ("Couldn't open script file %s", s);
17415           vec_free (s);
17416           return -99;
17417         }
17418     }
17419   else
17420     {
17421       errmsg ("Missing script name");
17422       return -99;
17423     }
17424
17425   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17426   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17427   save_ifp = vam->ifp;
17428   save_line_number = vam->input_line_number;
17429   save_current_file = (char *) vam->current_file;
17430
17431   vam->input_line_number = 0;
17432   vam->ifp = new_fp;
17433   vam->current_file = s;
17434   do_one_file (vam);
17435
17436   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17437   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17438   vam->ifp = save_ifp;
17439   vam->input_line_number = save_line_number;
17440   vam->current_file = (u8 *) save_current_file;
17441   vec_free (s);
17442
17443   return 0;
17444 #else
17445   clib_warning ("use the exec command...");
17446   return -99;
17447 #endif
17448 }
17449
17450 static int
17451 echo (vat_main_t * vam)
17452 {
17453   print (vam->ofp, "%v", vam->input->buffer);
17454   return 0;
17455 }
17456
17457 /* List of API message constructors, CLI names map to api_xxx */
17458 #define foreach_vpe_api_msg                                             \
17459 _(create_loopback,"[mac <mac-addr>]")                                   \
17460 _(sw_interface_dump,"")                                                 \
17461 _(sw_interface_set_flags,                                               \
17462   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17463 _(sw_interface_add_del_address,                                         \
17464   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17465 _(sw_interface_set_table,                                               \
17466   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17467 _(sw_interface_set_mpls_enable,                                         \
17468   "<intfc> | sw_if_index [disable | dis]")                              \
17469 _(sw_interface_set_vpath,                                               \
17470   "<intfc> | sw_if_index <id> enable | disable")                        \
17471 _(sw_interface_set_vxlan_bypass,                                        \
17472   "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable")            \
17473 _(sw_interface_set_l2_xconnect,                                         \
17474   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17475   "enable | disable")                                                   \
17476 _(sw_interface_set_l2_bridge,                                           \
17477   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
17478   "[shg <split-horizon-group>] [bvi]\n"                                 \
17479   "enable | disable")                                                   \
17480 _(bridge_domain_add_del,                                                \
17481   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
17482 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
17483 _(l2fib_add_del,                                                        \
17484   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17485 _(l2_flags,                                                             \
17486   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
17487 _(bridge_flags,                                                         \
17488   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17489 _(tap_connect,                                                          \
17490   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17491 _(tap_modify,                                                           \
17492   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17493 _(tap_delete,                                                           \
17494   "<vpp-if-name> | sw_if_index <id>")                                   \
17495 _(sw_interface_tap_dump, "")                                            \
17496 _(ip_add_del_route,                                                     \
17497   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17498   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17499   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17500   "[multipath] [count <n>]")                                            \
17501 _(mpls_route_add_del,                                                   \
17502   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17503   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17504   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17505   "[multipath] [count <n>]")                                            \
17506 _(mpls_ip_bind_unbind,                                                  \
17507   "<label> <addr/len>")                                                 \
17508 _(mpls_tunnel_add_del,                                                  \
17509   " via <addr> [table-id <n>]\n"                                        \
17510   "sw_if_index <id>] [l2]  [del]")                                      \
17511 _(proxy_arp_add_del,                                                    \
17512   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17513 _(proxy_arp_intfc_enable_disable,                                       \
17514   "<intfc> | sw_if_index <id> enable | disable")                        \
17515 _(sw_interface_set_unnumbered,                                          \
17516   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17517 _(ip_neighbor_add_del,                                                  \
17518   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17519   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17520 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17521 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17522 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17523   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17524   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17525   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17526 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17527 _(reset_fib, "vrf <n> [ipv6]")                                          \
17528 _(dhcp_proxy_config,                                                    \
17529   "svr <v46-address> src <v46-address>\n"                               \
17530    "insert-cid <n> [del]")                                              \
17531 _(dhcp_proxy_config_2,                                                  \
17532   "svr <v46-address> src <v46-address>\n"                               \
17533    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
17534 _(dhcp_proxy_set_vss,                                                   \
17535   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17536 _(dhcp_client_config,                                                   \
17537   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17538 _(set_ip_flow_hash,                                                     \
17539   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17540 _(sw_interface_ip6_enable_disable,                                      \
17541   "<intfc> | sw_if_index <id> enable | disable")                        \
17542 _(sw_interface_ip6_set_link_local_address,                              \
17543   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17544 _(sw_interface_ip6nd_ra_prefix,                                         \
17545   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17546   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17547   "[nolink] [isno]")                                                    \
17548 _(sw_interface_ip6nd_ra_config,                                         \
17549   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17550   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17551   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17552 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17553 _(l2_patch_add_del,                                                     \
17554   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17555   "enable | disable")                                                   \
17556 _(sr_tunnel_add_del,                                                    \
17557   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
17558   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
17559   "[policy <policy_name>]")                                             \
17560 _(sr_policy_add_del,                                                    \
17561   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
17562 _(sr_multicast_map_add_del,                                             \
17563   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
17564 _(classify_add_del_table,                                               \
17565   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17566   " [del] [del-chain] mask <mask-value>\n"                              \
17567   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17568   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17569 _(classify_add_del_session,                                             \
17570   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17571   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17572   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17573   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17574 _(classify_set_interface_ip_table,                                      \
17575   "<intfc> | sw_if_index <nn> table <nn>")                              \
17576 _(classify_set_interface_l2_tables,                                     \
17577   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17578   "  [other-table <nn>]")                                               \
17579 _(get_node_index, "node <node-name")                                    \
17580 _(add_node_next, "node <node-name> next <next-node-name>")              \
17581 _(l2tpv3_create_tunnel,                                                 \
17582   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17583   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
17584   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17585 _(l2tpv3_set_tunnel_cookies,                                            \
17586   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17587   "[new_remote_cookie <nn>]\n")                                         \
17588 _(l2tpv3_interface_enable_disable,                                      \
17589   "<intfc> | sw_if_index <nn> enable | disable")                        \
17590 _(l2tpv3_set_lookup_key,                                                \
17591   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
17592 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
17593 _(vxlan_add_del_tunnel,                                                 \
17594   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
17595   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
17596   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
17597 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
17598 _(gre_add_del_tunnel,                                                   \
17599   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
17600 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
17601 _(l2_fib_clear_table, "")                                               \
17602 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
17603 _(l2_interface_vlan_tag_rewrite,                                        \
17604   "<intfc> | sw_if_index <nn> \n"                                       \
17605   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
17606   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
17607 _(create_vhost_user_if,                                                 \
17608         "socket <filename> [server] [renumber <dev_instance>] "         \
17609         "[mac <mac_address>]")                                          \
17610 _(modify_vhost_user_if,                                                 \
17611         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
17612         "[server] [renumber <dev_instance>]")                           \
17613 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
17614 _(sw_interface_vhost_user_dump, "")                                     \
17615 _(show_version, "")                                                     \
17616 _(vxlan_gpe_add_del_tunnel,                                             \
17617   "local <addr> remote <addr> vni <nn>\n"                               \
17618     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
17619   "[next-ethernet] [next-nsh]\n")                                       \
17620 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
17621 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
17622 _(interface_name_renumber,                                              \
17623   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
17624 _(input_acl_set_interface,                                              \
17625   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17626   "  [l2-table <nn>] [del]")                                            \
17627 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
17628 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
17629 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
17630 _(ip_dump, "ipv4 | ipv6")                                               \
17631 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
17632 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
17633   "  spid_id <n> ")                                                     \
17634 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
17635   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
17636   "  integ_alg <alg> integ_key <hex>")                                  \
17637 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
17638   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
17639   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
17640   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
17641 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
17642 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
17643 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
17644   "(auth_data 0x<data> | auth_data <data>)")                            \
17645 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
17646   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
17647 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
17648   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
17649   "(local|remote)")                                                     \
17650 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
17651 _(delete_loopback,"sw_if_index <nn>")                                   \
17652 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
17653 _(map_add_domain,                                                       \
17654   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
17655   "ip6-src <ip6addr> "                                                  \
17656   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
17657 _(map_del_domain, "index <n>")                                          \
17658 _(map_add_del_rule,                                                     \
17659   "index <n> psid <n> dst <ip6addr> [del]")                             \
17660 _(map_domain_dump, "")                                                  \
17661 _(map_rule_dump, "index <map-domain>")                                  \
17662 _(want_interface_events,  "enable|disable")                             \
17663 _(want_stats,"enable|disable")                                          \
17664 _(get_first_msg_id, "client <name>")                                    \
17665 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
17666 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
17667   "fib-id <nn> [ip4][ip6][default]")                                    \
17668 _(get_node_graph, " ")                                                  \
17669 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
17670 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
17671 _(ioam_disable, "")                                                     \
17672 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
17673                             " sw_if_index <sw_if_index> p <priority> "  \
17674                             "w <weight>] [del]")                        \
17675 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
17676                         "iface <intf> | sw_if_index <sw_if_index> "     \
17677                         "p <priority> w <weight> [del]")                \
17678 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
17679                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
17680                          "locator-set <locator_name> [del]"             \
17681                          "[key-id sha1|sha256 secret-key <secret-key>]") \
17682 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
17683   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
17684 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
17685 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
17686 _(lisp_gpe_enable_disable, "enable|disable")                            \
17687 _(lisp_enable_disable, "enable|disable")                                \
17688 _(lisp_map_register_enable_disable, "enable|disable")                   \
17689 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
17690 _(lisp_gpe_add_del_iface, "up|down")                                    \
17691 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
17692                                "[seid <seid>] "                         \
17693                                "rloc <locator> p <prio> "               \
17694                                "w <weight> [rloc <loc> ... ] "          \
17695                                "action <action> [del-all]")             \
17696 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
17697                           "<local-eid>")                                \
17698 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
17699 _(lisp_map_request_mode, "src-dst|dst-only")                            \
17700 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
17701 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
17702 _(lisp_locator_set_dump, "[local | remote]")                            \
17703 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
17704 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
17705                        "[local] | [remote]")                            \
17706 _(lisp_eid_table_vni_dump, "")                                          \
17707 _(lisp_eid_table_map_dump, "l2|l3")                                     \
17708 _(lisp_gpe_tunnel_dump, "")                                             \
17709 _(lisp_map_resolver_dump, "")                                           \
17710 _(lisp_map_server_dump, "")                                             \
17711 _(lisp_adjacencies_get, "vni <vni>")                                    \
17712 _(show_lisp_rloc_probe_state, "")                                       \
17713 _(show_lisp_map_register_state, "")                                     \
17714 _(show_lisp_status, "")                                                 \
17715 _(lisp_get_map_request_itr_rlocs, "")                                   \
17716 _(show_lisp_pitr, "")                                                   \
17717 _(show_lisp_map_request_mode, "")                                       \
17718 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
17719 _(af_packet_delete, "name <host interface name>")                       \
17720 _(policer_add_del, "name <policer name> <params> [del]")                \
17721 _(policer_dump, "[name <policer name>]")                                \
17722 _(policer_classify_set_interface,                                       \
17723   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17724   "  [l2-table <nn>] [del]")                                            \
17725 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
17726 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
17727     "[master|slave]")                                                   \
17728 _(netmap_delete, "name <interface name>")                               \
17729 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
17730 _(mpls_fib_dump, "")                                                    \
17731 _(classify_table_ids, "")                                               \
17732 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
17733 _(classify_table_info, "table_id <nn>")                                 \
17734 _(classify_session_dump, "table_id <nn>")                               \
17735 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
17736     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
17737     "[template_interval <nn>] [udp_checksum]")                          \
17738 _(ipfix_exporter_dump, "")                                              \
17739 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17740 _(ipfix_classify_stream_dump, "")                                       \
17741 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
17742 _(ipfix_classify_table_dump, "")                                        \
17743 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
17744 _(sw_interface_span_dump, "")                                           \
17745 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
17746 _(pg_create_interface, "if_id <nn>")                                    \
17747 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
17748 _(pg_enable_disable, "[stream <id>] disable")                           \
17749 _(ip_source_and_port_range_check_add_del,                               \
17750   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
17751 _(ip_source_and_port_range_check_interface_add_del,                     \
17752   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
17753   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
17754 _(ipsec_gre_add_del_tunnel,                                             \
17755   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
17756 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
17757 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
17758 _(l2_interface_pbb_tag_rewrite,                                         \
17759   "<intfc> | sw_if_index <nn> \n"                                       \
17760   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
17761   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
17762 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
17763 _(flow_classify_set_interface,                                          \
17764   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17765 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17766 _(ip_fib_dump, "")                                                      \
17767 _(ip6_fib_dump, "")                                                     \
17768 _(feature_enable_disable, "arc_name <arc_name> "                        \
17769   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
17770 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
17771 "[disable]")                                                            \
17772 _(l2_xconnect_dump, "")                                                 \
17773 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
17774 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
17775 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
17776
17777 #if DPDK > 0
17778 #define foreach_vpe_dpdk_api_msg                                        \
17779 _(sw_interface_set_dpdk_hqos_pipe,                                      \
17780   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
17781   "profile <profile-id>\n")                                             \
17782 _(sw_interface_set_dpdk_hqos_subport,                                   \
17783   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
17784   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
17785 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
17786   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")
17787 #endif
17788
17789 /* List of command functions, CLI names map directly to functions */
17790 #define foreach_cli_function                                    \
17791 _(comment, "usage: comment <ignore-rest-of-line>")              \
17792 _(dump_interface_table, "usage: dump_interface_table")          \
17793 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17794 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17795 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17796 _(dump_stats_table, "usage: dump_stats_table")                  \
17797 _(dump_macro_table, "usage: dump_macro_table ")                 \
17798 _(dump_node_table, "usage: dump_node_table")                    \
17799 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17800 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17801 _(echo, "usage: echo <message>")                                \
17802 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17803 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17804 _(help, "usage: help")                                          \
17805 _(q, "usage: quit")                                             \
17806 _(quit, "usage: quit")                                          \
17807 _(search_node_table, "usage: search_node_table <name>...")      \
17808 _(set, "usage: set <variable-name> <value>")                    \
17809 _(script, "usage: script <file-name>")                          \
17810 _(unset, "usage: unset <variable-name>")
17811
17812 #define _(N,n)                                  \
17813     static void vl_api_##n##_t_handler_uni      \
17814     (vl_api_##n##_t * mp)                       \
17815     {                                           \
17816         vat_main_t * vam = &vat_main;           \
17817         if (vam->json_output) {                 \
17818             vl_api_##n##_t_handler_json(mp);    \
17819         } else {                                \
17820             vl_api_##n##_t_handler(mp);         \
17821         }                                       \
17822     }
17823 foreach_vpe_api_reply_msg;
17824 #undef _
17825
17826 #if DPDK > 0
17827 #define _(N,n)                                  \
17828     static void vl_api_##n##_t_handler_uni      \
17829     (vl_api_##n##_t * mp)                       \
17830     {                                           \
17831         vat_main_t * vam = &vat_main;           \
17832         if (vam->json_output) {                 \
17833             vl_api_##n##_t_handler_json(mp);    \
17834         } else {                                \
17835             vl_api_##n##_t_handler(mp);         \
17836         }                                       \
17837     }
17838 foreach_vpe_dpdk_api_reply_msg;
17839 #undef _
17840 #endif
17841
17842 void
17843 vat_api_hookup (vat_main_t * vam)
17844 {
17845 #define _(N,n)                                                  \
17846     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17847                            vl_api_##n##_t_handler_uni,          \
17848                            vl_noop_handler,                     \
17849                            vl_api_##n##_t_endian,               \
17850                            vl_api_##n##_t_print,                \
17851                            sizeof(vl_api_##n##_t), 1);
17852   foreach_vpe_api_reply_msg;
17853 #undef _
17854
17855 #if DPDK > 0
17856 #define _(N,n)                                                  \
17857     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17858                            vl_api_##n##_t_handler_uni,          \
17859                            vl_noop_handler,                     \
17860                            vl_api_##n##_t_endian,               \
17861                            vl_api_##n##_t_print,                \
17862                            sizeof(vl_api_##n##_t), 1);
17863   foreach_vpe_dpdk_api_reply_msg;
17864 #undef _
17865 #endif
17866
17867 #if (VPP_API_TEST_BUILTIN==0)
17868   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17869 #endif
17870
17871   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17872
17873   vam->function_by_name = hash_create_string (0, sizeof (uword));
17874
17875   vam->help_by_name = hash_create_string (0, sizeof (uword));
17876
17877   /* API messages we can send */
17878 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17879   foreach_vpe_api_msg;
17880 #undef _
17881 #if DPDK >0
17882 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17883   foreach_vpe_dpdk_api_msg;
17884 #undef _
17885 #endif
17886
17887   /* Help strings */
17888 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17889   foreach_vpe_api_msg;
17890 #undef _
17891 #if DPDK >0
17892 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17893   foreach_vpe_dpdk_api_msg;
17894 #undef _
17895 #endif
17896
17897   /* CLI functions */
17898 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17899   foreach_cli_function;
17900 #undef _
17901
17902   /* Help strings */
17903 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17904   foreach_cli_function;
17905 #undef _
17906 }
17907
17908 /*
17909  * fd.io coding-style-patch-verification: ON
17910  *
17911  * Local Variables:
17912  * eval: (c-set-style "gnu")
17913  * End:
17914  */