dpdk: remove rte_mbuf modifications at many places in the code
[vpp.git] / vpp-api-test / 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 #if DPDK > 0
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #else
44 #include <inttypes.h>
45 #endif
46 #include <vnet/map/map.h>
47 #include <vnet/cop/cop.h>
48 #include <vnet/ip/ip6_hop_by_hop.h>
49 #include <vnet/ip/ip_source_and_port_range_check.h>
50 #include <vnet/policer/xlate.h>
51 #include <vnet/span/span.h>
52 #include <vnet/policer/policer.h>
53 #include <vnet/policer/police.h>
54
55 #include "vat/json_format.h"
56
57 #include <inttypes.h>
58 #include <sys/stat.h>
59
60 #define vl_typedefs             /* define message structures */
61 #include <vpp-api/vpe_all_api_h.h>
62 #undef vl_typedefs
63
64 /* declare message handlers for each api */
65
66 #define vl_endianfun            /* define message structures */
67 #include <vpp-api/vpe_all_api_h.h>
68 #undef vl_endianfun
69
70 /* instantiate all the print functions we know about */
71 #define vl_print(handle, ...)
72 #define vl_printfun
73 #include <vpp-api/vpe_all_api_h.h>
74 #undef vl_printfun
75
76 uword
77 unformat_sw_if_index (unformat_input_t * input, va_list * args)
78 {
79   vat_main_t *vam = va_arg (*args, vat_main_t *);
80   u32 *result = va_arg (*args, u32 *);
81   u8 *if_name;
82   uword *p;
83
84   if (!unformat (input, "%s", &if_name))
85     return 0;
86
87   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
88   if (p == 0)
89     return 0;
90   *result = p[0];
91   return 1;
92 }
93
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
116 uword
117 unformat_ethernet_address (unformat_input_t * input, va_list * args)
118 {
119   u8 *result = va_arg (*args, u8 *);
120   u32 i, a[6];
121
122   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
123                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
124     return 0;
125
126   /* Check range. */
127   for (i = 0; i < 6; i++)
128     if (a[i] >= (1 << 8))
129       return 0;
130
131   for (i = 0; i < 6; i++)
132     result[i] = a[i];
133
134   return 1;
135 }
136
137 /* Returns ethernet type as an int in host byte order. */
138 uword
139 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
140                                         va_list * args)
141 {
142   u16 *result = va_arg (*args, u16 *);
143   int type;
144
145   /* Numeric type. */
146   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
147     {
148       if (type >= (1 << 16))
149         return 0;
150       *result = type;
151       return 1;
152     }
153   return 0;
154 }
155
156 /* Parse an IP6 address. */
157 uword
158 unformat_ip6_address (unformat_input_t * input, va_list * args)
159 {
160   ip6_address_t *result = va_arg (*args, ip6_address_t *);
161   u16 hex_quads[8];
162   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
163   uword c, n_colon, double_colon_index;
164
165   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
166   double_colon_index = ARRAY_LEN (hex_quads);
167   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
168     {
169       hex_digit = 16;
170       if (c >= '0' && c <= '9')
171         hex_digit = c - '0';
172       else if (c >= 'a' && c <= 'f')
173         hex_digit = c + 10 - 'a';
174       else if (c >= 'A' && c <= 'F')
175         hex_digit = c + 10 - 'A';
176       else if (c == ':' && n_colon < 2)
177         n_colon++;
178       else
179         {
180           unformat_put_input (input);
181           break;
182         }
183
184       /* Too many hex quads. */
185       if (n_hex_quads >= ARRAY_LEN (hex_quads))
186         return 0;
187
188       if (hex_digit < 16)
189         {
190           hex_quad = (hex_quad << 4) | hex_digit;
191
192           /* Hex quad must fit in 16 bits. */
193           if (n_hex_digits >= 4)
194             return 0;
195
196           n_colon = 0;
197           n_hex_digits++;
198         }
199
200       /* Save position of :: */
201       if (n_colon == 2)
202         {
203           /* More than one :: ? */
204           if (double_colon_index < ARRAY_LEN (hex_quads))
205             return 0;
206           double_colon_index = n_hex_quads;
207         }
208
209       if (n_colon > 0 && n_hex_digits > 0)
210         {
211           hex_quads[n_hex_quads++] = hex_quad;
212           hex_quad = 0;
213           n_hex_digits = 0;
214         }
215     }
216
217   if (n_hex_digits > 0)
218     hex_quads[n_hex_quads++] = hex_quad;
219
220   {
221     word i;
222
223     /* Expand :: to appropriate number of zero hex quads. */
224     if (double_colon_index < ARRAY_LEN (hex_quads))
225       {
226         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
227
228         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
229           hex_quads[n_zero + i] = hex_quads[i];
230
231         for (i = 0; i < n_zero; i++)
232           hex_quads[double_colon_index + i] = 0;
233
234         n_hex_quads = ARRAY_LEN (hex_quads);
235       }
236
237     /* Too few hex quads given. */
238     if (n_hex_quads < ARRAY_LEN (hex_quads))
239       return 0;
240
241     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
242       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
243
244     return 1;
245   }
246 }
247
248 uword
249 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
250 {
251 #if DPDK > 0
252   u32 *r = va_arg (*args, u32 *);
253
254   if (0);
255 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
256   foreach_ipsec_policy_action
257 #undef _
258     else
259     return 0;
260   return 1;
261 #else
262   return 0;
263 #endif
264 }
265
266 uword
267 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
268 {
269 #if DPDK > 0
270   u32 *r = va_arg (*args, u32 *);
271
272   if (0);
273 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
274   foreach_ipsec_crypto_alg
275 #undef _
276     else
277     return 0;
278   return 1;
279 #else
280   return 0;
281 #endif
282 }
283
284 u8 *
285 format_ipsec_crypto_alg (u8 * s, va_list * args)
286 {
287 #if DPDK > 0
288   u32 i = va_arg (*args, u32);
289   u8 *t = 0;
290
291   switch (i)
292     {
293 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
294       foreach_ipsec_crypto_alg
295 #undef _
296     default:
297       return format (s, "unknown");
298     }
299   return format (s, "%s", t);
300 #else
301   return format (s, "Unimplemented");
302 #endif
303 }
304
305 uword
306 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
307 {
308 #if DPDK > 0
309   u32 *r = va_arg (*args, u32 *);
310
311   if (0);
312 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
313   foreach_ipsec_integ_alg
314 #undef _
315     else
316     return 0;
317   return 1;
318 #else
319   return 0;
320 #endif
321 }
322
323 u8 *
324 format_ipsec_integ_alg (u8 * s, va_list * args)
325 {
326 #if DPDK > 0
327   u32 i = va_arg (*args, u32);
328   u8 *t = 0;
329
330   switch (i)
331     {
332 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
333       foreach_ipsec_integ_alg
334 #undef _
335     default:
336       return format (s, "unknown");
337     }
338   return format (s, "%s", t);
339 #else
340   return format (s, "Unsupported");
341 #endif
342 }
343
344 uword
345 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
346 {
347 #if DPDK > 0
348   u32 *r = va_arg (*args, u32 *);
349
350   if (0);
351 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
352   foreach_ikev2_auth_method
353 #undef _
354     else
355     return 0;
356   return 1;
357 #else
358   return 0;
359 #endif
360 }
361
362 uword
363 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
364 {
365 #if DPDK > 0
366   u32 *r = va_arg (*args, u32 *);
367
368   if (0);
369 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
370   foreach_ikev2_id_type
371 #undef _
372     else
373     return 0;
374   return 1;
375 #else
376   return 0;
377 #endif
378 }
379
380 uword
381 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
382 {
383   u8 *r = va_arg (*args, u8 *);
384
385   if (unformat (input, "kbps"))
386     *r = SSE2_QOS_RATE_KBPS;
387   else if (unformat (input, "pps"))
388     *r = SSE2_QOS_RATE_PPS;
389   else
390     return 0;
391   return 1;
392 }
393
394 uword
395 unformat_policer_round_type (unformat_input_t * input, va_list * args)
396 {
397   u8 *r = va_arg (*args, u8 *);
398
399   if (unformat (input, "closest"))
400     *r = SSE2_QOS_ROUND_TO_CLOSEST;
401   else if (unformat (input, "up"))
402     *r = SSE2_QOS_ROUND_TO_UP;
403   else if (unformat (input, "down"))
404     *r = SSE2_QOS_ROUND_TO_DOWN;
405   else
406     return 0;
407   return 1;
408 }
409
410 uword
411 unformat_policer_type (unformat_input_t * input, va_list * args)
412 {
413   u8 *r = va_arg (*args, u8 *);
414
415   if (unformat (input, "1r2c"))
416     *r = SSE2_QOS_POLICER_TYPE_1R2C;
417   else if (unformat (input, "1r3c"))
418     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
419   else if (unformat (input, "2r3c-2698"))
420     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
421   else if (unformat (input, "2r3c-4115"))
422     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
423   else if (unformat (input, "2r3c-mef5cf1"))
424     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
425   else
426     return 0;
427   return 1;
428 }
429
430 uword
431 unformat_dscp (unformat_input_t * input, va_list * va)
432 {
433   u8 *r = va_arg (*va, u8 *);
434
435   if (0);
436 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
437   foreach_vnet_dscp
438 #undef _
439     else
440     return 0;
441   return 1;
442 }
443
444 uword
445 unformat_policer_action_type (unformat_input_t * input, va_list * va)
446 {
447   sse2_qos_pol_action_params_st *a
448     = va_arg (*va, sse2_qos_pol_action_params_st *);
449
450   if (unformat (input, "drop"))
451     a->action_type = SSE2_QOS_ACTION_DROP;
452   else if (unformat (input, "transmit"))
453     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
454   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
455     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
456   else
457     return 0;
458   return 1;
459 }
460
461 uword
462 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
463 {
464   u32 *r = va_arg (*va, u32 *);
465   u32 tid;
466
467   if (unformat (input, "ip4"))
468     tid = POLICER_CLASSIFY_TABLE_IP4;
469   else if (unformat (input, "ip6"))
470     tid = POLICER_CLASSIFY_TABLE_IP6;
471   else if (unformat (input, "l2"))
472     tid = POLICER_CLASSIFY_TABLE_L2;
473   else
474     return 0;
475
476   *r = tid;
477   return 1;
478 }
479
480 uword
481 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
482 {
483   u32 *r = va_arg (*va, u32 *);
484   u32 tid;
485
486   if (unformat (input, "ip4"))
487     tid = FLOW_CLASSIFY_TABLE_IP4;
488   else if (unformat (input, "ip6"))
489     tid = FLOW_CLASSIFY_TABLE_IP6;
490   else
491     return 0;
492
493   *r = tid;
494   return 1;
495 }
496
497 u8 *
498 format_ip4_address (u8 * s, va_list * args)
499 {
500   u8 *a = va_arg (*args, u8 *);
501   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
502 }
503
504 u8 *
505 format_ip6_address (u8 * s, va_list * args)
506 {
507   ip6_address_t *a = va_arg (*args, ip6_address_t *);
508   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
509
510   i_max_n_zero = ARRAY_LEN (a->as_u16);
511   max_n_zeros = 0;
512   i_first_zero = i_max_n_zero;
513   n_zeros = 0;
514   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
515     {
516       u32 is_zero = a->as_u16[i] == 0;
517       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
518         {
519           i_first_zero = i;
520           n_zeros = 0;
521         }
522       n_zeros += is_zero;
523       if ((!is_zero && n_zeros > max_n_zeros)
524           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
525         {
526           i_max_n_zero = i_first_zero;
527           max_n_zeros = n_zeros;
528           i_first_zero = ARRAY_LEN (a->as_u16);
529           n_zeros = 0;
530         }
531     }
532
533   last_double_colon = 0;
534   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
535     {
536       if (i == i_max_n_zero && max_n_zeros > 1)
537         {
538           s = format (s, "::");
539           i += max_n_zeros - 1;
540           last_double_colon = 1;
541         }
542       else
543         {
544           s = format (s, "%s%x",
545                       (last_double_colon || i == 0) ? "" : ":",
546                       clib_net_to_host_u16 (a->as_u16[i]));
547           last_double_colon = 0;
548         }
549     }
550
551   return s;
552 }
553
554 /* Format an IP46 address. */
555 u8 *
556 format_ip46_address (u8 * s, va_list * args)
557 {
558   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
559   ip46_type_t type = va_arg (*args, ip46_type_t);
560   int is_ip4 = 1;
561
562   switch (type)
563     {
564     case IP46_TYPE_ANY:
565       is_ip4 = ip46_address_is_ip4 (ip46);
566       break;
567     case IP46_TYPE_IP4:
568       is_ip4 = 1;
569       break;
570     case IP46_TYPE_IP6:
571       is_ip4 = 0;
572       break;
573     }
574
575   return is_ip4 ?
576     format (s, "%U", format_ip4_address, &ip46->ip4) :
577     format (s, "%U", format_ip6_address, &ip46->ip6);
578 }
579
580 u8 *
581 format_ethernet_address (u8 * s, va_list * args)
582 {
583   u8 *a = va_arg (*args, u8 *);
584
585   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
586                  a[0], a[1], a[2], a[3], a[4], a[5]);
587 }
588
589 void
590 increment_v4_address (ip4_address_t * a)
591 {
592   u32 v;
593
594   v = ntohl (a->as_u32) + 1;
595   a->as_u32 = ntohl (v);
596 }
597
598 void
599 increment_v6_address (ip6_address_t * a)
600 {
601   u64 v0, v1;
602
603   v0 = clib_net_to_host_u64 (a->as_u64[0]);
604   v1 = clib_net_to_host_u64 (a->as_u64[1]);
605
606   v1 += 1;
607   if (v1 == 0)
608     v0 += 1;
609   a->as_u64[0] = clib_net_to_host_u64 (v0);
610   a->as_u64[1] = clib_net_to_host_u64 (v1);
611 }
612
613 void
614 increment_mac_address (u64 * mac)
615 {
616   u64 tmp = *mac;
617
618   tmp = clib_net_to_host_u64 (tmp);
619   tmp += 1 << 16;               /* skip unused (least significant) octets */
620   tmp = clib_host_to_net_u64 (tmp);
621   *mac = tmp;
622 }
623
624 static void vl_api_create_loopback_reply_t_handler
625   (vl_api_create_loopback_reply_t * mp)
626 {
627   vat_main_t *vam = &vat_main;
628   i32 retval = ntohl (mp->retval);
629
630   vam->retval = retval;
631   vam->regenerate_interface_table = 1;
632   vam->sw_if_index = ntohl (mp->sw_if_index);
633   vam->result_ready = 1;
634 }
635
636 static void vl_api_create_loopback_reply_t_handler_json
637   (vl_api_create_loopback_reply_t * mp)
638 {
639   vat_main_t *vam = &vat_main;
640   vat_json_node_t node;
641
642   vat_json_init_object (&node);
643   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
644   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
645
646   vat_json_print (vam->ofp, &node);
647   vat_json_free (&node);
648   vam->retval = ntohl (mp->retval);
649   vam->result_ready = 1;
650 }
651
652 static void vl_api_af_packet_create_reply_t_handler
653   (vl_api_af_packet_create_reply_t * mp)
654 {
655   vat_main_t *vam = &vat_main;
656   i32 retval = ntohl (mp->retval);
657
658   vam->retval = retval;
659   vam->regenerate_interface_table = 1;
660   vam->sw_if_index = ntohl (mp->sw_if_index);
661   vam->result_ready = 1;
662 }
663
664 static void vl_api_af_packet_create_reply_t_handler_json
665   (vl_api_af_packet_create_reply_t * mp)
666 {
667   vat_main_t *vam = &vat_main;
668   vat_json_node_t node;
669
670   vat_json_init_object (&node);
671   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
672   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
673
674   vat_json_print (vam->ofp, &node);
675   vat_json_free (&node);
676
677   vam->retval = ntohl (mp->retval);
678   vam->result_ready = 1;
679 }
680
681 static void vl_api_create_vlan_subif_reply_t_handler
682   (vl_api_create_vlan_subif_reply_t * mp)
683 {
684   vat_main_t *vam = &vat_main;
685   i32 retval = ntohl (mp->retval);
686
687   vam->retval = retval;
688   vam->regenerate_interface_table = 1;
689   vam->sw_if_index = ntohl (mp->sw_if_index);
690   vam->result_ready = 1;
691 }
692
693 static void vl_api_create_vlan_subif_reply_t_handler_json
694   (vl_api_create_vlan_subif_reply_t * mp)
695 {
696   vat_main_t *vam = &vat_main;
697   vat_json_node_t node;
698
699   vat_json_init_object (&node);
700   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
701   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
702
703   vat_json_print (vam->ofp, &node);
704   vat_json_free (&node);
705
706   vam->retval = ntohl (mp->retval);
707   vam->result_ready = 1;
708 }
709
710 static void vl_api_create_subif_reply_t_handler
711   (vl_api_create_subif_reply_t * mp)
712 {
713   vat_main_t *vam = &vat_main;
714   i32 retval = ntohl (mp->retval);
715
716   vam->retval = retval;
717   vam->regenerate_interface_table = 1;
718   vam->sw_if_index = ntohl (mp->sw_if_index);
719   vam->result_ready = 1;
720 }
721
722 static void vl_api_create_subif_reply_t_handler_json
723   (vl_api_create_subif_reply_t * mp)
724 {
725   vat_main_t *vam = &vat_main;
726   vat_json_node_t node;
727
728   vat_json_init_object (&node);
729   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
730   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
731
732   vat_json_print (vam->ofp, &node);
733   vat_json_free (&node);
734
735   vam->retval = ntohl (mp->retval);
736   vam->result_ready = 1;
737 }
738
739 static void vl_api_interface_name_renumber_reply_t_handler
740   (vl_api_interface_name_renumber_reply_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   i32 retval = ntohl (mp->retval);
744
745   vam->retval = retval;
746   vam->regenerate_interface_table = 1;
747   vam->result_ready = 1;
748 }
749
750 static void vl_api_interface_name_renumber_reply_t_handler_json
751   (vl_api_interface_name_renumber_reply_t * mp)
752 {
753   vat_main_t *vam = &vat_main;
754   vat_json_node_t node;
755
756   vat_json_init_object (&node);
757   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
758
759   vat_json_print (vam->ofp, &node);
760   vat_json_free (&node);
761
762   vam->retval = ntohl (mp->retval);
763   vam->result_ready = 1;
764 }
765
766 /*
767  * Special-case: build the interface table, maintain
768  * the next loopback sw_if_index vbl.
769  */
770 static void vl_api_sw_interface_details_t_handler
771   (vl_api_sw_interface_details_t * mp)
772 {
773   vat_main_t *vam = &vat_main;
774   u8 *s = format (0, "%s%c", mp->interface_name, 0);
775
776   hash_set_mem (vam->sw_if_index_by_interface_name, s,
777                 ntohl (mp->sw_if_index));
778
779   /* In sub interface case, fill the sub interface table entry */
780   if (mp->sw_if_index != mp->sup_sw_if_index)
781     {
782       sw_interface_subif_t *sub = NULL;
783
784       vec_add2 (vam->sw_if_subif_table, sub, 1);
785
786       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
787       strncpy ((char *) sub->interface_name, (char *) s,
788                vec_len (sub->interface_name));
789       sub->sw_if_index = ntohl (mp->sw_if_index);
790       sub->sub_id = ntohl (mp->sub_id);
791
792       sub->sub_dot1ad = mp->sub_dot1ad;
793       sub->sub_number_of_tags = mp->sub_number_of_tags;
794       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
795       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
796       sub->sub_exact_match = mp->sub_exact_match;
797       sub->sub_default = mp->sub_default;
798       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
799       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
800
801       /* vlan tag rewrite */
802       sub->vtr_op = ntohl (mp->vtr_op);
803       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
804       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
805       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
806     }
807 }
808
809 static void vl_api_sw_interface_details_t_handler_json
810   (vl_api_sw_interface_details_t * mp)
811 {
812   vat_main_t *vam = &vat_main;
813   vat_json_node_t *node = NULL;
814
815   if (VAT_JSON_ARRAY != vam->json_tree.type)
816     {
817       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
818       vat_json_init_array (&vam->json_tree);
819     }
820   node = vat_json_array_add (&vam->json_tree);
821
822   vat_json_init_object (node);
823   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
824   vat_json_object_add_uint (node, "sup_sw_if_index",
825                             ntohl (mp->sup_sw_if_index));
826   vat_json_object_add_uint (node, "l2_address_length",
827                             ntohl (mp->l2_address_length));
828   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
829                              sizeof (mp->l2_address));
830   vat_json_object_add_string_copy (node, "interface_name",
831                                    mp->interface_name);
832   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
833   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
834   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
835   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
836   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
837   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
838   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
839   vat_json_object_add_uint (node, "sub_number_of_tags",
840                             mp->sub_number_of_tags);
841   vat_json_object_add_uint (node, "sub_outer_vlan_id",
842                             ntohs (mp->sub_outer_vlan_id));
843   vat_json_object_add_uint (node, "sub_inner_vlan_id",
844                             ntohs (mp->sub_inner_vlan_id));
845   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
846   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
847   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
848                             mp->sub_outer_vlan_id_any);
849   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
850                             mp->sub_inner_vlan_id_any);
851   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
852   vat_json_object_add_uint (node, "vtr_push_dot1q",
853                             ntohl (mp->vtr_push_dot1q));
854   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
855   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
856 }
857
858 static void vl_api_sw_interface_set_flags_t_handler
859   (vl_api_sw_interface_set_flags_t * mp)
860 {
861   vat_main_t *vam = &vat_main;
862   if (vam->interface_event_display)
863     errmsg ("interface flags: sw_if_index %d %s %s\n",
864             ntohl (mp->sw_if_index),
865             mp->admin_up_down ? "admin-up" : "admin-down",
866             mp->link_up_down ? "link-up" : "link-down");
867 }
868
869 static void vl_api_sw_interface_set_flags_t_handler_json
870   (vl_api_sw_interface_set_flags_t * mp)
871 {
872   /* JSON output not supported */
873 }
874
875 static void
876 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
877 {
878   vat_main_t *vam = &vat_main;
879   i32 retval = ntohl (mp->retval);
880
881   vam->retval = retval;
882   vam->shmem_result = (u8 *) mp->reply_in_shmem;
883   vam->result_ready = 1;
884 }
885
886 static void
887 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
888 {
889   vat_main_t *vam = &vat_main;
890   vat_json_node_t node;
891   api_main_t *am = &api_main;
892   void *oldheap;
893   u8 *reply;
894
895   vat_json_init_object (&node);
896   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
897   vat_json_object_add_uint (&node, "reply_in_shmem",
898                             ntohl (mp->reply_in_shmem));
899   /* Toss the shared-memory original... */
900   pthread_mutex_lock (&am->vlib_rp->mutex);
901   oldheap = svm_push_data_heap (am->vlib_rp);
902
903   reply = (u8 *) (mp->reply_in_shmem);
904   vec_free (reply);
905
906   svm_pop_heap (oldheap);
907   pthread_mutex_unlock (&am->vlib_rp->mutex);
908
909   vat_json_print (vam->ofp, &node);
910   vat_json_free (&node);
911
912   vam->retval = ntohl (mp->retval);
913   vam->result_ready = 1;
914 }
915
916 static void
917 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
918 {
919   vat_main_t *vam = &vat_main;
920   i32 retval = ntohl (mp->retval);
921
922   vam->retval = retval;
923   vam->cmd_reply = mp->reply;
924   vam->result_ready = 1;
925 }
926
927 static void
928 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
929 {
930   vat_main_t *vam = &vat_main;
931   vat_json_node_t node;
932
933   vat_json_init_object (&node);
934   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
935   vat_json_object_add_string_copy (&node, "reply", mp->reply);
936
937   vat_json_print (vam->ofp, &node);
938   vat_json_free (&node);
939
940   vam->retval = ntohl (mp->retval);
941   vam->result_ready = 1;
942 }
943
944 static void vl_api_classify_add_del_table_reply_t_handler
945   (vl_api_classify_add_del_table_reply_t * mp)
946 {
947   vat_main_t *vam = &vat_main;
948   i32 retval = ntohl (mp->retval);
949   if (vam->async_mode)
950     {
951       vam->async_errors += (retval < 0);
952     }
953   else
954     {
955       vam->retval = retval;
956       if (retval == 0 &&
957           ((mp->new_table_index != 0xFFFFFFFF) ||
958            (mp->skip_n_vectors != 0xFFFFFFFF) ||
959            (mp->match_n_vectors != 0xFFFFFFFF)))
960         /*
961          * Note: this is just barely thread-safe, depends on
962          * the main thread spinning waiting for an answer...
963          */
964         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
965                 ntohl (mp->new_table_index),
966                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
967       vam->result_ready = 1;
968     }
969 }
970
971 static void vl_api_classify_add_del_table_reply_t_handler_json
972   (vl_api_classify_add_del_table_reply_t * mp)
973 {
974   vat_main_t *vam = &vat_main;
975   vat_json_node_t node;
976
977   vat_json_init_object (&node);
978   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
979   vat_json_object_add_uint (&node, "new_table_index",
980                             ntohl (mp->new_table_index));
981   vat_json_object_add_uint (&node, "skip_n_vectors",
982                             ntohl (mp->skip_n_vectors));
983   vat_json_object_add_uint (&node, "match_n_vectors",
984                             ntohl (mp->match_n_vectors));
985
986   vat_json_print (vam->ofp, &node);
987   vat_json_free (&node);
988
989   vam->retval = ntohl (mp->retval);
990   vam->result_ready = 1;
991 }
992
993 static void vl_api_get_node_index_reply_t_handler
994   (vl_api_get_node_index_reply_t * mp)
995 {
996   vat_main_t *vam = &vat_main;
997   i32 retval = ntohl (mp->retval);
998   if (vam->async_mode)
999     {
1000       vam->async_errors += (retval < 0);
1001     }
1002   else
1003     {
1004       vam->retval = retval;
1005       if (retval == 0)
1006         errmsg ("node index %d\n", ntohl (mp->node_index));
1007       vam->result_ready = 1;
1008     }
1009 }
1010
1011 static void vl_api_get_node_index_reply_t_handler_json
1012   (vl_api_get_node_index_reply_t * mp)
1013 {
1014   vat_main_t *vam = &vat_main;
1015   vat_json_node_t node;
1016
1017   vat_json_init_object (&node);
1018   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1019   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1020
1021   vat_json_print (vam->ofp, &node);
1022   vat_json_free (&node);
1023
1024   vam->retval = ntohl (mp->retval);
1025   vam->result_ready = 1;
1026 }
1027
1028 static void vl_api_get_next_index_reply_t_handler
1029   (vl_api_get_next_index_reply_t * mp)
1030 {
1031   vat_main_t *vam = &vat_main;
1032   i32 retval = ntohl (mp->retval);
1033   if (vam->async_mode)
1034     {
1035       vam->async_errors += (retval < 0);
1036     }
1037   else
1038     {
1039       vam->retval = retval;
1040       if (retval == 0)
1041         errmsg ("next node index %d\n", ntohl (mp->next_index));
1042       vam->result_ready = 1;
1043     }
1044 }
1045
1046 static void vl_api_get_next_index_reply_t_handler_json
1047   (vl_api_get_next_index_reply_t * mp)
1048 {
1049   vat_main_t *vam = &vat_main;
1050   vat_json_node_t node;
1051
1052   vat_json_init_object (&node);
1053   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1054   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1055
1056   vat_json_print (vam->ofp, &node);
1057   vat_json_free (&node);
1058
1059   vam->retval = ntohl (mp->retval);
1060   vam->result_ready = 1;
1061 }
1062
1063 static void vl_api_add_node_next_reply_t_handler
1064   (vl_api_add_node_next_reply_t * mp)
1065 {
1066   vat_main_t *vam = &vat_main;
1067   i32 retval = ntohl (mp->retval);
1068   if (vam->async_mode)
1069     {
1070       vam->async_errors += (retval < 0);
1071     }
1072   else
1073     {
1074       vam->retval = retval;
1075       if (retval == 0)
1076         errmsg ("next index %d\n", ntohl (mp->next_index));
1077       vam->result_ready = 1;
1078     }
1079 }
1080
1081 static void vl_api_add_node_next_reply_t_handler_json
1082   (vl_api_add_node_next_reply_t * mp)
1083 {
1084   vat_main_t *vam = &vat_main;
1085   vat_json_node_t node;
1086
1087   vat_json_init_object (&node);
1088   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1089   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1090
1091   vat_json_print (vam->ofp, &node);
1092   vat_json_free (&node);
1093
1094   vam->retval = ntohl (mp->retval);
1095   vam->result_ready = 1;
1096 }
1097
1098 static void vl_api_show_version_reply_t_handler
1099   (vl_api_show_version_reply_t * mp)
1100 {
1101   vat_main_t *vam = &vat_main;
1102   i32 retval = ntohl (mp->retval);
1103
1104   if (retval >= 0)
1105     {
1106       errmsg ("        program: %s\n", mp->program);
1107       errmsg ("        version: %s\n", mp->version);
1108       errmsg ("     build date: %s\n", mp->build_date);
1109       errmsg ("build directory: %s\n", mp->build_directory);
1110     }
1111   vam->retval = retval;
1112   vam->result_ready = 1;
1113 }
1114
1115 static void vl_api_show_version_reply_t_handler_json
1116   (vl_api_show_version_reply_t * mp)
1117 {
1118   vat_main_t *vam = &vat_main;
1119   vat_json_node_t node;
1120
1121   vat_json_init_object (&node);
1122   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1123   vat_json_object_add_string_copy (&node, "program", mp->program);
1124   vat_json_object_add_string_copy (&node, "version", mp->version);
1125   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1126   vat_json_object_add_string_copy (&node, "build_directory",
1127                                    mp->build_directory);
1128
1129   vat_json_print (vam->ofp, &node);
1130   vat_json_free (&node);
1131
1132   vam->retval = ntohl (mp->retval);
1133   vam->result_ready = 1;
1134 }
1135
1136 static void
1137 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1138 {
1139   vat_main_t *vam = &vat_main;
1140   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1141           mp->mac_ip ? "mac/ip binding" : "address resolution",
1142           format_ip4_address, &mp->address,
1143           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1144 }
1145
1146 static void
1147 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1148 {
1149   /* JSON output not supported */
1150 }
1151
1152 static void
1153 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1154 {
1155   vat_main_t *vam = &vat_main;
1156   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1157           mp->mac_ip ? "mac/ip binding" : "address resolution",
1158           format_ip6_address, mp->address,
1159           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1160 }
1161
1162 static void
1163 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1164 {
1165   /* JSON output not supported */
1166 }
1167
1168 /*
1169  * Special-case: build the bridge domain table, maintain
1170  * the next bd id vbl.
1171  */
1172 static void vl_api_bridge_domain_details_t_handler
1173   (vl_api_bridge_domain_details_t * mp)
1174 {
1175   vat_main_t *vam = &vat_main;
1176   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1177
1178   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1179            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1180
1181   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1182            ntohl (mp->bd_id), mp->learn, mp->forward,
1183            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1184
1185   if (n_sw_ifs)
1186     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1187              "Interface Name");
1188 }
1189
1190 static void vl_api_bridge_domain_details_t_handler_json
1191   (vl_api_bridge_domain_details_t * mp)
1192 {
1193   vat_main_t *vam = &vat_main;
1194   vat_json_node_t *node, *array = NULL;
1195
1196   if (VAT_JSON_ARRAY != vam->json_tree.type)
1197     {
1198       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1199       vat_json_init_array (&vam->json_tree);
1200     }
1201   node = vat_json_array_add (&vam->json_tree);
1202
1203   vat_json_init_object (node);
1204   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1205   vat_json_object_add_uint (node, "flood", mp->flood);
1206   vat_json_object_add_uint (node, "forward", mp->forward);
1207   vat_json_object_add_uint (node, "learn", mp->learn);
1208   vat_json_object_add_uint (node, "bvi_sw_if_index",
1209                             ntohl (mp->bvi_sw_if_index));
1210   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1211   array = vat_json_object_add (node, "sw_if");
1212   vat_json_init_array (array);
1213 }
1214
1215 /*
1216  * Special-case: build the bridge domain sw if table.
1217  */
1218 static void vl_api_bridge_domain_sw_if_details_t_handler
1219   (vl_api_bridge_domain_sw_if_details_t * mp)
1220 {
1221   vat_main_t *vam = &vat_main;
1222   hash_pair_t *p;
1223   u8 *sw_if_name = 0;
1224   u32 sw_if_index;
1225
1226   sw_if_index = ntohl (mp->sw_if_index);
1227   /* *INDENT-OFF* */
1228   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1229   ({
1230     if ((u32) p->value[0] == sw_if_index)
1231       {
1232         sw_if_name = (u8 *)(p->key);
1233         break;
1234       }
1235   }));
1236   /* *INDENT-ON* */
1237
1238   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1239            mp->shg, sw_if_name ? (char *) sw_if_name :
1240            "sw_if_index not found!");
1241 }
1242
1243 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1244   (vl_api_bridge_domain_sw_if_details_t * mp)
1245 {
1246   vat_main_t *vam = &vat_main;
1247   vat_json_node_t *node = NULL;
1248   uword last_index = 0;
1249
1250   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1251   ASSERT (vec_len (vam->json_tree.array) >= 1);
1252   last_index = vec_len (vam->json_tree.array) - 1;
1253   node = &vam->json_tree.array[last_index];
1254   node = vat_json_object_get_element (node, "sw_if");
1255   ASSERT (NULL != node);
1256   node = vat_json_array_add (node);
1257
1258   vat_json_init_object (node);
1259   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1260   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1261   vat_json_object_add_uint (node, "shg", mp->shg);
1262 }
1263
1264 static void vl_api_control_ping_reply_t_handler
1265   (vl_api_control_ping_reply_t * mp)
1266 {
1267   vat_main_t *vam = &vat_main;
1268   i32 retval = ntohl (mp->retval);
1269   if (vam->async_mode)
1270     {
1271       vam->async_errors += (retval < 0);
1272     }
1273   else
1274     {
1275       vam->retval = retval;
1276       vam->result_ready = 1;
1277     }
1278 }
1279
1280 static void vl_api_control_ping_reply_t_handler_json
1281   (vl_api_control_ping_reply_t * mp)
1282 {
1283   vat_main_t *vam = &vat_main;
1284   i32 retval = ntohl (mp->retval);
1285
1286   if (VAT_JSON_NONE != vam->json_tree.type)
1287     {
1288       vat_json_print (vam->ofp, &vam->json_tree);
1289       vat_json_free (&vam->json_tree);
1290       vam->json_tree.type = VAT_JSON_NONE;
1291     }
1292   else
1293     {
1294       /* just print [] */
1295       vat_json_init_array (&vam->json_tree);
1296       vat_json_print (vam->ofp, &vam->json_tree);
1297       vam->json_tree.type = VAT_JSON_NONE;
1298     }
1299
1300   vam->retval = retval;
1301   vam->result_ready = 1;
1302 }
1303
1304 static void
1305 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1306 {
1307   vat_main_t *vam = &vat_main;
1308   i32 retval = ntohl (mp->retval);
1309   if (vam->async_mode)
1310     {
1311       vam->async_errors += (retval < 0);
1312     }
1313   else
1314     {
1315       vam->retval = retval;
1316       vam->result_ready = 1;
1317     }
1318 }
1319
1320 static void vl_api_l2_flags_reply_t_handler_json
1321   (vl_api_l2_flags_reply_t * mp)
1322 {
1323   vat_main_t *vam = &vat_main;
1324   vat_json_node_t node;
1325
1326   vat_json_init_object (&node);
1327   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1328   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1329                             ntohl (mp->resulting_feature_bitmap));
1330
1331   vat_json_print (vam->ofp, &node);
1332   vat_json_free (&node);
1333
1334   vam->retval = ntohl (mp->retval);
1335   vam->result_ready = 1;
1336 }
1337
1338 static void vl_api_bridge_flags_reply_t_handler
1339   (vl_api_bridge_flags_reply_t * mp)
1340 {
1341   vat_main_t *vam = &vat_main;
1342   i32 retval = ntohl (mp->retval);
1343   if (vam->async_mode)
1344     {
1345       vam->async_errors += (retval < 0);
1346     }
1347   else
1348     {
1349       vam->retval = retval;
1350       vam->result_ready = 1;
1351     }
1352 }
1353
1354 static void vl_api_bridge_flags_reply_t_handler_json
1355   (vl_api_bridge_flags_reply_t * mp)
1356 {
1357   vat_main_t *vam = &vat_main;
1358   vat_json_node_t node;
1359
1360   vat_json_init_object (&node);
1361   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1362   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1363                             ntohl (mp->resulting_feature_bitmap));
1364
1365   vat_json_print (vam->ofp, &node);
1366   vat_json_free (&node);
1367
1368   vam->retval = ntohl (mp->retval);
1369   vam->result_ready = 1;
1370 }
1371
1372 static void vl_api_tap_connect_reply_t_handler
1373   (vl_api_tap_connect_reply_t * mp)
1374 {
1375   vat_main_t *vam = &vat_main;
1376   i32 retval = ntohl (mp->retval);
1377   if (vam->async_mode)
1378     {
1379       vam->async_errors += (retval < 0);
1380     }
1381   else
1382     {
1383       vam->retval = retval;
1384       vam->sw_if_index = ntohl (mp->sw_if_index);
1385       vam->result_ready = 1;
1386     }
1387
1388 }
1389
1390 static void vl_api_tap_connect_reply_t_handler_json
1391   (vl_api_tap_connect_reply_t * mp)
1392 {
1393   vat_main_t *vam = &vat_main;
1394   vat_json_node_t node;
1395
1396   vat_json_init_object (&node);
1397   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1398   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1399
1400   vat_json_print (vam->ofp, &node);
1401   vat_json_free (&node);
1402
1403   vam->retval = ntohl (mp->retval);
1404   vam->result_ready = 1;
1405
1406 }
1407
1408 static void
1409 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1410 {
1411   vat_main_t *vam = &vat_main;
1412   i32 retval = ntohl (mp->retval);
1413   if (vam->async_mode)
1414     {
1415       vam->async_errors += (retval < 0);
1416     }
1417   else
1418     {
1419       vam->retval = retval;
1420       vam->sw_if_index = ntohl (mp->sw_if_index);
1421       vam->result_ready = 1;
1422     }
1423 }
1424
1425 static void vl_api_tap_modify_reply_t_handler_json
1426   (vl_api_tap_modify_reply_t * mp)
1427 {
1428   vat_main_t *vam = &vat_main;
1429   vat_json_node_t node;
1430
1431   vat_json_init_object (&node);
1432   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1433   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1434
1435   vat_json_print (vam->ofp, &node);
1436   vat_json_free (&node);
1437
1438   vam->retval = ntohl (mp->retval);
1439   vam->result_ready = 1;
1440 }
1441
1442 static void
1443 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1444 {
1445   vat_main_t *vam = &vat_main;
1446   i32 retval = ntohl (mp->retval);
1447   if (vam->async_mode)
1448     {
1449       vam->async_errors += (retval < 0);
1450     }
1451   else
1452     {
1453       vam->retval = retval;
1454       vam->result_ready = 1;
1455     }
1456 }
1457
1458 static void vl_api_tap_delete_reply_t_handler_json
1459   (vl_api_tap_delete_reply_t * mp)
1460 {
1461   vat_main_t *vam = &vat_main;
1462   vat_json_node_t node;
1463
1464   vat_json_init_object (&node);
1465   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1466
1467   vat_json_print (vam->ofp, &node);
1468   vat_json_free (&node);
1469
1470   vam->retval = ntohl (mp->retval);
1471   vam->result_ready = 1;
1472 }
1473
1474 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1475   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1476 {
1477   vat_main_t *vam = &vat_main;
1478   i32 retval = ntohl (mp->retval);
1479   if (vam->async_mode)
1480     {
1481       vam->async_errors += (retval < 0);
1482     }
1483   else
1484     {
1485       vam->retval = retval;
1486       vam->result_ready = 1;
1487     }
1488 }
1489
1490 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1491   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1492 {
1493   vat_main_t *vam = &vat_main;
1494   vat_json_node_t node;
1495
1496   vat_json_init_object (&node);
1497   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1498   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1499                             ntohl (mp->tunnel_sw_if_index));
1500
1501   vat_json_print (vam->ofp, &node);
1502   vat_json_free (&node);
1503
1504   vam->retval = ntohl (mp->retval);
1505   vam->result_ready = 1;
1506 }
1507
1508 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1509   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1510 {
1511   vat_main_t *vam = &vat_main;
1512   i32 retval = ntohl (mp->retval);
1513   if (vam->async_mode)
1514     {
1515       vam->async_errors += (retval < 0);
1516     }
1517   else
1518     {
1519       vam->retval = retval;
1520       vam->sw_if_index = ntohl (mp->sw_if_index);
1521       vam->result_ready = 1;
1522     }
1523 }
1524
1525 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1526   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1527 {
1528   vat_main_t *vam = &vat_main;
1529   vat_json_node_t node;
1530
1531   vat_json_init_object (&node);
1532   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1533   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1534
1535   vat_json_print (vam->ofp, &node);
1536   vat_json_free (&node);
1537
1538   vam->retval = ntohl (mp->retval);
1539   vam->result_ready = 1;
1540 }
1541
1542
1543 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1544   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1545 {
1546   vat_main_t *vam = &vat_main;
1547   i32 retval = ntohl (mp->retval);
1548   if (vam->async_mode)
1549     {
1550       vam->async_errors += (retval < 0);
1551     }
1552   else
1553     {
1554       vam->retval = retval;
1555       vam->result_ready = 1;
1556     }
1557 }
1558
1559 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1560   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1561 {
1562   vat_main_t *vam = &vat_main;
1563   vat_json_node_t node;
1564
1565   vat_json_init_object (&node);
1566   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1567   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1568
1569   vat_json_print (vam->ofp, &node);
1570   vat_json_free (&node);
1571
1572   vam->retval = ntohl (mp->retval);
1573   vam->result_ready = 1;
1574 }
1575
1576 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1577   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1578 {
1579   vat_main_t *vam = &vat_main;
1580   i32 retval = ntohl (mp->retval);
1581   if (vam->async_mode)
1582     {
1583       vam->async_errors += (retval < 0);
1584     }
1585   else
1586     {
1587       vam->retval = retval;
1588       vam->sw_if_index = ntohl (mp->sw_if_index);
1589       vam->result_ready = 1;
1590     }
1591 }
1592
1593 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1594   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1595 {
1596   vat_main_t *vam = &vat_main;
1597   vat_json_node_t node;
1598
1599   vat_json_init_object (&node);
1600   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1601   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1602
1603   vat_json_print (vam->ofp, &node);
1604   vat_json_free (&node);
1605
1606   vam->retval = ntohl (mp->retval);
1607   vam->result_ready = 1;
1608 }
1609
1610 static void vl_api_gre_add_del_tunnel_reply_t_handler
1611   (vl_api_gre_add_del_tunnel_reply_t * mp)
1612 {
1613   vat_main_t *vam = &vat_main;
1614   i32 retval = ntohl (mp->retval);
1615   if (vam->async_mode)
1616     {
1617       vam->async_errors += (retval < 0);
1618     }
1619   else
1620     {
1621       vam->retval = retval;
1622       vam->sw_if_index = ntohl (mp->sw_if_index);
1623       vam->result_ready = 1;
1624     }
1625 }
1626
1627 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1628   (vl_api_gre_add_del_tunnel_reply_t * mp)
1629 {
1630   vat_main_t *vam = &vat_main;
1631   vat_json_node_t node;
1632
1633   vat_json_init_object (&node);
1634   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1635   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1636
1637   vat_json_print (vam->ofp, &node);
1638   vat_json_free (&node);
1639
1640   vam->retval = ntohl (mp->retval);
1641   vam->result_ready = 1;
1642 }
1643
1644 static void vl_api_create_vhost_user_if_reply_t_handler
1645   (vl_api_create_vhost_user_if_reply_t * mp)
1646 {
1647   vat_main_t *vam = &vat_main;
1648   i32 retval = ntohl (mp->retval);
1649   if (vam->async_mode)
1650     {
1651       vam->async_errors += (retval < 0);
1652     }
1653   else
1654     {
1655       vam->retval = retval;
1656       vam->sw_if_index = ntohl (mp->sw_if_index);
1657       vam->result_ready = 1;
1658     }
1659 }
1660
1661 static void vl_api_create_vhost_user_if_reply_t_handler_json
1662   (vl_api_create_vhost_user_if_reply_t * mp)
1663 {
1664   vat_main_t *vam = &vat_main;
1665   vat_json_node_t node;
1666
1667   vat_json_init_object (&node);
1668   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1669   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1670
1671   vat_json_print (vam->ofp, &node);
1672   vat_json_free (&node);
1673
1674   vam->retval = ntohl (mp->retval);
1675   vam->result_ready = 1;
1676 }
1677
1678 static void vl_api_ip_address_details_t_handler
1679   (vl_api_ip_address_details_t * mp)
1680 {
1681   vat_main_t *vam = &vat_main;
1682   static ip_address_details_t empty_ip_address_details = { {0} };
1683   ip_address_details_t *address = NULL;
1684   ip_details_t *current_ip_details = NULL;
1685   ip_details_t *details = NULL;
1686
1687   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1688
1689   if (!details || vam->current_sw_if_index >= vec_len (details)
1690       || !details[vam->current_sw_if_index].present)
1691     {
1692       errmsg ("ip address details arrived but not stored\n");
1693       errmsg ("ip_dump should be called first\n");
1694       return;
1695     }
1696
1697   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1698
1699 #define addresses (current_ip_details->addr)
1700
1701   vec_validate_init_empty (addresses, vec_len (addresses),
1702                            empty_ip_address_details);
1703
1704   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1705
1706   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1707   address->prefix_length = mp->prefix_length;
1708 #undef addresses
1709 }
1710
1711 static void vl_api_ip_address_details_t_handler_json
1712   (vl_api_ip_address_details_t * mp)
1713 {
1714   vat_main_t *vam = &vat_main;
1715   vat_json_node_t *node = NULL;
1716   struct in6_addr ip6;
1717   struct in_addr ip4;
1718
1719   if (VAT_JSON_ARRAY != vam->json_tree.type)
1720     {
1721       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1722       vat_json_init_array (&vam->json_tree);
1723     }
1724   node = vat_json_array_add (&vam->json_tree);
1725
1726   vat_json_init_object (node);
1727   if (vam->is_ipv6)
1728     {
1729       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1730       vat_json_object_add_ip6 (node, "ip", ip6);
1731     }
1732   else
1733     {
1734       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1735       vat_json_object_add_ip4 (node, "ip", ip4);
1736     }
1737   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1738 }
1739
1740 static void
1741 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1742 {
1743   vat_main_t *vam = &vat_main;
1744   static ip_details_t empty_ip_details = { 0 };
1745   ip_details_t *ip = NULL;
1746   u32 sw_if_index = ~0;
1747
1748   sw_if_index = ntohl (mp->sw_if_index);
1749
1750   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1751                            sw_if_index, empty_ip_details);
1752
1753   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1754                          sw_if_index);
1755
1756   ip->present = 1;
1757 }
1758
1759 static void
1760 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1761 {
1762   vat_main_t *vam = &vat_main;
1763
1764   if (VAT_JSON_ARRAY != vam->json_tree.type)
1765     {
1766       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1767       vat_json_init_array (&vam->json_tree);
1768     }
1769   vat_json_array_add_uint (&vam->json_tree,
1770                            clib_net_to_host_u32 (mp->sw_if_index));
1771 }
1772
1773 static void vl_api_map_domain_details_t_handler_json
1774   (vl_api_map_domain_details_t * mp)
1775 {
1776   vat_json_node_t *node = NULL;
1777   vat_main_t *vam = &vat_main;
1778   struct in6_addr ip6;
1779   struct in_addr ip4;
1780
1781   if (VAT_JSON_ARRAY != vam->json_tree.type)
1782     {
1783       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1784       vat_json_init_array (&vam->json_tree);
1785     }
1786
1787   node = vat_json_array_add (&vam->json_tree);
1788   vat_json_init_object (node);
1789
1790   vat_json_object_add_uint (node, "domain_index",
1791                             clib_net_to_host_u32 (mp->domain_index));
1792   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1793   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1794   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1795   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1796   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1797   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1798   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1799   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1800   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1801   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1802   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1803   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1804   vat_json_object_add_uint (node, "flags", mp->flags);
1805   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1806   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1807 }
1808
1809 static void vl_api_map_domain_details_t_handler
1810   (vl_api_map_domain_details_t * mp)
1811 {
1812   vat_main_t *vam = &vat_main;
1813
1814   if (mp->is_translation)
1815     {
1816       fformat (vam->ofp,
1817                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1818                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1819                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1820                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1821                clib_net_to_host_u32 (mp->domain_index));
1822     }
1823   else
1824     {
1825       fformat (vam->ofp,
1826                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1827                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1828                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1829                format_ip6_address, mp->ip6_src,
1830                clib_net_to_host_u32 (mp->domain_index));
1831     }
1832   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1833            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1834            mp->is_translation ? "map-t" : "");
1835 }
1836
1837 static void vl_api_map_rule_details_t_handler_json
1838   (vl_api_map_rule_details_t * mp)
1839 {
1840   struct in6_addr ip6;
1841   vat_json_node_t *node = NULL;
1842   vat_main_t *vam = &vat_main;
1843
1844   if (VAT_JSON_ARRAY != vam->json_tree.type)
1845     {
1846       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1847       vat_json_init_array (&vam->json_tree);
1848     }
1849
1850   node = vat_json_array_add (&vam->json_tree);
1851   vat_json_init_object (node);
1852
1853   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1854   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1855   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1856 }
1857
1858 static void
1859 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1860 {
1861   vat_main_t *vam = &vat_main;
1862   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1863            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1864 }
1865
1866 static void
1867 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1868 {
1869   vat_main_t *vam = &vat_main;
1870   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1871           "router_addr %U host_mac %U\n",
1872           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1873           format_ip4_address, &mp->host_address,
1874           format_ip4_address, &mp->router_address,
1875           format_ethernet_address, mp->host_mac);
1876 }
1877
1878 static void vl_api_dhcp_compl_event_t_handler_json
1879   (vl_api_dhcp_compl_event_t * mp)
1880 {
1881   /* JSON output not supported */
1882 }
1883
1884 static void
1885 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1886                               u32 counter)
1887 {
1888   vat_main_t *vam = &vat_main;
1889   static u64 default_counter = 0;
1890
1891   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1892                            NULL);
1893   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1894                            sw_if_index, default_counter);
1895   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1896 }
1897
1898 static void
1899 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1900                                 interface_counter_t counter)
1901 {
1902   vat_main_t *vam = &vat_main;
1903   static interface_counter_t default_counter = { 0, };
1904
1905   vec_validate_init_empty (vam->combined_interface_counters,
1906                            vnet_counter_type, NULL);
1907   vec_validate_init_empty (vam->combined_interface_counters
1908                            [vnet_counter_type], sw_if_index, default_counter);
1909   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1910 }
1911
1912 static void vl_api_vnet_interface_counters_t_handler
1913   (vl_api_vnet_interface_counters_t * mp)
1914 {
1915   /* not supported */
1916 }
1917
1918 static void vl_api_vnet_interface_counters_t_handler_json
1919   (vl_api_vnet_interface_counters_t * mp)
1920 {
1921   interface_counter_t counter;
1922   vlib_counter_t *v;
1923   u64 *v_packets;
1924   u64 packets;
1925   u32 count;
1926   u32 first_sw_if_index;
1927   int i;
1928
1929   count = ntohl (mp->count);
1930   first_sw_if_index = ntohl (mp->first_sw_if_index);
1931
1932   if (!mp->is_combined)
1933     {
1934       v_packets = (u64 *) & mp->data;
1935       for (i = 0; i < count; i++)
1936         {
1937           packets =
1938             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1939           set_simple_interface_counter (mp->vnet_counter_type,
1940                                         first_sw_if_index + i, packets);
1941           v_packets++;
1942         }
1943     }
1944   else
1945     {
1946       v = (vlib_counter_t *) & mp->data;
1947       for (i = 0; i < count; i++)
1948         {
1949           counter.packets =
1950             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1951           counter.bytes =
1952             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1953           set_combined_interface_counter (mp->vnet_counter_type,
1954                                           first_sw_if_index + i, counter);
1955           v++;
1956         }
1957     }
1958 }
1959
1960 static u32
1961 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1962 {
1963   vat_main_t *vam = &vat_main;
1964   u32 i;
1965
1966   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1967     {
1968       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1969         {
1970           return i;
1971         }
1972     }
1973   return ~0;
1974 }
1975
1976 static u32
1977 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1978 {
1979   vat_main_t *vam = &vat_main;
1980   u32 i;
1981
1982   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1983     {
1984       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1985         {
1986           return i;
1987         }
1988     }
1989   return ~0;
1990 }
1991
1992 static void vl_api_vnet_ip4_fib_counters_t_handler
1993   (vl_api_vnet_ip4_fib_counters_t * mp)
1994 {
1995   /* not supported */
1996 }
1997
1998 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1999   (vl_api_vnet_ip4_fib_counters_t * mp)
2000 {
2001   vat_main_t *vam = &vat_main;
2002   vl_api_ip4_fib_counter_t *v;
2003   ip4_fib_counter_t *counter;
2004   struct in_addr ip4;
2005   u32 vrf_id;
2006   u32 vrf_index;
2007   u32 count;
2008   int i;
2009
2010   vrf_id = ntohl (mp->vrf_id);
2011   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2012   if (~0 == vrf_index)
2013     {
2014       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2015       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2016       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2017       vec_validate (vam->ip4_fib_counters, vrf_index);
2018       vam->ip4_fib_counters[vrf_index] = NULL;
2019     }
2020
2021   vec_free (vam->ip4_fib_counters[vrf_index]);
2022   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2023   count = ntohl (mp->count);
2024   for (i = 0; i < count; i++)
2025     {
2026       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2027       counter = &vam->ip4_fib_counters[vrf_index][i];
2028       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2029       counter->address = ip4;
2030       counter->address_length = v->address_length;
2031       counter->packets = clib_net_to_host_u64 (v->packets);
2032       counter->bytes = clib_net_to_host_u64 (v->bytes);
2033       v++;
2034     }
2035 }
2036
2037 static void vl_api_vnet_ip6_fib_counters_t_handler
2038   (vl_api_vnet_ip6_fib_counters_t * mp)
2039 {
2040   /* not supported */
2041 }
2042
2043 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2044   (vl_api_vnet_ip6_fib_counters_t * mp)
2045 {
2046   vat_main_t *vam = &vat_main;
2047   vl_api_ip6_fib_counter_t *v;
2048   ip6_fib_counter_t *counter;
2049   struct in6_addr ip6;
2050   u32 vrf_id;
2051   u32 vrf_index;
2052   u32 count;
2053   int i;
2054
2055   vrf_id = ntohl (mp->vrf_id);
2056   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2057   if (~0 == vrf_index)
2058     {
2059       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2060       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2061       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2062       vec_validate (vam->ip6_fib_counters, vrf_index);
2063       vam->ip6_fib_counters[vrf_index] = NULL;
2064     }
2065
2066   vec_free (vam->ip6_fib_counters[vrf_index]);
2067   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2068   count = ntohl (mp->count);
2069   for (i = 0; i < count; i++)
2070     {
2071       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2072       counter = &vam->ip6_fib_counters[vrf_index][i];
2073       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2074       counter->address = ip6;
2075       counter->address_length = v->address_length;
2076       counter->packets = clib_net_to_host_u64 (v->packets);
2077       counter->bytes = clib_net_to_host_u64 (v->bytes);
2078       v++;
2079     }
2080 }
2081
2082 static void vl_api_get_first_msg_id_reply_t_handler
2083   (vl_api_get_first_msg_id_reply_t * mp)
2084 {
2085   vat_main_t *vam = &vat_main;
2086   i32 retval = ntohl (mp->retval);
2087
2088   if (vam->async_mode)
2089     {
2090       vam->async_errors += (retval < 0);
2091     }
2092   else
2093     {
2094       vam->retval = retval;
2095       vam->result_ready = 1;
2096     }
2097   if (retval >= 0)
2098     {
2099       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2100     }
2101 }
2102
2103 static void vl_api_get_first_msg_id_reply_t_handler_json
2104   (vl_api_get_first_msg_id_reply_t * mp)
2105 {
2106   vat_main_t *vam = &vat_main;
2107   vat_json_node_t node;
2108
2109   vat_json_init_object (&node);
2110   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2111   vat_json_object_add_uint (&node, "first_msg_id",
2112                             (uint) ntohs (mp->first_msg_id));
2113
2114   vat_json_print (vam->ofp, &node);
2115   vat_json_free (&node);
2116
2117   vam->retval = ntohl (mp->retval);
2118   vam->result_ready = 1;
2119 }
2120
2121 static void vl_api_get_node_graph_reply_t_handler
2122   (vl_api_get_node_graph_reply_t * mp)
2123 {
2124   vat_main_t *vam = &vat_main;
2125   api_main_t *am = &api_main;
2126   i32 retval = ntohl (mp->retval);
2127   u8 *pvt_copy, *reply;
2128   void *oldheap;
2129   vlib_node_t *node;
2130   int i;
2131
2132   if (vam->async_mode)
2133     {
2134       vam->async_errors += (retval < 0);
2135     }
2136   else
2137     {
2138       vam->retval = retval;
2139       vam->result_ready = 1;
2140     }
2141
2142   /* "Should never happen..." */
2143   if (retval != 0)
2144     return;
2145
2146   reply = (u8 *) (mp->reply_in_shmem);
2147   pvt_copy = vec_dup (reply);
2148
2149   /* Toss the shared-memory original... */
2150   pthread_mutex_lock (&am->vlib_rp->mutex);
2151   oldheap = svm_push_data_heap (am->vlib_rp);
2152
2153   vec_free (reply);
2154
2155   svm_pop_heap (oldheap);
2156   pthread_mutex_unlock (&am->vlib_rp->mutex);
2157
2158   if (vam->graph_nodes)
2159     {
2160       hash_free (vam->graph_node_index_by_name);
2161
2162       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2163         {
2164           node = vam->graph_nodes[i];
2165           vec_free (node->name);
2166           vec_free (node->next_nodes);
2167           vec_free (node);
2168         }
2169       vec_free (vam->graph_nodes);
2170     }
2171
2172   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2173   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2174   vec_free (pvt_copy);
2175
2176   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2177     {
2178       node = vam->graph_nodes[i];
2179       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2180     }
2181 }
2182
2183 static void vl_api_get_node_graph_reply_t_handler_json
2184   (vl_api_get_node_graph_reply_t * mp)
2185 {
2186   vat_main_t *vam = &vat_main;
2187   api_main_t *am = &api_main;
2188   void *oldheap;
2189   vat_json_node_t node;
2190   u8 *reply;
2191
2192   /* $$$$ make this real? */
2193   vat_json_init_object (&node);
2194   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2195   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2196
2197   reply = (u8 *) (mp->reply_in_shmem);
2198
2199   /* Toss the shared-memory original... */
2200   pthread_mutex_lock (&am->vlib_rp->mutex);
2201   oldheap = svm_push_data_heap (am->vlib_rp);
2202
2203   vec_free (reply);
2204
2205   svm_pop_heap (oldheap);
2206   pthread_mutex_unlock (&am->vlib_rp->mutex);
2207
2208   vat_json_print (vam->ofp, &node);
2209   vat_json_free (&node);
2210
2211   vam->retval = ntohl (mp->retval);
2212   vam->result_ready = 1;
2213 }
2214
2215 static void
2216 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2217 {
2218   vat_main_t *vam = &vat_main;
2219   u8 *s = 0;
2220
2221   if (mp->local)
2222     {
2223       s = format (s, "%=16d%=16d%=16d\n",
2224                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2225     }
2226   else
2227     {
2228       s = format (s, "%=16U%=16d%=16d\n",
2229                   mp->is_ipv6 ? format_ip6_address :
2230                   format_ip4_address,
2231                   mp->ip_address, mp->priority, mp->weight);
2232     }
2233
2234   fformat (vam->ofp, "%v", s);
2235   vec_free (s);
2236 }
2237
2238 static void
2239 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2240                                             mp)
2241 {
2242   vat_main_t *vam = &vat_main;
2243   vat_json_node_t *node = NULL;
2244   struct in6_addr ip6;
2245   struct in_addr ip4;
2246
2247   if (VAT_JSON_ARRAY != vam->json_tree.type)
2248     {
2249       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2250       vat_json_init_array (&vam->json_tree);
2251     }
2252   node = vat_json_array_add (&vam->json_tree);
2253   vat_json_init_object (node);
2254
2255   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2256   vat_json_object_add_uint (node, "priority", mp->priority);
2257   vat_json_object_add_uint (node, "weight", mp->weight);
2258
2259   if (mp->local)
2260     vat_json_object_add_uint (node, "sw_if_index",
2261                               clib_net_to_host_u32 (mp->sw_if_index));
2262   else
2263     {
2264       if (mp->is_ipv6)
2265         {
2266           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2267           vat_json_object_add_ip6 (node, "address", ip6);
2268         }
2269       else
2270         {
2271           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2272           vat_json_object_add_ip4 (node, "address", ip4);
2273         }
2274     }
2275 }
2276
2277 static void
2278 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2279                                            mp)
2280 {
2281   vat_main_t *vam = &vat_main;
2282   u8 *ls_name = 0;
2283
2284   ls_name = format (0, "%s", mp->ls_name);
2285
2286   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2287            ls_name);
2288   vec_free (ls_name);
2289 }
2290
2291 static void
2292   vl_api_lisp_locator_set_details_t_handler_json
2293   (vl_api_lisp_locator_set_details_t * mp)
2294 {
2295   vat_main_t *vam = &vat_main;
2296   vat_json_node_t *node = 0;
2297   u8 *ls_name = 0;
2298
2299   ls_name = format (0, "%s", mp->ls_name);
2300   vec_add1 (ls_name, 0);
2301
2302   if (VAT_JSON_ARRAY != vam->json_tree.type)
2303     {
2304       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2305       vat_json_init_array (&vam->json_tree);
2306     }
2307   node = vat_json_array_add (&vam->json_tree);
2308
2309   vat_json_init_object (node);
2310   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2311   vat_json_object_add_uint (node, "ls_index",
2312                             clib_net_to_host_u32 (mp->ls_index));
2313   vec_free (ls_name);
2314 }
2315
2316 static u8 *
2317 format_lisp_flat_eid (u8 * s, va_list * args)
2318 {
2319   u32 type = va_arg (*args, u32);
2320   u8 *eid = va_arg (*args, u8 *);
2321   u32 eid_len = va_arg (*args, u32);
2322
2323   switch (type)
2324     {
2325     case 0:
2326       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2327     case 1:
2328       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2329     case 2:
2330       return format (s, "%U", format_ethernet_address, eid);
2331     }
2332   return 0;
2333 }
2334
2335 static u8 *
2336 format_lisp_eid_vat (u8 * s, va_list * args)
2337 {
2338   u32 type = va_arg (*args, u32);
2339   u8 *eid = va_arg (*args, u8 *);
2340   u32 eid_len = va_arg (*args, u32);
2341   u8 *seid = va_arg (*args, u8 *);
2342   u32 seid_len = va_arg (*args, u32);
2343   u32 is_src_dst = va_arg (*args, u32);
2344
2345   if (is_src_dst)
2346     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2347
2348   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2349
2350   return s;
2351 }
2352
2353 static void
2354 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2355 {
2356   vat_main_t *vam = &vat_main;
2357   u8 *s = 0, *eid = 0;
2358
2359   if (~0 == mp->locator_set_index)
2360     s = format (0, "action: %d", mp->action);
2361   else
2362     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2363
2364   eid = format (0, "%U", format_lisp_eid_vat,
2365                 mp->eid_type,
2366                 mp->eid,
2367                 mp->eid_prefix_len,
2368                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2369   vec_add1 (eid, 0);
2370
2371   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2372            clib_net_to_host_u32 (mp->vni),
2373            eid,
2374            mp->is_local ? "local" : "remote",
2375            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2376   vec_free (s);
2377   vec_free (eid);
2378 }
2379
2380 static void
2381 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2382                                               * mp)
2383 {
2384   vat_main_t *vam = &vat_main;
2385   vat_json_node_t *node = 0;
2386   u8 *eid = 0;
2387
2388   if (VAT_JSON_ARRAY != vam->json_tree.type)
2389     {
2390       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2391       vat_json_init_array (&vam->json_tree);
2392     }
2393   node = vat_json_array_add (&vam->json_tree);
2394
2395   vat_json_init_object (node);
2396   if (~0 == mp->locator_set_index)
2397     vat_json_object_add_uint (node, "action", mp->action);
2398   else
2399     vat_json_object_add_uint (node, "locator_set_index",
2400                               clib_net_to_host_u32 (mp->locator_set_index));
2401
2402   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2403   eid = format (0, "%U", format_lisp_eid_vat,
2404                 mp->eid_type,
2405                 mp->eid,
2406                 mp->eid_prefix_len,
2407                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2408   vec_add1 (eid, 0);
2409   vat_json_object_add_string_copy (node, "eid", eid);
2410   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2411   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2412   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2413   vec_free (eid);
2414 }
2415
2416 static void
2417   vl_api_lisp_eid_table_map_details_t_handler
2418   (vl_api_lisp_eid_table_map_details_t * mp)
2419 {
2420   vat_main_t *vam = &vat_main;
2421
2422   u8 *line = format (0, "%=10d%=10d",
2423                      clib_net_to_host_u32 (mp->vni),
2424                      clib_net_to_host_u32 (mp->dp_table));
2425   fformat (vam->ofp, "%v\n", line);
2426   vec_free (line);
2427 }
2428
2429 static void
2430   vl_api_lisp_eid_table_map_details_t_handler_json
2431   (vl_api_lisp_eid_table_map_details_t * mp)
2432 {
2433   vat_main_t *vam = &vat_main;
2434   vat_json_node_t *node = NULL;
2435
2436   if (VAT_JSON_ARRAY != vam->json_tree.type)
2437     {
2438       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2439       vat_json_init_array (&vam->json_tree);
2440     }
2441   node = vat_json_array_add (&vam->json_tree);
2442   vat_json_init_object (node);
2443   vat_json_object_add_uint (node, "dp_table",
2444                             clib_net_to_host_u32 (mp->dp_table));
2445   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2446 }
2447
2448 static void
2449   vl_api_lisp_eid_table_vni_details_t_handler
2450   (vl_api_lisp_eid_table_vni_details_t * mp)
2451 {
2452   vat_main_t *vam = &vat_main;
2453
2454   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2455   fformat (vam->ofp, "%v\n", line);
2456   vec_free (line);
2457 }
2458
2459 static void
2460   vl_api_lisp_eid_table_vni_details_t_handler_json
2461   (vl_api_lisp_eid_table_vni_details_t * mp)
2462 {
2463   vat_main_t *vam = &vat_main;
2464   vat_json_node_t *node = NULL;
2465
2466   if (VAT_JSON_ARRAY != vam->json_tree.type)
2467     {
2468       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2469       vat_json_init_array (&vam->json_tree);
2470     }
2471   node = vat_json_array_add (&vam->json_tree);
2472   vat_json_init_object (node);
2473   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2474 }
2475
2476 static u8 *
2477 format_decap_next (u8 * s, va_list * args)
2478 {
2479   u32 next_index = va_arg (*args, u32);
2480
2481   switch (next_index)
2482     {
2483     case LISP_GPE_INPUT_NEXT_DROP:
2484       return format (s, "drop");
2485     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2486       return format (s, "ip4");
2487     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2488       return format (s, "ip6");
2489     default:
2490       return format (s, "unknown %d", next_index);
2491     }
2492   return s;
2493 }
2494
2495 static void
2496 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2497                                           mp)
2498 {
2499   vat_main_t *vam = &vat_main;
2500   u8 *iid_str;
2501   u8 *flag_str = NULL;
2502
2503   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2504
2505 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2506   foreach_lisp_gpe_flag_bit;
2507 #undef _
2508
2509   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2510            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2511            mp->tunnels,
2512            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2513            mp->source_ip,
2514            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2515            mp->destination_ip,
2516            ntohl (mp->encap_fib_id),
2517            ntohl (mp->decap_fib_id),
2518            format_decap_next, ntohl (mp->dcap_next),
2519            mp->ver_res >> 6,
2520            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2521
2522   vec_free (iid_str);
2523 }
2524
2525 static void
2526   vl_api_lisp_gpe_tunnel_details_t_handler_json
2527   (vl_api_lisp_gpe_tunnel_details_t * mp)
2528 {
2529   vat_main_t *vam = &vat_main;
2530   vat_json_node_t *node = NULL;
2531   struct in6_addr ip6;
2532   struct in_addr ip4;
2533   u8 *next_decap_str;
2534
2535   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2536
2537   if (VAT_JSON_ARRAY != vam->json_tree.type)
2538     {
2539       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2540       vat_json_init_array (&vam->json_tree);
2541     }
2542   node = vat_json_array_add (&vam->json_tree);
2543
2544   vat_json_init_object (node);
2545   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2546   if (mp->is_ipv6)
2547     {
2548       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2549       vat_json_object_add_ip6 (node, "source address", ip6);
2550       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2551       vat_json_object_add_ip6 (node, "destination address", ip6);
2552     }
2553   else
2554     {
2555       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2556       vat_json_object_add_ip4 (node, "source address", ip4);
2557       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2558       vat_json_object_add_ip4 (node, "destination address", ip4);
2559     }
2560   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2561   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2562   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2563   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2564   vat_json_object_add_uint (node, "flags", mp->flags);
2565   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2566   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2567   vat_json_object_add_uint (node, "res", mp->res);
2568   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2569
2570   vec_free (next_decap_str);
2571 }
2572
2573 static void
2574   vl_api_lisp_adjacencies_get_reply_t_handler
2575   (vl_api_lisp_adjacencies_get_reply_t * mp)
2576 {
2577   vat_main_t *vam = &vat_main;
2578   u32 i, n;
2579   int retval = clib_net_to_host_u32 (mp->retval);
2580   vl_api_lisp_adjacency_t *a;
2581
2582   if (retval)
2583     goto end;
2584
2585   n = clib_net_to_host_u32 (mp->count);
2586
2587   for (i = 0; i < n; i++)
2588     {
2589       a = &mp->adjacencies[i];
2590       fformat (vam->ofp, "%U %40U\n",
2591                format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2592                format_lisp_flat_eid, a->eid_type, a->reid,
2593                a->reid_prefix_len);
2594     }
2595
2596 end:
2597   vam->retval = retval;
2598   vam->result_ready = 1;
2599 }
2600
2601 static void
2602   vl_api_lisp_adjacencies_get_reply_t_handler_json
2603   (vl_api_lisp_adjacencies_get_reply_t * mp)
2604 {
2605   u8 *s = 0;
2606   vat_main_t *vam = &vat_main;
2607   vat_json_node_t *e = 0, root;
2608   u32 i, n;
2609   int retval = clib_net_to_host_u32 (mp->retval);
2610   vl_api_lisp_adjacency_t *a;
2611
2612   if (retval)
2613     goto end;
2614
2615   n = clib_net_to_host_u32 (mp->count);
2616   vat_json_init_array (&root);
2617
2618   for (i = 0; i < n; i++)
2619     {
2620       e = vat_json_array_add (&root);
2621       a = &mp->adjacencies[i];
2622
2623       vat_json_init_object (e);
2624       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2625                   a->leid_prefix_len);
2626       vec_add1 (s, 0);
2627       vat_json_object_add_string_copy (e, "leid", s);
2628       vec_free (s);
2629
2630       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2631                   a->reid_prefix_len);
2632       vec_add1 (s, 0);
2633       vat_json_object_add_string_copy (e, "reid", s);
2634       vec_free (s);
2635     }
2636
2637   vat_json_print (vam->ofp, &root);
2638   vat_json_free (&root);
2639
2640 end:
2641   vam->retval = retval;
2642   vam->result_ready = 1;
2643 }
2644
2645 static void
2646 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2647                                             * mp)
2648 {
2649   vat_main_t *vam = &vat_main;
2650
2651   fformat (vam->ofp, "%=20U\n",
2652            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2653            mp->ip_address);
2654 }
2655
2656 static void
2657   vl_api_lisp_map_resolver_details_t_handler_json
2658   (vl_api_lisp_map_resolver_details_t * mp)
2659 {
2660   vat_main_t *vam = &vat_main;
2661   vat_json_node_t *node = NULL;
2662   struct in6_addr ip6;
2663   struct in_addr ip4;
2664
2665   if (VAT_JSON_ARRAY != vam->json_tree.type)
2666     {
2667       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2668       vat_json_init_array (&vam->json_tree);
2669     }
2670   node = vat_json_array_add (&vam->json_tree);
2671
2672   vat_json_init_object (node);
2673   if (mp->is_ipv6)
2674     {
2675       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2676       vat_json_object_add_ip6 (node, "map resolver", ip6);
2677     }
2678   else
2679     {
2680       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2681       vat_json_object_add_ip4 (node, "map resolver", ip4);
2682     }
2683 }
2684
2685 static void
2686   vl_api_show_lisp_status_reply_t_handler
2687   (vl_api_show_lisp_status_reply_t * mp)
2688 {
2689   vat_main_t *vam = &vat_main;
2690   i32 retval = ntohl (mp->retval);
2691
2692   if (0 <= retval)
2693     {
2694       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2695                mp->feature_status ? "enabled" : "disabled",
2696                mp->gpe_status ? "enabled" : "disabled");
2697     }
2698
2699   vam->retval = retval;
2700   vam->result_ready = 1;
2701 }
2702
2703 static void
2704   vl_api_show_lisp_status_reply_t_handler_json
2705   (vl_api_show_lisp_status_reply_t * mp)
2706 {
2707   vat_main_t *vam = &vat_main;
2708   vat_json_node_t node;
2709   u8 *gpe_status = NULL;
2710   u8 *feature_status = NULL;
2711
2712   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2713   feature_status = format (0, "%s",
2714                            mp->feature_status ? "enabled" : "disabled");
2715   vec_add1 (gpe_status, 0);
2716   vec_add1 (feature_status, 0);
2717
2718   vat_json_init_object (&node);
2719   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2720   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2721
2722   vec_free (gpe_status);
2723   vec_free (feature_status);
2724
2725   vat_json_print (vam->ofp, &node);
2726   vat_json_free (&node);
2727
2728   vam->retval = ntohl (mp->retval);
2729   vam->result_ready = 1;
2730 }
2731
2732 static void
2733   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2734   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2735 {
2736   vat_main_t *vam = &vat_main;
2737   i32 retval = ntohl (mp->retval);
2738
2739   if (retval >= 0)
2740     {
2741       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2742     }
2743
2744   vam->retval = retval;
2745   vam->result_ready = 1;
2746 }
2747
2748 static void
2749   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2750   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2751 {
2752   vat_main_t *vam = &vat_main;
2753   vat_json_node_t *node = NULL;
2754
2755   if (VAT_JSON_ARRAY != vam->json_tree.type)
2756     {
2757       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2758       vat_json_init_array (&vam->json_tree);
2759     }
2760   node = vat_json_array_add (&vam->json_tree);
2761
2762   vat_json_init_object (node);
2763   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2764
2765   vat_json_print (vam->ofp, node);
2766   vat_json_free (node);
2767
2768   vam->retval = ntohl (mp->retval);
2769   vam->result_ready = 1;
2770 }
2771
2772 static u8 *
2773 format_lisp_map_request_mode (u8 * s, va_list * args)
2774 {
2775   u32 mode = va_arg (*args, u32);
2776
2777   switch (mode)
2778     {
2779     case 0:
2780       return format (0, "dst-only");
2781     case 1:
2782       return format (0, "src-dst");
2783     }
2784   return 0;
2785 }
2786
2787 static void
2788   vl_api_show_lisp_map_request_mode_reply_t_handler
2789   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2790 {
2791   vat_main_t *vam = &vat_main;
2792   i32 retval = ntohl (mp->retval);
2793
2794   if (0 <= retval)
2795     {
2796       u32 mode = mp->mode;
2797       fformat (vam->ofp, "map_request_mode: %U\n",
2798                format_lisp_map_request_mode, mode);
2799     }
2800
2801   vam->retval = retval;
2802   vam->result_ready = 1;
2803 }
2804
2805 static void
2806   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2807   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2808 {
2809   vat_main_t *vam = &vat_main;
2810   vat_json_node_t node;
2811   u8 *s = 0;
2812   u32 mode;
2813
2814   mode = mp->mode;
2815   s = format (0, "%U", format_lisp_map_request_mode, mode);
2816   vec_add1 (s, 0);
2817
2818   vat_json_init_object (&node);
2819   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2820   vat_json_print (vam->ofp, &node);
2821   vat_json_free (&node);
2822
2823   vec_free (s);
2824   vam->retval = ntohl (mp->retval);
2825   vam->result_ready = 1;
2826 }
2827
2828 static void
2829 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2830 {
2831   vat_main_t *vam = &vat_main;
2832   i32 retval = ntohl (mp->retval);
2833
2834   if (0 <= retval)
2835     {
2836       fformat (vam->ofp, "%-20s%-16s\n",
2837                mp->status ? "enabled" : "disabled",
2838                mp->status ? (char *) mp->locator_set_name : "");
2839     }
2840
2841   vam->retval = retval;
2842   vam->result_ready = 1;
2843 }
2844
2845 static void
2846 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2847                                             mp)
2848 {
2849   vat_main_t *vam = &vat_main;
2850   vat_json_node_t node;
2851   u8 *status = 0;
2852
2853   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2854   vec_add1 (status, 0);
2855
2856   vat_json_init_object (&node);
2857   vat_json_object_add_string_copy (&node, "status", status);
2858   if (mp->status)
2859     {
2860       vat_json_object_add_string_copy (&node, "locator_set",
2861                                        mp->locator_set_name);
2862     }
2863
2864   vec_free (status);
2865
2866   vat_json_print (vam->ofp, &node);
2867   vat_json_free (&node);
2868
2869   vam->retval = ntohl (mp->retval);
2870   vam->result_ready = 1;
2871 }
2872
2873 static u8 *
2874 format_policer_type (u8 * s, va_list * va)
2875 {
2876   u32 i = va_arg (*va, u32);
2877
2878   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2879     s = format (s, "1r2c");
2880   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2881     s = format (s, "1r3c");
2882   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2883     s = format (s, "2r3c-2698");
2884   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2885     s = format (s, "2r3c-4115");
2886   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2887     s = format (s, "2r3c-mef5cf1");
2888   else
2889     s = format (s, "ILLEGAL");
2890   return s;
2891 }
2892
2893 static u8 *
2894 format_policer_rate_type (u8 * s, va_list * va)
2895 {
2896   u32 i = va_arg (*va, u32);
2897
2898   if (i == SSE2_QOS_RATE_KBPS)
2899     s = format (s, "kbps");
2900   else if (i == SSE2_QOS_RATE_PPS)
2901     s = format (s, "pps");
2902   else
2903     s = format (s, "ILLEGAL");
2904   return s;
2905 }
2906
2907 static u8 *
2908 format_policer_round_type (u8 * s, va_list * va)
2909 {
2910   u32 i = va_arg (*va, u32);
2911
2912   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2913     s = format (s, "closest");
2914   else if (i == SSE2_QOS_ROUND_TO_UP)
2915     s = format (s, "up");
2916   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2917     s = format (s, "down");
2918   else
2919     s = format (s, "ILLEGAL");
2920   return s;
2921 }
2922
2923 static u8 *
2924 format_policer_action_type (u8 * s, va_list * va)
2925 {
2926   u32 i = va_arg (*va, u32);
2927
2928   if (i == SSE2_QOS_ACTION_DROP)
2929     s = format (s, "drop");
2930   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2931     s = format (s, "transmit");
2932   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2933     s = format (s, "mark-and-transmit");
2934   else
2935     s = format (s, "ILLEGAL");
2936   return s;
2937 }
2938
2939 static u8 *
2940 format_dscp (u8 * s, va_list * va)
2941 {
2942   u32 i = va_arg (*va, u32);
2943   char *t = 0;
2944
2945   switch (i)
2946     {
2947 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2948       foreach_vnet_dscp
2949 #undef _
2950     default:
2951       return format (s, "ILLEGAL");
2952     }
2953   s = format (s, "%s", t);
2954   return s;
2955 }
2956
2957 static void
2958 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2959 {
2960   vat_main_t *vam = &vat_main;
2961   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2962
2963   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2964     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2965   else
2966     conform_dscp_str = format (0, "");
2967
2968   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2969     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2970   else
2971     exceed_dscp_str = format (0, "");
2972
2973   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2974     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2975   else
2976     violate_dscp_str = format (0, "");
2977
2978   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2979            "rate type %U, round type %U, %s rate, %s color-aware, "
2980            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2981            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2982            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2983            mp->name,
2984            format_policer_type, mp->type,
2985            ntohl (mp->cir),
2986            ntohl (mp->eir),
2987            clib_net_to_host_u64 (mp->cb),
2988            clib_net_to_host_u64 (mp->eb),
2989            format_policer_rate_type, mp->rate_type,
2990            format_policer_round_type, mp->round_type,
2991            mp->single_rate ? "single" : "dual",
2992            mp->color_aware ? "is" : "not",
2993            ntohl (mp->cir_tokens_per_period),
2994            ntohl (mp->pir_tokens_per_period),
2995            ntohl (mp->scale),
2996            ntohl (mp->current_limit),
2997            ntohl (mp->current_bucket),
2998            ntohl (mp->extended_limit),
2999            ntohl (mp->extended_bucket),
3000            clib_net_to_host_u64 (mp->last_update_time),
3001            format_policer_action_type, mp->conform_action_type,
3002            conform_dscp_str,
3003            format_policer_action_type, mp->exceed_action_type,
3004            exceed_dscp_str,
3005            format_policer_action_type, mp->violate_action_type,
3006            violate_dscp_str);
3007
3008   vec_free (conform_dscp_str);
3009   vec_free (exceed_dscp_str);
3010   vec_free (violate_dscp_str);
3011 }
3012
3013 static void vl_api_policer_details_t_handler_json
3014   (vl_api_policer_details_t * mp)
3015 {
3016   vat_main_t *vam = &vat_main;
3017   vat_json_node_t *node;
3018   u8 *rate_type_str, *round_type_str, *type_str;
3019   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3020
3021   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3022   round_type_str =
3023     format (0, "%U", format_policer_round_type, mp->round_type);
3024   type_str = format (0, "%U", format_policer_type, mp->type);
3025   conform_action_str = format (0, "%U", format_policer_action_type,
3026                                mp->conform_action_type);
3027   exceed_action_str = format (0, "%U", format_policer_action_type,
3028                               mp->exceed_action_type);
3029   violate_action_str = format (0, "%U", format_policer_action_type,
3030                                mp->violate_action_type);
3031
3032   if (VAT_JSON_ARRAY != vam->json_tree.type)
3033     {
3034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3035       vat_json_init_array (&vam->json_tree);
3036     }
3037   node = vat_json_array_add (&vam->json_tree);
3038
3039   vat_json_init_object (node);
3040   vat_json_object_add_string_copy (node, "name", mp->name);
3041   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3042   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3043   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3044   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3045   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3046   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3047   vat_json_object_add_string_copy (node, "type", type_str);
3048   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3049   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3050   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3051   vat_json_object_add_uint (node, "cir_tokens_per_period",
3052                             ntohl (mp->cir_tokens_per_period));
3053   vat_json_object_add_uint (node, "eir_tokens_per_period",
3054                             ntohl (mp->pir_tokens_per_period));
3055   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3056   vat_json_object_add_uint (node, "current_bucket",
3057                             ntohl (mp->current_bucket));
3058   vat_json_object_add_uint (node, "extended_limit",
3059                             ntohl (mp->extended_limit));
3060   vat_json_object_add_uint (node, "extended_bucket",
3061                             ntohl (mp->extended_bucket));
3062   vat_json_object_add_uint (node, "last_update_time",
3063                             ntohl (mp->last_update_time));
3064   vat_json_object_add_string_copy (node, "conform_action",
3065                                    conform_action_str);
3066   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3067     {
3068       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3069       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3070       vec_free (dscp_str);
3071     }
3072   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3073   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3074     {
3075       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3076       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3077       vec_free (dscp_str);
3078     }
3079   vat_json_object_add_string_copy (node, "violate_action",
3080                                    violate_action_str);
3081   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3082     {
3083       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3084       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3085       vec_free (dscp_str);
3086     }
3087
3088   vec_free (rate_type_str);
3089   vec_free (round_type_str);
3090   vec_free (type_str);
3091   vec_free (conform_action_str);
3092   vec_free (exceed_action_str);
3093   vec_free (violate_action_str);
3094 }
3095
3096 static void
3097 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3098                                            mp)
3099 {
3100   vat_main_t *vam = &vat_main;
3101   int i, count = ntohl (mp->count);
3102
3103   if (count > 0)
3104     fformat (vam->ofp, "classify table ids (%d) : ", count);
3105   for (i = 0; i < count; i++)
3106     {
3107       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3108       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3109     }
3110   vam->retval = ntohl (mp->retval);
3111   vam->result_ready = 1;
3112 }
3113
3114 static void
3115   vl_api_classify_table_ids_reply_t_handler_json
3116   (vl_api_classify_table_ids_reply_t * mp)
3117 {
3118   vat_main_t *vam = &vat_main;
3119   int i, count = ntohl (mp->count);
3120
3121   if (count > 0)
3122     {
3123       vat_json_node_t node;
3124
3125       vat_json_init_object (&node);
3126       for (i = 0; i < count; i++)
3127         {
3128           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3129         }
3130       vat_json_print (vam->ofp, &node);
3131       vat_json_free (&node);
3132     }
3133   vam->retval = ntohl (mp->retval);
3134   vam->result_ready = 1;
3135 }
3136
3137 static void
3138   vl_api_classify_table_by_interface_reply_t_handler
3139   (vl_api_classify_table_by_interface_reply_t * mp)
3140 {
3141   vat_main_t *vam = &vat_main;
3142   u32 table_id;
3143
3144   table_id = ntohl (mp->l2_table_id);
3145   if (table_id != ~0)
3146     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3147   else
3148     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3149   table_id = ntohl (mp->ip4_table_id);
3150   if (table_id != ~0)
3151     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3152   else
3153     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3154   table_id = ntohl (mp->ip6_table_id);
3155   if (table_id != ~0)
3156     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3157   else
3158     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3159   vam->retval = ntohl (mp->retval);
3160   vam->result_ready = 1;
3161 }
3162
3163 static void
3164   vl_api_classify_table_by_interface_reply_t_handler_json
3165   (vl_api_classify_table_by_interface_reply_t * mp)
3166 {
3167   vat_main_t *vam = &vat_main;
3168   vat_json_node_t node;
3169
3170   vat_json_init_object (&node);
3171
3172   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3173   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3174   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3175
3176   vat_json_print (vam->ofp, &node);
3177   vat_json_free (&node);
3178
3179   vam->retval = ntohl (mp->retval);
3180   vam->result_ready = 1;
3181 }
3182
3183 static void vl_api_policer_add_del_reply_t_handler
3184   (vl_api_policer_add_del_reply_t * mp)
3185 {
3186   vat_main_t *vam = &vat_main;
3187   i32 retval = ntohl (mp->retval);
3188   if (vam->async_mode)
3189     {
3190       vam->async_errors += (retval < 0);
3191     }
3192   else
3193     {
3194       vam->retval = retval;
3195       vam->result_ready = 1;
3196       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3197         /*
3198          * Note: this is just barely thread-safe, depends on
3199          * the main thread spinning waiting for an answer...
3200          */
3201         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3202     }
3203 }
3204
3205 static void vl_api_policer_add_del_reply_t_handler_json
3206   (vl_api_policer_add_del_reply_t * mp)
3207 {
3208   vat_main_t *vam = &vat_main;
3209   vat_json_node_t node;
3210
3211   vat_json_init_object (&node);
3212   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3213   vat_json_object_add_uint (&node, "policer_index",
3214                             ntohl (mp->policer_index));
3215
3216   vat_json_print (vam->ofp, &node);
3217   vat_json_free (&node);
3218
3219   vam->retval = ntohl (mp->retval);
3220   vam->result_ready = 1;
3221 }
3222
3223 /* Format hex dump. */
3224 u8 *
3225 format_hex_bytes (u8 * s, va_list * va)
3226 {
3227   u8 *bytes = va_arg (*va, u8 *);
3228   int n_bytes = va_arg (*va, int);
3229   uword i;
3230
3231   /* Print short or long form depending on byte count. */
3232   uword short_form = n_bytes <= 32;
3233   uword indent = format_get_indent (s);
3234
3235   if (n_bytes == 0)
3236     return s;
3237
3238   for (i = 0; i < n_bytes; i++)
3239     {
3240       if (!short_form && (i % 32) == 0)
3241         s = format (s, "%08x: ", i);
3242       s = format (s, "%02x", bytes[i]);
3243       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3244         s = format (s, "\n%U", format_white_space, indent);
3245     }
3246
3247   return s;
3248 }
3249
3250 static void
3251 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3252                                             * mp)
3253 {
3254   vat_main_t *vam = &vat_main;
3255   i32 retval = ntohl (mp->retval);
3256   if (retval == 0)
3257     {
3258       fformat (vam->ofp, "classify table info :\n");
3259       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3260                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3261                ntohl (mp->miss_next_index));
3262       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3263                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3264                ntohl (mp->match_n_vectors));
3265       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3266                ntohl (mp->mask_length));
3267     }
3268   vam->retval = retval;
3269   vam->result_ready = 1;
3270 }
3271
3272 static void
3273   vl_api_classify_table_info_reply_t_handler_json
3274   (vl_api_classify_table_info_reply_t * mp)
3275 {
3276   vat_main_t *vam = &vat_main;
3277   vat_json_node_t node;
3278
3279   i32 retval = ntohl (mp->retval);
3280   if (retval == 0)
3281     {
3282       vat_json_init_object (&node);
3283
3284       vat_json_object_add_int (&node, "sessions",
3285                                ntohl (mp->active_sessions));
3286       vat_json_object_add_int (&node, "nexttbl",
3287                                ntohl (mp->next_table_index));
3288       vat_json_object_add_int (&node, "nextnode",
3289                                ntohl (mp->miss_next_index));
3290       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3291       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3292       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3293       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3294                       ntohl (mp->mask_length), 0);
3295       vat_json_object_add_string_copy (&node, "mask", s);
3296
3297       vat_json_print (vam->ofp, &node);
3298       vat_json_free (&node);
3299     }
3300   vam->retval = ntohl (mp->retval);
3301   vam->result_ready = 1;
3302 }
3303
3304 static void
3305 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3306                                            mp)
3307 {
3308   vat_main_t *vam = &vat_main;
3309
3310   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3311            ntohl (mp->hit_next_index), ntohl (mp->advance),
3312            ntohl (mp->opaque_index));
3313   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3314            ntohl (mp->match_length));
3315 }
3316
3317 static void
3318   vl_api_classify_session_details_t_handler_json
3319   (vl_api_classify_session_details_t * mp)
3320 {
3321   vat_main_t *vam = &vat_main;
3322   vat_json_node_t *node = NULL;
3323
3324   if (VAT_JSON_ARRAY != vam->json_tree.type)
3325     {
3326       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3327       vat_json_init_array (&vam->json_tree);
3328     }
3329   node = vat_json_array_add (&vam->json_tree);
3330
3331   vat_json_init_object (node);
3332   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3333   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3334   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3335   u8 *s =
3336     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3337             0);
3338   vat_json_object_add_string_copy (node, "match", s);
3339 }
3340
3341 static void vl_api_pg_create_interface_reply_t_handler
3342   (vl_api_pg_create_interface_reply_t * mp)
3343 {
3344   vat_main_t *vam = &vat_main;
3345
3346   vam->retval = ntohl (mp->retval);
3347   vam->result_ready = 1;
3348 }
3349
3350 static void vl_api_pg_create_interface_reply_t_handler_json
3351   (vl_api_pg_create_interface_reply_t * mp)
3352 {
3353   vat_main_t *vam = &vat_main;
3354   vat_json_node_t node;
3355
3356   i32 retval = ntohl (mp->retval);
3357   if (retval == 0)
3358     {
3359       vat_json_init_object (&node);
3360
3361       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3362
3363       vat_json_print (vam->ofp, &node);
3364       vat_json_free (&node);
3365     }
3366   vam->retval = ntohl (mp->retval);
3367   vam->result_ready = 1;
3368 }
3369
3370 static void vl_api_policer_classify_details_t_handler
3371   (vl_api_policer_classify_details_t * mp)
3372 {
3373   vat_main_t *vam = &vat_main;
3374
3375   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3376            ntohl (mp->table_index));
3377 }
3378
3379 static void vl_api_policer_classify_details_t_handler_json
3380   (vl_api_policer_classify_details_t * mp)
3381 {
3382   vat_main_t *vam = &vat_main;
3383   vat_json_node_t *node;
3384
3385   if (VAT_JSON_ARRAY != vam->json_tree.type)
3386     {
3387       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3388       vat_json_init_array (&vam->json_tree);
3389     }
3390   node = vat_json_array_add (&vam->json_tree);
3391
3392   vat_json_init_object (node);
3393   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3394   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3395 }
3396
3397 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3398   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3399 {
3400   vat_main_t *vam = &vat_main;
3401   i32 retval = ntohl (mp->retval);
3402   if (vam->async_mode)
3403     {
3404       vam->async_errors += (retval < 0);
3405     }
3406   else
3407     {
3408       vam->retval = retval;
3409       vam->sw_if_index = ntohl (mp->sw_if_index);
3410       vam->result_ready = 1;
3411     }
3412 }
3413
3414 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3415   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3416 {
3417   vat_main_t *vam = &vat_main;
3418   vat_json_node_t node;
3419
3420   vat_json_init_object (&node);
3421   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3422   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3423
3424   vat_json_print (vam->ofp, &node);
3425   vat_json_free (&node);
3426
3427   vam->retval = ntohl (mp->retval);
3428   vam->result_ready = 1;
3429 }
3430
3431 static void vl_api_flow_classify_details_t_handler
3432   (vl_api_flow_classify_details_t * mp)
3433 {
3434   vat_main_t *vam = &vat_main;
3435
3436   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3437            ntohl (mp->table_index));
3438 }
3439
3440 static void vl_api_flow_classify_details_t_handler_json
3441   (vl_api_flow_classify_details_t * mp)
3442 {
3443   vat_main_t *vam = &vat_main;
3444   vat_json_node_t *node;
3445
3446   if (VAT_JSON_ARRAY != vam->json_tree.type)
3447     {
3448       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3449       vat_json_init_array (&vam->json_tree);
3450     }
3451   node = vat_json_array_add (&vam->json_tree);
3452
3453   vat_json_init_object (node);
3454   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3455   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3456 }
3457
3458
3459
3460 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3461 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3462 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3463 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3464 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3465 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3466
3467 /*
3468  * Generate boilerplate reply handlers, which
3469  * dig the return value out of the xxx_reply_t API message,
3470  * stick it into vam->retval, and set vam->result_ready
3471  *
3472  * Could also do this by pointing N message decode slots at
3473  * a single function, but that could break in subtle ways.
3474  */
3475
3476 #define foreach_standard_reply_retval_handler           \
3477 _(sw_interface_set_flags_reply)                         \
3478 _(sw_interface_add_del_address_reply)                   \
3479 _(sw_interface_set_table_reply)                         \
3480 _(sw_interface_set_mpls_enable_reply)                   \
3481 _(sw_interface_set_vpath_reply)                         \
3482 _(sw_interface_set_l2_bridge_reply)                     \
3483 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3484 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3485 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3486 _(bridge_domain_add_del_reply)                          \
3487 _(sw_interface_set_l2_xconnect_reply)                   \
3488 _(l2fib_add_del_reply)                                  \
3489 _(ip_add_del_route_reply)                               \
3490 _(mpls_route_add_del_reply)                             \
3491 _(mpls_ip_bind_unbind_reply)                            \
3492 _(proxy_arp_add_del_reply)                              \
3493 _(proxy_arp_intfc_enable_disable_reply)                 \
3494 _(mpls_add_del_encap_reply)                             \
3495 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3496 _(sw_interface_set_unnumbered_reply)                    \
3497 _(ip_neighbor_add_del_reply)                            \
3498 _(reset_vrf_reply)                                      \
3499 _(oam_add_del_reply)                                    \
3500 _(reset_fib_reply)                                      \
3501 _(dhcp_proxy_config_reply)                              \
3502 _(dhcp_proxy_config_2_reply)                            \
3503 _(dhcp_proxy_set_vss_reply)                             \
3504 _(dhcp_client_config_reply)                             \
3505 _(set_ip_flow_hash_reply)                               \
3506 _(sw_interface_ip6_enable_disable_reply)                \
3507 _(sw_interface_ip6_set_link_local_address_reply)        \
3508 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3509 _(sw_interface_ip6nd_ra_config_reply)                   \
3510 _(set_arp_neighbor_limit_reply)                         \
3511 _(l2_patch_add_del_reply)                               \
3512 _(sr_tunnel_add_del_reply)                              \
3513 _(sr_policy_add_del_reply)                              \
3514 _(sr_multicast_map_add_del_reply)                       \
3515 _(classify_add_del_session_reply)                       \
3516 _(classify_set_interface_ip_table_reply)                \
3517 _(classify_set_interface_l2_tables_reply)               \
3518 _(l2tpv3_set_tunnel_cookies_reply)                      \
3519 _(l2tpv3_interface_enable_disable_reply)                \
3520 _(l2tpv3_set_lookup_key_reply)                          \
3521 _(l2_fib_clear_table_reply)                             \
3522 _(l2_interface_efp_filter_reply)                        \
3523 _(l2_interface_vlan_tag_rewrite_reply)                  \
3524 _(modify_vhost_user_if_reply)                           \
3525 _(delete_vhost_user_if_reply)                           \
3526 _(want_ip4_arp_events_reply)                            \
3527 _(want_ip6_nd_events_reply)                             \
3528 _(input_acl_set_interface_reply)                        \
3529 _(ipsec_spd_add_del_reply)                              \
3530 _(ipsec_interface_add_del_spd_reply)                    \
3531 _(ipsec_spd_add_del_entry_reply)                        \
3532 _(ipsec_sad_add_del_entry_reply)                        \
3533 _(ipsec_sa_set_key_reply)                               \
3534 _(ikev2_profile_add_del_reply)                          \
3535 _(ikev2_profile_set_auth_reply)                         \
3536 _(ikev2_profile_set_id_reply)                           \
3537 _(ikev2_profile_set_ts_reply)                           \
3538 _(ikev2_set_local_key_reply)                            \
3539 _(delete_loopback_reply)                                \
3540 _(bd_ip_mac_add_del_reply)                              \
3541 _(map_del_domain_reply)                                 \
3542 _(map_add_del_rule_reply)                               \
3543 _(want_interface_events_reply)                          \
3544 _(want_stats_reply)                                     \
3545 _(cop_interface_enable_disable_reply)                   \
3546 _(cop_whitelist_enable_disable_reply)                   \
3547 _(sw_interface_clear_stats_reply)                       \
3548 _(ioam_enable_reply)                              \
3549 _(ioam_disable_reply)                              \
3550 _(lisp_add_del_locator_reply)                           \
3551 _(lisp_add_del_local_eid_reply)                         \
3552 _(lisp_add_del_remote_mapping_reply)                    \
3553 _(lisp_add_del_adjacency_reply)                         \
3554 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3555 _(lisp_add_del_map_resolver_reply)                      \
3556 _(lisp_gpe_enable_disable_reply)                        \
3557 _(lisp_gpe_add_del_iface_reply)                         \
3558 _(lisp_enable_disable_reply)                            \
3559 _(lisp_pitr_set_locator_set_reply)                      \
3560 _(lisp_map_request_mode_reply)                          \
3561 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3562 _(lisp_eid_table_add_del_map_reply)                     \
3563 _(vxlan_gpe_add_del_tunnel_reply)                       \
3564 _(af_packet_delete_reply)                               \
3565 _(policer_classify_set_interface_reply)                 \
3566 _(netmap_create_reply)                                  \
3567 _(netmap_delete_reply)                                  \
3568 _(set_ipfix_exporter_reply)                             \
3569 _(set_ipfix_classify_stream_reply)                      \
3570 _(ipfix_classify_table_add_del_reply)                   \
3571 _(flow_classify_set_interface_reply)                    \
3572 _(sw_interface_span_enable_disable_reply)               \
3573 _(pg_capture_reply)                                     \
3574 _(pg_enable_disable_reply)                              \
3575 _(ip_source_and_port_range_check_add_del_reply)         \
3576 _(ip_source_and_port_range_check_interface_add_del_reply)\
3577 _(delete_subif_reply)                                   \
3578 _(l2_interface_pbb_tag_rewrite_reply)                   \
3579 _(punt_reply)                                           \
3580 _(feature_enable_disable_reply)
3581
3582 #define _(n)                                    \
3583     static void vl_api_##n##_t_handler          \
3584     (vl_api_##n##_t * mp)                       \
3585     {                                           \
3586         vat_main_t * vam = &vat_main;           \
3587         i32 retval = ntohl(mp->retval);         \
3588         if (vam->async_mode) {                  \
3589             vam->async_errors += (retval < 0);  \
3590         } else {                                \
3591             vam->retval = retval;               \
3592             vam->result_ready = 1;              \
3593         }                                       \
3594     }
3595 foreach_standard_reply_retval_handler;
3596 #undef _
3597
3598 #define _(n)                                    \
3599     static void vl_api_##n##_t_handler_json     \
3600     (vl_api_##n##_t * mp)                       \
3601     {                                           \
3602         vat_main_t * vam = &vat_main;           \
3603         vat_json_node_t node;                   \
3604         vat_json_init_object(&node);            \
3605         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3606         vat_json_print(vam->ofp, &node);        \
3607         vam->retval = ntohl(mp->retval);        \
3608         vam->result_ready = 1;                  \
3609     }
3610 foreach_standard_reply_retval_handler;
3611 #undef _
3612
3613 /*
3614  * Table of message reply handlers, must include boilerplate handlers
3615  * we just generated
3616  */
3617
3618 #define foreach_vpe_api_reply_msg                                       \
3619 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3620 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3621 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3622 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3623 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3624 _(CLI_REPLY, cli_reply)                                                 \
3625 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3626 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3627   sw_interface_add_del_address_reply)                                   \
3628 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3629 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3630 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3631 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3632   sw_interface_set_l2_xconnect_reply)                                   \
3633 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3634   sw_interface_set_l2_bridge_reply)                                     \
3635 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3636   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3637 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3638   sw_interface_set_dpdk_hqos_subport_reply)                             \
3639 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3640   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3641 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3642 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3643 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3644 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3645 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3646 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3647 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3648 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3649 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3650 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3651 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3652 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3653 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3654 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3655 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3656   proxy_arp_intfc_enable_disable_reply)                                 \
3657 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3658 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3659   mpls_ethernet_add_del_tunnel_reply)                                   \
3660 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3661   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3662 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3663   sw_interface_set_unnumbered_reply)                                    \
3664 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3665 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3666 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3667 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3668 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3669 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3670 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3671 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3672 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3673 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3674 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3675 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3676   sw_interface_ip6_enable_disable_reply)                                \
3677 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3678   sw_interface_ip6_set_link_local_address_reply)                        \
3679 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3680   sw_interface_ip6nd_ra_prefix_reply)                                   \
3681 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3682   sw_interface_ip6nd_ra_config_reply)                                   \
3683 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3684 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3685 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3686 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3687 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3688 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3689 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3690 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3691 classify_set_interface_ip_table_reply)                                  \
3692 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3693   classify_set_interface_l2_tables_reply)                               \
3694 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3695 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3696 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3697 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3698 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3699   l2tpv3_interface_enable_disable_reply)                                \
3700 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3701 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3702 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3703 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3704 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3705 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3706 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3707 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3708 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3709 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3710 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3711 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3712 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3713 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3714 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3715 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3716 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3717 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3718 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3719 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3720 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3721 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3722 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3723 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3724 _(IP_DETAILS, ip_details)                                               \
3725 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3726 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3727 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3728 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3729 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3730 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3731 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3732 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3733 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3734 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3735 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3736 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3737 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3738 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3739 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3740 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3741 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3742 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3743 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3744 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3745 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3746 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3747 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3748 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3749 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3750 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3751 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3752 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3753 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3754 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3755 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3756 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3757 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3758 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3759 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3760 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3761 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3762 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3763 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3764 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3765 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3766 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3767 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3768 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3769 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3770 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3771 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3772 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3773 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3774 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3775 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3776 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3777 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3778   lisp_add_del_map_request_itr_rlocs_reply)                             \
3779 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3780   lisp_get_map_request_itr_rlocs_reply)                                 \
3781 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3782 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3783 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3784 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3785 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3786 _(POLICER_DETAILS, policer_details)                                     \
3787 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3788 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3789 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3790 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3791 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3792 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3793 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3794 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3795 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3796 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3797 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3798 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3799 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3800 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3801 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3802 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3803 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3804 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3805 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3806 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3807 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3808 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3809 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3810 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3811 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3812 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3813  ip_source_and_port_range_check_add_del_reply)                          \
3814 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3815  ip_source_and_port_range_check_interface_add_del_reply)                \
3816 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3817 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3818 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3819 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3820 _(PUNT_REPLY, punt_reply)                                               \
3821 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3822 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
3823 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)
3824
3825 /* M: construct, but don't yet send a message */
3826
3827 #define M(T,t)                                  \
3828 do {                                            \
3829     vam->result_ready = 0;                      \
3830     mp = vl_msg_api_alloc(sizeof(*mp));         \
3831     memset (mp, 0, sizeof (*mp));               \
3832     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3833     mp->client_index = vam->my_client_index;    \
3834 } while(0);
3835
3836 #define M2(T,t,n)                               \
3837 do {                                            \
3838     vam->result_ready = 0;                      \
3839     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3840     memset (mp, 0, sizeof (*mp));               \
3841     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3842     mp->client_index = vam->my_client_index;    \
3843 } while(0);
3844
3845
3846 /* S: send a message */
3847 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3848
3849 /* W: wait for results, with timeout */
3850 #define W                                       \
3851 do {                                            \
3852     timeout = vat_time_now (vam) + 1.0;         \
3853                                                 \
3854     while (vat_time_now (vam) < timeout) {      \
3855         if (vam->result_ready == 1) {           \
3856             return (vam->retval);               \
3857         }                                       \
3858     }                                           \
3859     return -99;                                 \
3860 } while(0);
3861
3862 /* W2: wait for results, with timeout */
3863 #define W2(body)                                \
3864 do {                                            \
3865     timeout = vat_time_now (vam) + 1.0;         \
3866                                                 \
3867     while (vat_time_now (vam) < timeout) {      \
3868         if (vam->result_ready == 1) {           \
3869           (body);                               \
3870           return (vam->retval);                 \
3871         }                                       \
3872     }                                           \
3873     return -99;                                 \
3874 } while(0);
3875
3876 typedef struct
3877 {
3878   u8 *name;
3879   u32 value;
3880 } name_sort_t;
3881
3882
3883 #define STR_VTR_OP_CASE(op)     \
3884     case L2_VTR_ ## op:         \
3885         return "" # op;
3886
3887 static const char *
3888 str_vtr_op (u32 vtr_op)
3889 {
3890   switch (vtr_op)
3891     {
3892       STR_VTR_OP_CASE (DISABLED);
3893       STR_VTR_OP_CASE (PUSH_1);
3894       STR_VTR_OP_CASE (PUSH_2);
3895       STR_VTR_OP_CASE (POP_1);
3896       STR_VTR_OP_CASE (POP_2);
3897       STR_VTR_OP_CASE (TRANSLATE_1_1);
3898       STR_VTR_OP_CASE (TRANSLATE_1_2);
3899       STR_VTR_OP_CASE (TRANSLATE_2_1);
3900       STR_VTR_OP_CASE (TRANSLATE_2_2);
3901     }
3902
3903   return "UNKNOWN";
3904 }
3905
3906 static int
3907 dump_sub_interface_table (vat_main_t * vam)
3908 {
3909   const sw_interface_subif_t *sub = NULL;
3910
3911   if (vam->json_output)
3912     {
3913       clib_warning
3914         ("JSON output supported only for VPE API calls and dump_stats_table");
3915       return -99;
3916     }
3917
3918   fformat (vam->ofp,
3919            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3920            "Interface", "sw_if_index",
3921            "sub id", "dot1ad", "tags", "outer id",
3922            "inner id", "exact", "default", "outer any", "inner any");
3923
3924   vec_foreach (sub, vam->sw_if_subif_table)
3925   {
3926     fformat (vam->ofp,
3927              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3928              sub->interface_name,
3929              sub->sw_if_index,
3930              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3931              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3932              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3933              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3934     if (sub->vtr_op != L2_VTR_DISABLED)
3935       {
3936         fformat (vam->ofp,
3937                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3938                  "tag1: %d tag2: %d ]\n",
3939                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3940                  sub->vtr_tag1, sub->vtr_tag2);
3941       }
3942   }
3943
3944   return 0;
3945 }
3946
3947 static int
3948 name_sort_cmp (void *a1, void *a2)
3949 {
3950   name_sort_t *n1 = a1;
3951   name_sort_t *n2 = a2;
3952
3953   return strcmp ((char *) n1->name, (char *) n2->name);
3954 }
3955
3956 static int
3957 dump_interface_table (vat_main_t * vam)
3958 {
3959   hash_pair_t *p;
3960   name_sort_t *nses = 0, *ns;
3961
3962   if (vam->json_output)
3963     {
3964       clib_warning
3965         ("JSON output supported only for VPE API calls and dump_stats_table");
3966       return -99;
3967     }
3968
3969   /* *INDENT-OFF* */
3970   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3971   ({
3972     vec_add2 (nses, ns, 1);
3973     ns->name = (u8 *)(p->key);
3974     ns->value = (u32) p->value[0];
3975   }));
3976   /* *INDENT-ON* */
3977
3978   vec_sort_with_function (nses, name_sort_cmp);
3979
3980   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3981   vec_foreach (ns, nses)
3982   {
3983     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3984   }
3985   vec_free (nses);
3986   return 0;
3987 }
3988
3989 static int
3990 dump_ip_table (vat_main_t * vam, int is_ipv6)
3991 {
3992   const ip_details_t *det = NULL;
3993   const ip_address_details_t *address = NULL;
3994   u32 i = ~0;
3995
3996   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3997
3998   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3999   {
4000     i++;
4001     if (!det->present)
4002       {
4003         continue;
4004       }
4005     fformat (vam->ofp, "%-12d\n", i);
4006     fformat (vam->ofp,
4007              "            %-30s%-13s\n", "Address", "Prefix length");
4008     if (!det->addr)
4009       {
4010         continue;
4011       }
4012     vec_foreach (address, det->addr)
4013     {
4014       fformat (vam->ofp,
4015                "            %-30U%-13d\n",
4016                is_ipv6 ? format_ip6_address : format_ip4_address,
4017                address->ip, address->prefix_length);
4018     }
4019   }
4020
4021   return 0;
4022 }
4023
4024 static int
4025 dump_ipv4_table (vat_main_t * vam)
4026 {
4027   if (vam->json_output)
4028     {
4029       clib_warning
4030         ("JSON output supported only for VPE API calls and dump_stats_table");
4031       return -99;
4032     }
4033
4034   return dump_ip_table (vam, 0);
4035 }
4036
4037 static int
4038 dump_ipv6_table (vat_main_t * vam)
4039 {
4040   if (vam->json_output)
4041     {
4042       clib_warning
4043         ("JSON output supported only for VPE API calls and dump_stats_table");
4044       return -99;
4045     }
4046
4047   return dump_ip_table (vam, 1);
4048 }
4049
4050 static char *
4051 counter_type_to_str (u8 counter_type, u8 is_combined)
4052 {
4053   if (!is_combined)
4054     {
4055       switch (counter_type)
4056         {
4057         case VNET_INTERFACE_COUNTER_DROP:
4058           return "drop";
4059         case VNET_INTERFACE_COUNTER_PUNT:
4060           return "punt";
4061         case VNET_INTERFACE_COUNTER_IP4:
4062           return "ip4";
4063         case VNET_INTERFACE_COUNTER_IP6:
4064           return "ip6";
4065         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4066           return "rx-no-buf";
4067         case VNET_INTERFACE_COUNTER_RX_MISS:
4068           return "rx-miss";
4069         case VNET_INTERFACE_COUNTER_RX_ERROR:
4070           return "rx-error";
4071         case VNET_INTERFACE_COUNTER_TX_ERROR:
4072           return "tx-error";
4073         default:
4074           return "INVALID-COUNTER-TYPE";
4075         }
4076     }
4077   else
4078     {
4079       switch (counter_type)
4080         {
4081         case VNET_INTERFACE_COUNTER_RX:
4082           return "rx";
4083         case VNET_INTERFACE_COUNTER_TX:
4084           return "tx";
4085         default:
4086           return "INVALID-COUNTER-TYPE";
4087         }
4088     }
4089 }
4090
4091 static int
4092 dump_stats_table (vat_main_t * vam)
4093 {
4094   vat_json_node_t node;
4095   vat_json_node_t *msg_array;
4096   vat_json_node_t *msg;
4097   vat_json_node_t *counter_array;
4098   vat_json_node_t *counter;
4099   interface_counter_t c;
4100   u64 packets;
4101   ip4_fib_counter_t *c4;
4102   ip6_fib_counter_t *c6;
4103   int i, j;
4104
4105   if (!vam->json_output)
4106     {
4107       clib_warning ("dump_stats_table supported only in JSON format");
4108       return -99;
4109     }
4110
4111   vat_json_init_object (&node);
4112
4113   /* interface counters */
4114   msg_array = vat_json_object_add (&node, "interface_counters");
4115   vat_json_init_array (msg_array);
4116   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4117     {
4118       msg = vat_json_array_add (msg_array);
4119       vat_json_init_object (msg);
4120       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4121                                        (u8 *) counter_type_to_str (i, 0));
4122       vat_json_object_add_int (msg, "is_combined", 0);
4123       counter_array = vat_json_object_add (msg, "data");
4124       vat_json_init_array (counter_array);
4125       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4126         {
4127           packets = vam->simple_interface_counters[i][j];
4128           vat_json_array_add_uint (counter_array, packets);
4129         }
4130     }
4131   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4132     {
4133       msg = vat_json_array_add (msg_array);
4134       vat_json_init_object (msg);
4135       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4136                                        (u8 *) counter_type_to_str (i, 1));
4137       vat_json_object_add_int (msg, "is_combined", 1);
4138       counter_array = vat_json_object_add (msg, "data");
4139       vat_json_init_array (counter_array);
4140       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4141         {
4142           c = vam->combined_interface_counters[i][j];
4143           counter = vat_json_array_add (counter_array);
4144           vat_json_init_object (counter);
4145           vat_json_object_add_uint (counter, "packets", c.packets);
4146           vat_json_object_add_uint (counter, "bytes", c.bytes);
4147         }
4148     }
4149
4150   /* ip4 fib counters */
4151   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4152   vat_json_init_array (msg_array);
4153   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4154     {
4155       msg = vat_json_array_add (msg_array);
4156       vat_json_init_object (msg);
4157       vat_json_object_add_uint (msg, "vrf_id",
4158                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4159       counter_array = vat_json_object_add (msg, "c");
4160       vat_json_init_array (counter_array);
4161       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4162         {
4163           counter = vat_json_array_add (counter_array);
4164           vat_json_init_object (counter);
4165           c4 = &vam->ip4_fib_counters[i][j];
4166           vat_json_object_add_ip4 (counter, "address", c4->address);
4167           vat_json_object_add_uint (counter, "address_length",
4168                                     c4->address_length);
4169           vat_json_object_add_uint (counter, "packets", c4->packets);
4170           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4171         }
4172     }
4173
4174   /* ip6 fib counters */
4175   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4176   vat_json_init_array (msg_array);
4177   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4178     {
4179       msg = vat_json_array_add (msg_array);
4180       vat_json_init_object (msg);
4181       vat_json_object_add_uint (msg, "vrf_id",
4182                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4183       counter_array = vat_json_object_add (msg, "c");
4184       vat_json_init_array (counter_array);
4185       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4186         {
4187           counter = vat_json_array_add (counter_array);
4188           vat_json_init_object (counter);
4189           c6 = &vam->ip6_fib_counters[i][j];
4190           vat_json_object_add_ip6 (counter, "address", c6->address);
4191           vat_json_object_add_uint (counter, "address_length",
4192                                     c6->address_length);
4193           vat_json_object_add_uint (counter, "packets", c6->packets);
4194           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4195         }
4196     }
4197
4198   vat_json_print (vam->ofp, &node);
4199   vat_json_free (&node);
4200
4201   return 0;
4202 }
4203
4204 int
4205 exec (vat_main_t * vam)
4206 {
4207   api_main_t *am = &api_main;
4208   vl_api_cli_request_t *mp;
4209   f64 timeout;
4210   void *oldheap;
4211   u8 *cmd = 0;
4212   unformat_input_t *i = vam->input;
4213
4214   if (vec_len (i->buffer) == 0)
4215     return -1;
4216
4217   if (vam->exec_mode == 0 && unformat (i, "mode"))
4218     {
4219       vam->exec_mode = 1;
4220       return 0;
4221     }
4222   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4223     {
4224       vam->exec_mode = 0;
4225       return 0;
4226     }
4227
4228
4229   M (CLI_REQUEST, cli_request);
4230
4231   /*
4232    * Copy cmd into shared memory.
4233    * In order for the CLI command to work, it
4234    * must be a vector ending in \n, not a C-string ending
4235    * in \n\0.
4236    */
4237   pthread_mutex_lock (&am->vlib_rp->mutex);
4238   oldheap = svm_push_data_heap (am->vlib_rp);
4239
4240   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4241   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4242
4243   svm_pop_heap (oldheap);
4244   pthread_mutex_unlock (&am->vlib_rp->mutex);
4245
4246   mp->cmd_in_shmem = (u64) cmd;
4247   S;
4248   timeout = vat_time_now (vam) + 10.0;
4249
4250   while (vat_time_now (vam) < timeout)
4251     {
4252       if (vam->result_ready == 1)
4253         {
4254           u8 *free_me;
4255           if (vam->shmem_result != NULL)
4256             fformat (vam->ofp, "%s", vam->shmem_result);
4257           pthread_mutex_lock (&am->vlib_rp->mutex);
4258           oldheap = svm_push_data_heap (am->vlib_rp);
4259
4260           free_me = (u8 *) vam->shmem_result;
4261           vec_free (free_me);
4262
4263           svm_pop_heap (oldheap);
4264           pthread_mutex_unlock (&am->vlib_rp->mutex);
4265           return 0;
4266         }
4267     }
4268   return -99;
4269 }
4270
4271 /*
4272  * Future replacement of exec() that passes CLI buffers directly in
4273  * the API messages instead of an additional shared memory area.
4274  */
4275 static int
4276 exec_inband (vat_main_t * vam)
4277 {
4278   vl_api_cli_inband_t *mp;
4279   f64 timeout;
4280   unformat_input_t *i = vam->input;
4281
4282   if (vec_len (i->buffer) == 0)
4283     return -1;
4284
4285   if (vam->exec_mode == 0 && unformat (i, "mode"))
4286     {
4287       vam->exec_mode = 1;
4288       return 0;
4289     }
4290   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4291     {
4292       vam->exec_mode = 0;
4293       return 0;
4294     }
4295
4296   /*
4297    * In order for the CLI command to work, it
4298    * must be a vector ending in \n, not a C-string ending
4299    * in \n\0.
4300    */
4301   u32 len = vec_len (vam->input->buffer);
4302   M2 (CLI_INBAND, cli_inband, len);
4303   clib_memcpy (mp->cmd, vam->input->buffer, len);
4304   mp->length = htonl (len);
4305
4306   S;
4307   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4308 }
4309
4310 static int
4311 api_create_loopback (vat_main_t * vam)
4312 {
4313   unformat_input_t *i = vam->input;
4314   vl_api_create_loopback_t *mp;
4315   f64 timeout;
4316   u8 mac_address[6];
4317   u8 mac_set = 0;
4318
4319   memset (mac_address, 0, sizeof (mac_address));
4320
4321   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4322     {
4323       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4324         mac_set = 1;
4325       else
4326         break;
4327     }
4328
4329   /* Construct the API message */
4330   M (CREATE_LOOPBACK, create_loopback);
4331   if (mac_set)
4332     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4333
4334   S;
4335   W;
4336 }
4337
4338 static int
4339 api_delete_loopback (vat_main_t * vam)
4340 {
4341   unformat_input_t *i = vam->input;
4342   vl_api_delete_loopback_t *mp;
4343   f64 timeout;
4344   u32 sw_if_index = ~0;
4345
4346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4347     {
4348       if (unformat (i, "sw_if_index %d", &sw_if_index))
4349         ;
4350       else
4351         break;
4352     }
4353
4354   if (sw_if_index == ~0)
4355     {
4356       errmsg ("missing sw_if_index\n");
4357       return -99;
4358     }
4359
4360   /* Construct the API message */
4361   M (DELETE_LOOPBACK, delete_loopback);
4362   mp->sw_if_index = ntohl (sw_if_index);
4363
4364   S;
4365   W;
4366 }
4367
4368 static int
4369 api_want_stats (vat_main_t * vam)
4370 {
4371   unformat_input_t *i = vam->input;
4372   vl_api_want_stats_t *mp;
4373   f64 timeout;
4374   int enable = -1;
4375
4376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4377     {
4378       if (unformat (i, "enable"))
4379         enable = 1;
4380       else if (unformat (i, "disable"))
4381         enable = 0;
4382       else
4383         break;
4384     }
4385
4386   if (enable == -1)
4387     {
4388       errmsg ("missing enable|disable\n");
4389       return -99;
4390     }
4391
4392   M (WANT_STATS, want_stats);
4393   mp->enable_disable = enable;
4394
4395   S;
4396   W;
4397 }
4398
4399 static int
4400 api_want_interface_events (vat_main_t * vam)
4401 {
4402   unformat_input_t *i = vam->input;
4403   vl_api_want_interface_events_t *mp;
4404   f64 timeout;
4405   int enable = -1;
4406
4407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4408     {
4409       if (unformat (i, "enable"))
4410         enable = 1;
4411       else if (unformat (i, "disable"))
4412         enable = 0;
4413       else
4414         break;
4415     }
4416
4417   if (enable == -1)
4418     {
4419       errmsg ("missing enable|disable\n");
4420       return -99;
4421     }
4422
4423   M (WANT_INTERFACE_EVENTS, want_interface_events);
4424   mp->enable_disable = enable;
4425
4426   vam->interface_event_display = enable;
4427
4428   S;
4429   W;
4430 }
4431
4432
4433 /* Note: non-static, called once to set up the initial intfc table */
4434 int
4435 api_sw_interface_dump (vat_main_t * vam)
4436 {
4437   vl_api_sw_interface_dump_t *mp;
4438   f64 timeout;
4439   hash_pair_t *p;
4440   name_sort_t *nses = 0, *ns;
4441   sw_interface_subif_t *sub = NULL;
4442
4443   /* Toss the old name table */
4444   /* *INDENT-OFF* */
4445   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4446   ({
4447     vec_add2 (nses, ns, 1);
4448     ns->name = (u8 *)(p->key);
4449     ns->value = (u32) p->value[0];
4450   }));
4451   /* *INDENT-ON* */
4452
4453   hash_free (vam->sw_if_index_by_interface_name);
4454
4455   vec_foreach (ns, nses) vec_free (ns->name);
4456
4457   vec_free (nses);
4458
4459   vec_foreach (sub, vam->sw_if_subif_table)
4460   {
4461     vec_free (sub->interface_name);
4462   }
4463   vec_free (vam->sw_if_subif_table);
4464
4465   /* recreate the interface name hash table */
4466   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4467
4468   /* Get list of ethernets */
4469   M (SW_INTERFACE_DUMP, sw_interface_dump);
4470   mp->name_filter_valid = 1;
4471   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4472   S;
4473
4474   /* and local / loopback interfaces */
4475   M (SW_INTERFACE_DUMP, sw_interface_dump);
4476   mp->name_filter_valid = 1;
4477   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4478   S;
4479
4480   /* and packet-generator interfaces */
4481   M (SW_INTERFACE_DUMP, sw_interface_dump);
4482   mp->name_filter_valid = 1;
4483   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4484   S;
4485
4486   /* and vxlan-gpe tunnel interfaces */
4487   M (SW_INTERFACE_DUMP, sw_interface_dump);
4488   mp->name_filter_valid = 1;
4489   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4490            sizeof (mp->name_filter) - 1);
4491   S;
4492
4493   /* and vxlan tunnel interfaces */
4494   M (SW_INTERFACE_DUMP, sw_interface_dump);
4495   mp->name_filter_valid = 1;
4496   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4497   S;
4498
4499   /* and host (af_packet) interfaces */
4500   M (SW_INTERFACE_DUMP, sw_interface_dump);
4501   mp->name_filter_valid = 1;
4502   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4503   S;
4504
4505   /* and l2tpv3 tunnel interfaces */
4506   M (SW_INTERFACE_DUMP, sw_interface_dump);
4507   mp->name_filter_valid = 1;
4508   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4509            sizeof (mp->name_filter) - 1);
4510   S;
4511
4512   /* and GRE tunnel interfaces */
4513   M (SW_INTERFACE_DUMP, sw_interface_dump);
4514   mp->name_filter_valid = 1;
4515   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4516   S;
4517
4518   /* and LISP-GPE interfaces */
4519   M (SW_INTERFACE_DUMP, sw_interface_dump);
4520   mp->name_filter_valid = 1;
4521   strncpy ((char *) mp->name_filter, "lisp_gpe",
4522            sizeof (mp->name_filter) - 1);
4523   S;
4524
4525   /* and IPSEC tunnel interfaces */
4526   M (SW_INTERFACE_DUMP, sw_interface_dump);
4527   mp->name_filter_valid = 1;
4528   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4529   S;
4530
4531   /* Use a control ping for synchronization */
4532   {
4533     vl_api_control_ping_t *mp;
4534     M (CONTROL_PING, control_ping);
4535     S;
4536   }
4537   W;
4538 }
4539
4540 static int
4541 api_sw_interface_set_flags (vat_main_t * vam)
4542 {
4543   unformat_input_t *i = vam->input;
4544   vl_api_sw_interface_set_flags_t *mp;
4545   f64 timeout;
4546   u32 sw_if_index;
4547   u8 sw_if_index_set = 0;
4548   u8 admin_up = 0, link_up = 0;
4549
4550   /* Parse args required to build the message */
4551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4552     {
4553       if (unformat (i, "admin-up"))
4554         admin_up = 1;
4555       else if (unformat (i, "admin-down"))
4556         admin_up = 0;
4557       else if (unformat (i, "link-up"))
4558         link_up = 1;
4559       else if (unformat (i, "link-down"))
4560         link_up = 0;
4561       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4562         sw_if_index_set = 1;
4563       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4564         sw_if_index_set = 1;
4565       else
4566         break;
4567     }
4568
4569   if (sw_if_index_set == 0)
4570     {
4571       errmsg ("missing interface name or sw_if_index\n");
4572       return -99;
4573     }
4574
4575   /* Construct the API message */
4576   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4577   mp->sw_if_index = ntohl (sw_if_index);
4578   mp->admin_up_down = admin_up;
4579   mp->link_up_down = link_up;
4580
4581   /* send it... */
4582   S;
4583
4584   /* Wait for a reply, return the good/bad news... */
4585   W;
4586 }
4587
4588 static int
4589 api_sw_interface_clear_stats (vat_main_t * vam)
4590 {
4591   unformat_input_t *i = vam->input;
4592   vl_api_sw_interface_clear_stats_t *mp;
4593   f64 timeout;
4594   u32 sw_if_index;
4595   u8 sw_if_index_set = 0;
4596
4597   /* Parse args required to build the message */
4598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4599     {
4600       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4601         sw_if_index_set = 1;
4602       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4603         sw_if_index_set = 1;
4604       else
4605         break;
4606     }
4607
4608   /* Construct the API message */
4609   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4610
4611   if (sw_if_index_set == 1)
4612     mp->sw_if_index = ntohl (sw_if_index);
4613   else
4614     mp->sw_if_index = ~0;
4615
4616   /* send it... */
4617   S;
4618
4619   /* Wait for a reply, return the good/bad news... */
4620   W;
4621 }
4622
4623 static int
4624 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4625 {
4626   unformat_input_t *i = vam->input;
4627   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4628   f64 timeout;
4629   u32 sw_if_index;
4630   u8 sw_if_index_set = 0;
4631   u32 subport;
4632   u8 subport_set = 0;
4633   u32 pipe;
4634   u8 pipe_set = 0;
4635   u32 profile;
4636   u8 profile_set = 0;
4637
4638   /* Parse args required to build the message */
4639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4640     {
4641       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4642         sw_if_index_set = 1;
4643       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4644         sw_if_index_set = 1;
4645       else if (unformat (i, "subport %u", &subport))
4646         subport_set = 1;
4647       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4648         sw_if_index_set = 1;
4649       else if (unformat (i, "pipe %u", &pipe))
4650         pipe_set = 1;
4651       else if (unformat (i, "profile %u", &profile))
4652         profile_set = 1;
4653       else
4654         break;
4655     }
4656
4657   if (sw_if_index_set == 0)
4658     {
4659       errmsg ("missing interface name or sw_if_index\n");
4660       return -99;
4661     }
4662
4663   if (subport_set == 0)
4664     {
4665       errmsg ("missing subport \n");
4666       return -99;
4667     }
4668
4669   if (pipe_set == 0)
4670     {
4671       errmsg ("missing pipe\n");
4672       return -99;
4673     }
4674
4675   if (profile_set == 0)
4676     {
4677       errmsg ("missing profile\n");
4678       return -99;
4679     }
4680
4681   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4682
4683   mp->sw_if_index = ntohl (sw_if_index);
4684   mp->subport = ntohl (subport);
4685   mp->pipe = ntohl (pipe);
4686   mp->profile = ntohl (profile);
4687
4688
4689   S;
4690   W;
4691   /* NOTREACHED */
4692   return 0;
4693 }
4694
4695 static int
4696 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4697 {
4698   unformat_input_t *i = vam->input;
4699   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4700   f64 timeout;
4701   u32 sw_if_index;
4702   u8 sw_if_index_set = 0;
4703   u32 subport;
4704   u8 subport_set = 0;
4705   u32 tb_rate = 1250000000;     /* 10GbE */
4706   u32 tb_size = 1000000;
4707   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4708   u32 tc_period = 10;
4709
4710   /* Parse args required to build the message */
4711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4712     {
4713       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4714         sw_if_index_set = 1;
4715       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4716         sw_if_index_set = 1;
4717       else if (unformat (i, "subport %u", &subport))
4718         subport_set = 1;
4719       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4720         sw_if_index_set = 1;
4721       else if (unformat (i, "rate %u", &tb_rate))
4722         {
4723           u32 tc_id;
4724
4725           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4726                tc_id++)
4727             tc_rate[tc_id] = tb_rate;
4728         }
4729       else if (unformat (i, "bktsize %u", &tb_size))
4730         ;
4731       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4732         ;
4733       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4734         ;
4735       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4736         ;
4737       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4738         ;
4739       else if (unformat (i, "period %u", &tc_period))
4740         ;
4741       else
4742         break;
4743     }
4744
4745   if (sw_if_index_set == 0)
4746     {
4747       errmsg ("missing interface name or sw_if_index\n");
4748       return -99;
4749     }
4750
4751   if (subport_set == 0)
4752     {
4753       errmsg ("missing subport \n");
4754       return -99;
4755     }
4756
4757   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4758
4759   mp->sw_if_index = ntohl (sw_if_index);
4760   mp->subport = ntohl (subport);
4761   mp->tb_rate = ntohl (tb_rate);
4762   mp->tb_size = ntohl (tb_size);
4763   mp->tc_rate[0] = ntohl (tc_rate[0]);
4764   mp->tc_rate[1] = ntohl (tc_rate[1]);
4765   mp->tc_rate[2] = ntohl (tc_rate[2]);
4766   mp->tc_rate[3] = ntohl (tc_rate[3]);
4767   mp->tc_period = ntohl (tc_period);
4768
4769   S;
4770   W;
4771   /* NOTREACHED */
4772   return 0;
4773 }
4774
4775 static int
4776 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4777 {
4778   unformat_input_t *i = vam->input;
4779   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4780   f64 timeout;
4781   u32 sw_if_index;
4782   u8 sw_if_index_set = 0;
4783   u8 entry_set = 0;
4784   u8 tc_set = 0;
4785   u8 queue_set = 0;
4786   u32 entry, tc, queue;
4787
4788   /* Parse args required to build the message */
4789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4790     {
4791       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4792         sw_if_index_set = 1;
4793       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4794         sw_if_index_set = 1;
4795       else if (unformat (i, "entry %d", &entry))
4796         entry_set = 1;
4797       else if (unformat (i, "tc %d", &tc))
4798         tc_set = 1;
4799       else if (unformat (i, "queue %d", &queue))
4800         queue_set = 1;
4801       else
4802         break;
4803     }
4804
4805   if (sw_if_index_set == 0)
4806     {
4807       errmsg ("missing interface name or sw_if_index\n");
4808       return -99;
4809     }
4810
4811   if (entry_set == 0)
4812     {
4813       errmsg ("missing entry \n");
4814       return -99;
4815     }
4816
4817   if (tc_set == 0)
4818     {
4819       errmsg ("missing traffic class \n");
4820       return -99;
4821     }
4822
4823   if (queue_set == 0)
4824     {
4825       errmsg ("missing queue \n");
4826       return -99;
4827     }
4828
4829   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4830
4831   mp->sw_if_index = ntohl (sw_if_index);
4832   mp->entry = ntohl (entry);
4833   mp->tc = ntohl (tc);
4834   mp->queue = ntohl (queue);
4835
4836   S;
4837   W;
4838   /* NOTREACHED */
4839   return 0;
4840 }
4841
4842 static int
4843 api_sw_interface_add_del_address (vat_main_t * vam)
4844 {
4845   unformat_input_t *i = vam->input;
4846   vl_api_sw_interface_add_del_address_t *mp;
4847   f64 timeout;
4848   u32 sw_if_index;
4849   u8 sw_if_index_set = 0;
4850   u8 is_add = 1, del_all = 0;
4851   u32 address_length = 0;
4852   u8 v4_address_set = 0;
4853   u8 v6_address_set = 0;
4854   ip4_address_t v4address;
4855   ip6_address_t v6address;
4856
4857   /* Parse args required to build the message */
4858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4859     {
4860       if (unformat (i, "del-all"))
4861         del_all = 1;
4862       else if (unformat (i, "del"))
4863         is_add = 0;
4864       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4865         sw_if_index_set = 1;
4866       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4867         sw_if_index_set = 1;
4868       else if (unformat (i, "%U/%d",
4869                          unformat_ip4_address, &v4address, &address_length))
4870         v4_address_set = 1;
4871       else if (unformat (i, "%U/%d",
4872                          unformat_ip6_address, &v6address, &address_length))
4873         v6_address_set = 1;
4874       else
4875         break;
4876     }
4877
4878   if (sw_if_index_set == 0)
4879     {
4880       errmsg ("missing interface name or sw_if_index\n");
4881       return -99;
4882     }
4883   if (v4_address_set && v6_address_set)
4884     {
4885       errmsg ("both v4 and v6 addresses set\n");
4886       return -99;
4887     }
4888   if (!v4_address_set && !v6_address_set && !del_all)
4889     {
4890       errmsg ("no addresses set\n");
4891       return -99;
4892     }
4893
4894   /* Construct the API message */
4895   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4896
4897   mp->sw_if_index = ntohl (sw_if_index);
4898   mp->is_add = is_add;
4899   mp->del_all = del_all;
4900   if (v6_address_set)
4901     {
4902       mp->is_ipv6 = 1;
4903       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4904     }
4905   else
4906     {
4907       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4908     }
4909   mp->address_length = address_length;
4910
4911   /* send it... */
4912   S;
4913
4914   /* Wait for a reply, return good/bad news  */
4915   W;
4916 }
4917
4918 static int
4919 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4920 {
4921   unformat_input_t *i = vam->input;
4922   vl_api_sw_interface_set_mpls_enable_t *mp;
4923   f64 timeout;
4924   u32 sw_if_index;
4925   u8 sw_if_index_set = 0;
4926   u8 enable = 1;
4927
4928   /* Parse args required to build the message */
4929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4930     {
4931       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4932         sw_if_index_set = 1;
4933       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4934         sw_if_index_set = 1;
4935       else if (unformat (i, "disable"))
4936         enable = 0;
4937       else if (unformat (i, "dis"))
4938         enable = 0;
4939       else
4940         break;
4941     }
4942
4943   if (sw_if_index_set == 0)
4944     {
4945       errmsg ("missing interface name or sw_if_index\n");
4946       return -99;
4947     }
4948
4949   /* Construct the API message */
4950   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
4951
4952   mp->sw_if_index = ntohl (sw_if_index);
4953   mp->enable = enable;
4954
4955   /* send it... */
4956   S;
4957
4958   /* Wait for a reply... */
4959   W;
4960 }
4961
4962 static int
4963 api_sw_interface_set_table (vat_main_t * vam)
4964 {
4965   unformat_input_t *i = vam->input;
4966   vl_api_sw_interface_set_table_t *mp;
4967   f64 timeout;
4968   u32 sw_if_index, vrf_id = 0;
4969   u8 sw_if_index_set = 0;
4970   u8 is_ipv6 = 0;
4971
4972   /* Parse args required to build the message */
4973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4974     {
4975       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4976         sw_if_index_set = 1;
4977       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4978         sw_if_index_set = 1;
4979       else if (unformat (i, "vrf %d", &vrf_id))
4980         ;
4981       else if (unformat (i, "ipv6"))
4982         is_ipv6 = 1;
4983       else
4984         break;
4985     }
4986
4987   if (sw_if_index_set == 0)
4988     {
4989       errmsg ("missing interface name or sw_if_index\n");
4990       return -99;
4991     }
4992
4993   /* Construct the API message */
4994   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4995
4996   mp->sw_if_index = ntohl (sw_if_index);
4997   mp->is_ipv6 = is_ipv6;
4998   mp->vrf_id = ntohl (vrf_id);
4999
5000   /* send it... */
5001   S;
5002
5003   /* Wait for a reply... */
5004   W;
5005 }
5006
5007 static int
5008 api_sw_interface_set_vpath (vat_main_t * vam)
5009 {
5010   unformat_input_t *i = vam->input;
5011   vl_api_sw_interface_set_vpath_t *mp;
5012   f64 timeout;
5013   u32 sw_if_index = 0;
5014   u8 sw_if_index_set = 0;
5015   u8 is_enable = 0;
5016
5017   /* Parse args required to build the message */
5018   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5019     {
5020       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5021         sw_if_index_set = 1;
5022       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5023         sw_if_index_set = 1;
5024       else if (unformat (i, "enable"))
5025         is_enable = 1;
5026       else if (unformat (i, "disable"))
5027         is_enable = 0;
5028       else
5029         break;
5030     }
5031
5032   if (sw_if_index_set == 0)
5033     {
5034       errmsg ("missing interface name or sw_if_index\n");
5035       return -99;
5036     }
5037
5038   /* Construct the API message */
5039   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5040
5041   mp->sw_if_index = ntohl (sw_if_index);
5042   mp->enable = is_enable;
5043
5044   /* send it... */
5045   S;
5046
5047   /* Wait for a reply... */
5048   W;
5049 }
5050
5051 static int
5052 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5053 {
5054   unformat_input_t *i = vam->input;
5055   vl_api_sw_interface_set_l2_xconnect_t *mp;
5056   f64 timeout;
5057   u32 rx_sw_if_index;
5058   u8 rx_sw_if_index_set = 0;
5059   u32 tx_sw_if_index;
5060   u8 tx_sw_if_index_set = 0;
5061   u8 enable = 1;
5062
5063   /* Parse args required to build the message */
5064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5065     {
5066       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5067         rx_sw_if_index_set = 1;
5068       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5069         tx_sw_if_index_set = 1;
5070       else if (unformat (i, "rx"))
5071         {
5072           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5073             {
5074               if (unformat (i, "%U", unformat_sw_if_index, vam,
5075                             &rx_sw_if_index))
5076                 rx_sw_if_index_set = 1;
5077             }
5078           else
5079             break;
5080         }
5081       else if (unformat (i, "tx"))
5082         {
5083           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5084             {
5085               if (unformat (i, "%U", unformat_sw_if_index, vam,
5086                             &tx_sw_if_index))
5087                 tx_sw_if_index_set = 1;
5088             }
5089           else
5090             break;
5091         }
5092       else if (unformat (i, "enable"))
5093         enable = 1;
5094       else if (unformat (i, "disable"))
5095         enable = 0;
5096       else
5097         break;
5098     }
5099
5100   if (rx_sw_if_index_set == 0)
5101     {
5102       errmsg ("missing rx interface name or rx_sw_if_index\n");
5103       return -99;
5104     }
5105
5106   if (enable && (tx_sw_if_index_set == 0))
5107     {
5108       errmsg ("missing tx interface name or tx_sw_if_index\n");
5109       return -99;
5110     }
5111
5112   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5113
5114   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5115   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5116   mp->enable = enable;
5117
5118   S;
5119   W;
5120   /* NOTREACHED */
5121   return 0;
5122 }
5123
5124 static int
5125 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5126 {
5127   unformat_input_t *i = vam->input;
5128   vl_api_sw_interface_set_l2_bridge_t *mp;
5129   f64 timeout;
5130   u32 rx_sw_if_index;
5131   u8 rx_sw_if_index_set = 0;
5132   u32 bd_id;
5133   u8 bd_id_set = 0;
5134   u8 bvi = 0;
5135   u32 shg = 0;
5136   u8 enable = 1;
5137
5138   /* Parse args required to build the message */
5139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5140     {
5141       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5142         rx_sw_if_index_set = 1;
5143       else if (unformat (i, "bd_id %d", &bd_id))
5144         bd_id_set = 1;
5145       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5146         rx_sw_if_index_set = 1;
5147       else if (unformat (i, "shg %d", &shg))
5148         ;
5149       else if (unformat (i, "bvi"))
5150         bvi = 1;
5151       else if (unformat (i, "enable"))
5152         enable = 1;
5153       else if (unformat (i, "disable"))
5154         enable = 0;
5155       else
5156         break;
5157     }
5158
5159   if (rx_sw_if_index_set == 0)
5160     {
5161       errmsg ("missing rx interface name or sw_if_index\n");
5162       return -99;
5163     }
5164
5165   if (enable && (bd_id_set == 0))
5166     {
5167       errmsg ("missing bridge domain\n");
5168       return -99;
5169     }
5170
5171   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5172
5173   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5174   mp->bd_id = ntohl (bd_id);
5175   mp->shg = (u8) shg;
5176   mp->bvi = bvi;
5177   mp->enable = enable;
5178
5179   S;
5180   W;
5181   /* NOTREACHED */
5182   return 0;
5183 }
5184
5185 static int
5186 api_bridge_domain_dump (vat_main_t * vam)
5187 {
5188   unformat_input_t *i = vam->input;
5189   vl_api_bridge_domain_dump_t *mp;
5190   f64 timeout;
5191   u32 bd_id = ~0;
5192
5193   /* Parse args required to build the message */
5194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5195     {
5196       if (unformat (i, "bd_id %d", &bd_id))
5197         ;
5198       else
5199         break;
5200     }
5201
5202   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5203   mp->bd_id = ntohl (bd_id);
5204   S;
5205
5206   /* Use a control ping for synchronization */
5207   {
5208     vl_api_control_ping_t *mp;
5209     M (CONTROL_PING, control_ping);
5210     S;
5211   }
5212
5213   W;
5214   /* NOTREACHED */
5215   return 0;
5216 }
5217
5218 static int
5219 api_bridge_domain_add_del (vat_main_t * vam)
5220 {
5221   unformat_input_t *i = vam->input;
5222   vl_api_bridge_domain_add_del_t *mp;
5223   f64 timeout;
5224   u32 bd_id = ~0;
5225   u8 is_add = 1;
5226   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5227
5228   /* Parse args required to build the message */
5229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5230     {
5231       if (unformat (i, "bd_id %d", &bd_id))
5232         ;
5233       else if (unformat (i, "flood %d", &flood))
5234         ;
5235       else if (unformat (i, "uu-flood %d", &uu_flood))
5236         ;
5237       else if (unformat (i, "forward %d", &forward))
5238         ;
5239       else if (unformat (i, "learn %d", &learn))
5240         ;
5241       else if (unformat (i, "arp-term %d", &arp_term))
5242         ;
5243       else if (unformat (i, "del"))
5244         {
5245           is_add = 0;
5246           flood = uu_flood = forward = learn = 0;
5247         }
5248       else
5249         break;
5250     }
5251
5252   if (bd_id == ~0)
5253     {
5254       errmsg ("missing bridge domain\n");
5255       return -99;
5256     }
5257
5258   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5259
5260   mp->bd_id = ntohl (bd_id);
5261   mp->flood = flood;
5262   mp->uu_flood = uu_flood;
5263   mp->forward = forward;
5264   mp->learn = learn;
5265   mp->arp_term = arp_term;
5266   mp->is_add = is_add;
5267
5268   S;
5269   W;
5270   /* NOTREACHED */
5271   return 0;
5272 }
5273
5274 static int
5275 api_l2fib_add_del (vat_main_t * vam)
5276 {
5277   unformat_input_t *i = vam->input;
5278   vl_api_l2fib_add_del_t *mp;
5279   f64 timeout;
5280   u64 mac = 0;
5281   u8 mac_set = 0;
5282   u32 bd_id;
5283   u8 bd_id_set = 0;
5284   u32 sw_if_index;
5285   u8 sw_if_index_set = 0;
5286   u8 is_add = 1;
5287   u8 static_mac = 0;
5288   u8 filter_mac = 0;
5289   u8 bvi_mac = 0;
5290   int count = 1;
5291   f64 before = 0;
5292   int j;
5293
5294   /* Parse args required to build the message */
5295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5296     {
5297       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5298         mac_set = 1;
5299       else if (unformat (i, "bd_id %d", &bd_id))
5300         bd_id_set = 1;
5301       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5302         sw_if_index_set = 1;
5303       else if (unformat (i, "sw_if"))
5304         {
5305           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5306             {
5307               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5308                 sw_if_index_set = 1;
5309             }
5310           else
5311             break;
5312         }
5313       else if (unformat (i, "static"))
5314         static_mac = 1;
5315       else if (unformat (i, "filter"))
5316         {
5317           filter_mac = 1;
5318           static_mac = 1;
5319         }
5320       else if (unformat (i, "bvi"))
5321         {
5322           bvi_mac = 1;
5323           static_mac = 1;
5324         }
5325       else if (unformat (i, "del"))
5326         is_add = 0;
5327       else if (unformat (i, "count %d", &count))
5328         ;
5329       else
5330         break;
5331     }
5332
5333   if (mac_set == 0)
5334     {
5335       errmsg ("missing mac address\n");
5336       return -99;
5337     }
5338
5339   if (bd_id_set == 0)
5340     {
5341       errmsg ("missing bridge domain\n");
5342       return -99;
5343     }
5344
5345   if (is_add && (sw_if_index_set == 0))
5346     {
5347       errmsg ("missing interface name or sw_if_index\n");
5348       return -99;
5349     }
5350
5351   if (count > 1)
5352     {
5353       /* Turn on async mode */
5354       vam->async_mode = 1;
5355       vam->async_errors = 0;
5356       before = vat_time_now (vam);
5357     }
5358
5359   for (j = 0; j < count; j++)
5360     {
5361       M (L2FIB_ADD_DEL, l2fib_add_del);
5362
5363       mp->mac = mac;
5364       mp->bd_id = ntohl (bd_id);
5365       mp->is_add = is_add;
5366
5367       if (is_add)
5368         {
5369           mp->sw_if_index = ntohl (sw_if_index);
5370           mp->static_mac = static_mac;
5371           mp->filter_mac = filter_mac;
5372           mp->bvi_mac = bvi_mac;
5373         }
5374       increment_mac_address (&mac);
5375       /* send it... */
5376       S;
5377     }
5378
5379   if (count > 1)
5380     {
5381       vl_api_control_ping_t *mp;
5382       f64 after;
5383
5384       /* Shut off async mode */
5385       vam->async_mode = 0;
5386
5387       M (CONTROL_PING, control_ping);
5388       S;
5389
5390       timeout = vat_time_now (vam) + 1.0;
5391       while (vat_time_now (vam) < timeout)
5392         if (vam->result_ready == 1)
5393           goto out;
5394       vam->retval = -99;
5395
5396     out:
5397       if (vam->retval == -99)
5398         errmsg ("timeout\n");
5399
5400       if (vam->async_errors > 0)
5401         {
5402           errmsg ("%d asynchronous errors\n", vam->async_errors);
5403           vam->retval = -98;
5404         }
5405       vam->async_errors = 0;
5406       after = vat_time_now (vam);
5407
5408       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5409                count, after - before, count / (after - before));
5410     }
5411   else
5412     {
5413       /* Wait for a reply... */
5414       W;
5415     }
5416   /* Return the good/bad news */
5417   return (vam->retval);
5418 }
5419
5420 static int
5421 api_l2_flags (vat_main_t * vam)
5422 {
5423   unformat_input_t *i = vam->input;
5424   vl_api_l2_flags_t *mp;
5425   f64 timeout;
5426   u32 sw_if_index;
5427   u32 feature_bitmap = 0;
5428   u8 sw_if_index_set = 0;
5429
5430   /* Parse args required to build the message */
5431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5432     {
5433       if (unformat (i, "sw_if_index %d", &sw_if_index))
5434         sw_if_index_set = 1;
5435       else if (unformat (i, "sw_if"))
5436         {
5437           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5438             {
5439               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5440                 sw_if_index_set = 1;
5441             }
5442           else
5443             break;
5444         }
5445       else if (unformat (i, "learn"))
5446         feature_bitmap |= L2INPUT_FEAT_LEARN;
5447       else if (unformat (i, "forward"))
5448         feature_bitmap |= L2INPUT_FEAT_FWD;
5449       else if (unformat (i, "flood"))
5450         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5451       else if (unformat (i, "uu-flood"))
5452         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5453       else
5454         break;
5455     }
5456
5457   if (sw_if_index_set == 0)
5458     {
5459       errmsg ("missing interface name or sw_if_index\n");
5460       return -99;
5461     }
5462
5463   M (L2_FLAGS, l2_flags);
5464
5465   mp->sw_if_index = ntohl (sw_if_index);
5466   mp->feature_bitmap = ntohl (feature_bitmap);
5467
5468   S;
5469   W;
5470   /* NOTREACHED */
5471   return 0;
5472 }
5473
5474 static int
5475 api_bridge_flags (vat_main_t * vam)
5476 {
5477   unformat_input_t *i = vam->input;
5478   vl_api_bridge_flags_t *mp;
5479   f64 timeout;
5480   u32 bd_id;
5481   u8 bd_id_set = 0;
5482   u8 is_set = 1;
5483   u32 flags = 0;
5484
5485   /* Parse args required to build the message */
5486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5487     {
5488       if (unformat (i, "bd_id %d", &bd_id))
5489         bd_id_set = 1;
5490       else if (unformat (i, "learn"))
5491         flags |= L2_LEARN;
5492       else if (unformat (i, "forward"))
5493         flags |= L2_FWD;
5494       else if (unformat (i, "flood"))
5495         flags |= L2_FLOOD;
5496       else if (unformat (i, "uu-flood"))
5497         flags |= L2_UU_FLOOD;
5498       else if (unformat (i, "arp-term"))
5499         flags |= L2_ARP_TERM;
5500       else if (unformat (i, "off"))
5501         is_set = 0;
5502       else if (unformat (i, "disable"))
5503         is_set = 0;
5504       else
5505         break;
5506     }
5507
5508   if (bd_id_set == 0)
5509     {
5510       errmsg ("missing bridge domain\n");
5511       return -99;
5512     }
5513
5514   M (BRIDGE_FLAGS, bridge_flags);
5515
5516   mp->bd_id = ntohl (bd_id);
5517   mp->feature_bitmap = ntohl (flags);
5518   mp->is_set = is_set;
5519
5520   S;
5521   W;
5522   /* NOTREACHED */
5523   return 0;
5524 }
5525
5526 static int
5527 api_bd_ip_mac_add_del (vat_main_t * vam)
5528 {
5529   unformat_input_t *i = vam->input;
5530   vl_api_bd_ip_mac_add_del_t *mp;
5531   f64 timeout;
5532   u32 bd_id;
5533   u8 is_ipv6 = 0;
5534   u8 is_add = 1;
5535   u8 bd_id_set = 0;
5536   u8 ip_set = 0;
5537   u8 mac_set = 0;
5538   ip4_address_t v4addr;
5539   ip6_address_t v6addr;
5540   u8 macaddr[6];
5541
5542
5543   /* Parse args required to build the message */
5544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5545     {
5546       if (unformat (i, "bd_id %d", &bd_id))
5547         {
5548           bd_id_set++;
5549         }
5550       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5551         {
5552           ip_set++;
5553         }
5554       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5555         {
5556           ip_set++;
5557           is_ipv6++;
5558         }
5559       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5560         {
5561           mac_set++;
5562         }
5563       else if (unformat (i, "del"))
5564         is_add = 0;
5565       else
5566         break;
5567     }
5568
5569   if (bd_id_set == 0)
5570     {
5571       errmsg ("missing bridge domain\n");
5572       return -99;
5573     }
5574   else if (ip_set == 0)
5575     {
5576       errmsg ("missing IP address\n");
5577       return -99;
5578     }
5579   else if (mac_set == 0)
5580     {
5581       errmsg ("missing MAC address\n");
5582       return -99;
5583     }
5584
5585   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5586
5587   mp->bd_id = ntohl (bd_id);
5588   mp->is_ipv6 = is_ipv6;
5589   mp->is_add = is_add;
5590   if (is_ipv6)
5591     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5592   else
5593     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5594   clib_memcpy (mp->mac_address, macaddr, 6);
5595   S;
5596   W;
5597   /* NOTREACHED */
5598   return 0;
5599 }
5600
5601 static int
5602 api_tap_connect (vat_main_t * vam)
5603 {
5604   unformat_input_t *i = vam->input;
5605   vl_api_tap_connect_t *mp;
5606   f64 timeout;
5607   u8 mac_address[6];
5608   u8 random_mac = 1;
5609   u8 name_set = 0;
5610   u8 *tap_name;
5611
5612   memset (mac_address, 0, sizeof (mac_address));
5613
5614   /* Parse args required to build the message */
5615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5616     {
5617       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5618         {
5619           random_mac = 0;
5620         }
5621       else if (unformat (i, "random-mac"))
5622         random_mac = 1;
5623       else if (unformat (i, "tapname %s", &tap_name))
5624         name_set = 1;
5625       else
5626         break;
5627     }
5628
5629   if (name_set == 0)
5630     {
5631       errmsg ("missing tap name\n");
5632       return -99;
5633     }
5634   if (vec_len (tap_name) > 63)
5635     {
5636       errmsg ("tap name too long\n");
5637     }
5638   vec_add1 (tap_name, 0);
5639
5640   /* Construct the API message */
5641   M (TAP_CONNECT, tap_connect);
5642
5643   mp->use_random_mac = random_mac;
5644   clib_memcpy (mp->mac_address, mac_address, 6);
5645   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5646   vec_free (tap_name);
5647
5648   /* send it... */
5649   S;
5650
5651   /* Wait for a reply... */
5652   W;
5653 }
5654
5655 static int
5656 api_tap_modify (vat_main_t * vam)
5657 {
5658   unformat_input_t *i = vam->input;
5659   vl_api_tap_modify_t *mp;
5660   f64 timeout;
5661   u8 mac_address[6];
5662   u8 random_mac = 1;
5663   u8 name_set = 0;
5664   u8 *tap_name;
5665   u32 sw_if_index = ~0;
5666   u8 sw_if_index_set = 0;
5667
5668   memset (mac_address, 0, sizeof (mac_address));
5669
5670   /* Parse args required to build the message */
5671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5672     {
5673       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5674         sw_if_index_set = 1;
5675       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5676         sw_if_index_set = 1;
5677       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5678         {
5679           random_mac = 0;
5680         }
5681       else if (unformat (i, "random-mac"))
5682         random_mac = 1;
5683       else if (unformat (i, "tapname %s", &tap_name))
5684         name_set = 1;
5685       else
5686         break;
5687     }
5688
5689   if (sw_if_index_set == 0)
5690     {
5691       errmsg ("missing vpp interface name");
5692       return -99;
5693     }
5694   if (name_set == 0)
5695     {
5696       errmsg ("missing tap name\n");
5697       return -99;
5698     }
5699   if (vec_len (tap_name) > 63)
5700     {
5701       errmsg ("tap name too long\n");
5702     }
5703   vec_add1 (tap_name, 0);
5704
5705   /* Construct the API message */
5706   M (TAP_MODIFY, tap_modify);
5707
5708   mp->use_random_mac = random_mac;
5709   mp->sw_if_index = ntohl (sw_if_index);
5710   clib_memcpy (mp->mac_address, mac_address, 6);
5711   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5712   vec_free (tap_name);
5713
5714   /* send it... */
5715   S;
5716
5717   /* Wait for a reply... */
5718   W;
5719 }
5720
5721 static int
5722 api_tap_delete (vat_main_t * vam)
5723 {
5724   unformat_input_t *i = vam->input;
5725   vl_api_tap_delete_t *mp;
5726   f64 timeout;
5727   u32 sw_if_index = ~0;
5728   u8 sw_if_index_set = 0;
5729
5730   /* Parse args required to build the message */
5731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5732     {
5733       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5734         sw_if_index_set = 1;
5735       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5736         sw_if_index_set = 1;
5737       else
5738         break;
5739     }
5740
5741   if (sw_if_index_set == 0)
5742     {
5743       errmsg ("missing vpp interface name");
5744       return -99;
5745     }
5746
5747   /* Construct the API message */
5748   M (TAP_DELETE, tap_delete);
5749
5750   mp->sw_if_index = ntohl (sw_if_index);
5751
5752   /* send it... */
5753   S;
5754
5755   /* Wait for a reply... */
5756   W;
5757 }
5758
5759 static int
5760 api_ip_add_del_route (vat_main_t * vam)
5761 {
5762   unformat_input_t *i = vam->input;
5763   vl_api_ip_add_del_route_t *mp;
5764   f64 timeout;
5765   u32 sw_if_index = ~0, vrf_id = 0;
5766   u8 sw_if_index_set = 0;
5767   u8 is_ipv6 = 0;
5768   u8 is_local = 0, is_drop = 0;
5769   u8 is_unreach = 0, is_prohibit = 0;
5770   u8 create_vrf_if_needed = 0;
5771   u8 is_add = 1;
5772   u32 next_hop_weight = 1;
5773   u8 not_last = 0;
5774   u8 is_multipath = 0;
5775   u8 address_set = 0;
5776   u8 address_length_set = 0;
5777   u32 next_hop_table_id = 0;
5778   u32 resolve_attempts = 0;
5779   u32 dst_address_length = 0;
5780   u8 next_hop_set = 0;
5781   ip4_address_t v4_dst_address, v4_next_hop_address;
5782   ip6_address_t v6_dst_address, v6_next_hop_address;
5783   int count = 1;
5784   int j;
5785   f64 before = 0;
5786   u32 random_add_del = 0;
5787   u32 *random_vector = 0;
5788   uword *random_hash;
5789   u32 random_seed = 0xdeaddabe;
5790   u32 classify_table_index = ~0;
5791   u8 is_classify = 0;
5792   u8 resolve_host = 0, resolve_attached = 0;
5793   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5794
5795   /* Parse args required to build the message */
5796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5797     {
5798       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5799         sw_if_index_set = 1;
5800       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5801         sw_if_index_set = 1;
5802       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5803         {
5804           address_set = 1;
5805           is_ipv6 = 0;
5806         }
5807       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5808         {
5809           address_set = 1;
5810           is_ipv6 = 1;
5811         }
5812       else if (unformat (i, "/%d", &dst_address_length))
5813         {
5814           address_length_set = 1;
5815         }
5816
5817       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5818                                          &v4_next_hop_address))
5819         {
5820           next_hop_set = 1;
5821         }
5822       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5823                                          &v6_next_hop_address))
5824         {
5825           next_hop_set = 1;
5826         }
5827       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5828         ;
5829       else if (unformat (i, "weight %d", &next_hop_weight))
5830         ;
5831       else if (unformat (i, "drop"))
5832         {
5833           is_drop = 1;
5834         }
5835       else if (unformat (i, "null-send-unreach"))
5836         {
5837           is_unreach = 1;
5838         }
5839       else if (unformat (i, "null-send-prohibit"))
5840         {
5841           is_prohibit = 1;
5842         }
5843       else if (unformat (i, "local"))
5844         {
5845           is_local = 1;
5846         }
5847       else if (unformat (i, "classify %d", &classify_table_index))
5848         {
5849           is_classify = 1;
5850         }
5851       else if (unformat (i, "del"))
5852         is_add = 0;
5853       else if (unformat (i, "add"))
5854         is_add = 1;
5855       else if (unformat (i, "not-last"))
5856         not_last = 1;
5857       else if (unformat (i, "resolve-via-host"))
5858         resolve_host = 1;
5859       else if (unformat (i, "resolve-via-attached"))
5860         resolve_attached = 1;
5861       else if (unformat (i, "multipath"))
5862         is_multipath = 1;
5863       else if (unformat (i, "vrf %d", &vrf_id))
5864         ;
5865       else if (unformat (i, "create-vrf"))
5866         create_vrf_if_needed = 1;
5867       else if (unformat (i, "count %d", &count))
5868         ;
5869       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
5870         ;
5871       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
5872         ;
5873       else if (unformat (i, "out-label %d", &next_hop_out_label))
5874         ;
5875       else if (unformat (i, "random"))
5876         random_add_del = 1;
5877       else if (unformat (i, "seed %d", &random_seed))
5878         ;
5879       else
5880         {
5881           clib_warning ("parse error '%U'", format_unformat_error, i);
5882           return -99;
5883         }
5884     }
5885
5886   if (resolve_attempts > 0 && sw_if_index_set == 0)
5887     {
5888       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5889       return -99;
5890     }
5891
5892   if (!next_hop_set && !is_drop && !is_local &&
5893       !is_classify && !is_unreach && !is_prohibit)
5894     {
5895       errmsg
5896         ("next hop / local / drop / unreach / prohibit / classify not set\n");
5897       return -99;
5898     }
5899
5900   if (address_set == 0)
5901     {
5902       errmsg ("missing addresses\n");
5903       return -99;
5904     }
5905
5906   if (address_length_set == 0)
5907     {
5908       errmsg ("missing address length\n");
5909       return -99;
5910     }
5911
5912   /* Generate a pile of unique, random routes */
5913   if (random_add_del)
5914     {
5915       u32 this_random_address;
5916       random_hash = hash_create (count, sizeof (uword));
5917
5918       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5919       for (j = 0; j <= count; j++)
5920         {
5921           do
5922             {
5923               this_random_address = random_u32 (&random_seed);
5924               this_random_address =
5925                 clib_host_to_net_u32 (this_random_address);
5926             }
5927           while (hash_get (random_hash, this_random_address));
5928           vec_add1 (random_vector, this_random_address);
5929           hash_set (random_hash, this_random_address, 1);
5930         }
5931       hash_free (random_hash);
5932       v4_dst_address.as_u32 = random_vector[0];
5933     }
5934
5935   if (count > 1)
5936     {
5937       /* Turn on async mode */
5938       vam->async_mode = 1;
5939       vam->async_errors = 0;
5940       before = vat_time_now (vam);
5941     }
5942
5943   for (j = 0; j < count; j++)
5944     {
5945       /* Construct the API message */
5946       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5947
5948       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5949       mp->table_id = ntohl (vrf_id);
5950       if (resolve_attempts > 0)
5951         {
5952           mp->resolve_attempts = ntohl (resolve_attempts);
5953           mp->resolve_if_needed = 1;
5954         }
5955       mp->create_vrf_if_needed = create_vrf_if_needed;
5956
5957       mp->is_add = is_add;
5958       mp->is_drop = is_drop;
5959       mp->is_unreach = is_unreach;
5960       mp->is_prohibit = is_prohibit;
5961       mp->is_ipv6 = is_ipv6;
5962       mp->is_local = is_local;
5963       mp->is_classify = is_classify;
5964       mp->is_multipath = is_multipath;
5965       mp->is_resolve_host = resolve_host;
5966       mp->is_resolve_attached = resolve_attached;
5967       mp->not_last = not_last;
5968       mp->next_hop_weight = next_hop_weight;
5969       mp->dst_address_length = dst_address_length;
5970       mp->next_hop_table_id = ntohl (next_hop_table_id);
5971       mp->classify_table_index = ntohl (classify_table_index);
5972       mp->next_hop_out_label = ntohl (next_hop_out_label);
5973
5974       if (is_ipv6)
5975         {
5976           clib_memcpy (mp->dst_address, &v6_dst_address,
5977                        sizeof (v6_dst_address));
5978           if (next_hop_set)
5979             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5980                          sizeof (v6_next_hop_address));
5981           increment_v6_address (&v6_dst_address);
5982         }
5983       else
5984         {
5985           clib_memcpy (mp->dst_address, &v4_dst_address,
5986                        sizeof (v4_dst_address));
5987           if (next_hop_set)
5988             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5989                          sizeof (v4_next_hop_address));
5990           if (random_add_del)
5991             v4_dst_address.as_u32 = random_vector[j + 1];
5992           else
5993             increment_v4_address (&v4_dst_address);
5994         }
5995       /* send it... */
5996       S;
5997       /* If we receive SIGTERM, stop now... */
5998       if (vam->do_exit)
5999         break;
6000     }
6001
6002   /* When testing multiple add/del ops, use a control-ping to sync */
6003   if (count > 1)
6004     {
6005       vl_api_control_ping_t *mp;
6006       f64 after;
6007
6008       /* Shut off async mode */
6009       vam->async_mode = 0;
6010
6011       M (CONTROL_PING, control_ping);
6012       S;
6013
6014       timeout = vat_time_now (vam) + 1.0;
6015       while (vat_time_now (vam) < timeout)
6016         if (vam->result_ready == 1)
6017           goto out;
6018       vam->retval = -99;
6019
6020     out:
6021       if (vam->retval == -99)
6022         errmsg ("timeout\n");
6023
6024       if (vam->async_errors > 0)
6025         {
6026           errmsg ("%d asynchronous errors\n", vam->async_errors);
6027           vam->retval = -98;
6028         }
6029       vam->async_errors = 0;
6030       after = vat_time_now (vam);
6031
6032       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6033       if (j > 0)
6034         count = j;
6035
6036       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6037                count, after - before, count / (after - before));
6038     }
6039   else
6040     {
6041       /* Wait for a reply... */
6042       W;
6043     }
6044
6045   /* Return the good/bad news */
6046   return (vam->retval);
6047 }
6048
6049 static int
6050 api_mpls_route_add_del (vat_main_t * vam)
6051 {
6052   unformat_input_t *i = vam->input;
6053   vl_api_mpls_route_add_del_t *mp;
6054   f64 timeout;
6055   u32 sw_if_index = ~0, table_id = 0;
6056   u8 create_table_if_needed = 0;
6057   u8 is_add = 1;
6058   u32 next_hop_weight = 1;
6059   u8 is_multipath = 0;
6060   u32 next_hop_table_id = 0;
6061   u8 next_hop_set = 0;
6062   ip4_address_t v4_next_hop_address = {
6063     .as_u32 = 0,
6064   };
6065   ip6_address_t v6_next_hop_address = { {0} };
6066   int count = 1;
6067   int j;
6068   f64 before = 0;
6069   u32 classify_table_index = ~0;
6070   u8 is_classify = 0;
6071   u8 resolve_host = 0, resolve_attached = 0;
6072   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6073   mpls_label_t local_label = MPLS_LABEL_INVALID;
6074   u8 is_eos = 1;
6075   u8 next_hop_proto_is_ip4 = 1;
6076
6077   /* Parse args required to build the message */
6078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6079     {
6080       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6081         ;
6082       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6083         ;
6084       else if (unformat (i, "%d", &local_label))
6085         ;
6086       else if (unformat (i, "eos"))
6087         is_eos = 1;
6088       else if (unformat (i, "non-eos"))
6089         is_eos = 0;
6090       else if (unformat (i, "via %U", unformat_ip4_address,
6091                          &v4_next_hop_address))
6092         {
6093           next_hop_set = 1;
6094           next_hop_proto_is_ip4 = 1;
6095         }
6096       else if (unformat (i, "via %U", unformat_ip6_address,
6097                          &v6_next_hop_address))
6098         {
6099           next_hop_set = 1;
6100           next_hop_proto_is_ip4 = 0;
6101         }
6102       else if (unformat (i, "weight %d", &next_hop_weight))
6103         ;
6104       else if (unformat (i, "create-table"))
6105         create_table_if_needed = 1;
6106       else if (unformat (i, "classify %d", &classify_table_index))
6107         {
6108           is_classify = 1;
6109         }
6110       else if (unformat (i, "del"))
6111         is_add = 0;
6112       else if (unformat (i, "add"))
6113         is_add = 1;
6114       else if (unformat (i, "resolve-via-host"))
6115         resolve_host = 1;
6116       else if (unformat (i, "resolve-via-attached"))
6117         resolve_attached = 1;
6118       else if (unformat (i, "multipath"))
6119         is_multipath = 1;
6120       else if (unformat (i, "count %d", &count))
6121         ;
6122       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6123         {
6124           next_hop_set = 1;
6125           next_hop_proto_is_ip4 = 1;
6126         }
6127       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6128         {
6129           next_hop_set = 1;
6130           next_hop_proto_is_ip4 = 0;
6131         }
6132       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6133         ;
6134       else if (unformat (i, "out-label %d", &next_hop_out_label))
6135         ;
6136       else
6137         {
6138           clib_warning ("parse error '%U'", format_unformat_error, i);
6139           return -99;
6140         }
6141     }
6142
6143   if (!next_hop_set && !is_classify)
6144     {
6145       errmsg ("next hop / classify not set\n");
6146       return -99;
6147     }
6148
6149   if (MPLS_LABEL_INVALID == local_label)
6150     {
6151       errmsg ("missing label\n");
6152       return -99;
6153     }
6154
6155   if (count > 1)
6156     {
6157       /* Turn on async mode */
6158       vam->async_mode = 1;
6159       vam->async_errors = 0;
6160       before = vat_time_now (vam);
6161     }
6162
6163   for (j = 0; j < count; j++)
6164     {
6165       /* Construct the API message */
6166       M (MPLS_ROUTE_ADD_DEL, mpls_route_add_del);
6167
6168       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6169       mp->mr_table_id = ntohl (table_id);
6170       mp->mr_create_table_if_needed = create_table_if_needed;
6171
6172       mp->mr_is_add = is_add;
6173       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6174       mp->mr_is_classify = is_classify;
6175       mp->mr_is_multipath = is_multipath;
6176       mp->mr_is_resolve_host = resolve_host;
6177       mp->mr_is_resolve_attached = resolve_attached;
6178       mp->mr_next_hop_weight = next_hop_weight;
6179       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6180       mp->mr_classify_table_index = ntohl (classify_table_index);
6181       mp->mr_next_hop_out_label = ntohl (next_hop_out_label);
6182       mp->mr_label = ntohl (local_label);
6183       mp->mr_eos = is_eos;
6184
6185       if (next_hop_set)
6186         {
6187           if (next_hop_proto_is_ip4)
6188             {
6189               clib_memcpy (mp->mr_next_hop,
6190                            &v4_next_hop_address,
6191                            sizeof (v4_next_hop_address));
6192             }
6193           else
6194             {
6195               clib_memcpy (mp->mr_next_hop,
6196                            &v6_next_hop_address,
6197                            sizeof (v6_next_hop_address));
6198             }
6199         }
6200       local_label++;
6201
6202       /* send it... */
6203       S;
6204       /* If we receive SIGTERM, stop now... */
6205       if (vam->do_exit)
6206         break;
6207     }
6208
6209   /* When testing multiple add/del ops, use a control-ping to sync */
6210   if (count > 1)
6211     {
6212       vl_api_control_ping_t *mp;
6213       f64 after;
6214
6215       /* Shut off async mode */
6216       vam->async_mode = 0;
6217
6218       M (CONTROL_PING, control_ping);
6219       S;
6220
6221       timeout = vat_time_now (vam) + 1.0;
6222       while (vat_time_now (vam) < timeout)
6223         if (vam->result_ready == 1)
6224           goto out;
6225       vam->retval = -99;
6226
6227     out:
6228       if (vam->retval == -99)
6229         errmsg ("timeout\n");
6230
6231       if (vam->async_errors > 0)
6232         {
6233           errmsg ("%d asynchronous errors\n", vam->async_errors);
6234           vam->retval = -98;
6235         }
6236       vam->async_errors = 0;
6237       after = vat_time_now (vam);
6238
6239       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6240       if (j > 0)
6241         count = j;
6242
6243       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6244                count, after - before, count / (after - before));
6245     }
6246   else
6247     {
6248       /* Wait for a reply... */
6249       W;
6250     }
6251
6252   /* Return the good/bad news */
6253   return (vam->retval);
6254 }
6255
6256 static int
6257 api_mpls_ip_bind_unbind (vat_main_t * vam)
6258 {
6259   unformat_input_t *i = vam->input;
6260   vl_api_mpls_ip_bind_unbind_t *mp;
6261   f64 timeout;
6262   u32 ip_table_id = 0;
6263   u8 create_table_if_needed = 0;
6264   u8 is_bind = 1;
6265   u8 is_ip4 = 1;
6266   ip4_address_t v4_address;
6267   ip6_address_t v6_address;
6268   u32 address_length;
6269   u8 address_set = 0;
6270   mpls_label_t local_label = MPLS_LABEL_INVALID;
6271
6272   /* Parse args required to build the message */
6273   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6274     {
6275       if (unformat (i, "%U/%d", unformat_ip4_address,
6276                     &v4_address, &address_length))
6277         {
6278           is_ip4 = 1;
6279           address_set = 1;
6280         }
6281       else if (unformat (i, "%U/%d", unformat_ip6_address,
6282                          &v6_address, &address_length))
6283         {
6284           is_ip4 = 0;
6285           address_set = 1;
6286         }
6287       else if (unformat (i, "%d", &local_label))
6288         ;
6289       else if (unformat (i, "create-table"))
6290         create_table_if_needed = 1;
6291       else if (unformat (i, "table-id %d", &ip_table_id))
6292         ;
6293       else if (unformat (i, "unbind"))
6294         is_bind = 0;
6295       else if (unformat (i, "bind"))
6296         is_bind = 1;
6297       else
6298         {
6299           clib_warning ("parse error '%U'", format_unformat_error, i);
6300           return -99;
6301         }
6302     }
6303
6304   if (!address_set)
6305     {
6306       errmsg ("IP addres not set\n");
6307       return -99;
6308     }
6309
6310   if (MPLS_LABEL_INVALID == local_label)
6311     {
6312       errmsg ("missing label\n");
6313       return -99;
6314     }
6315
6316   /* Construct the API message */
6317   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6318
6319   mp->mb_create_table_if_needed = create_table_if_needed;
6320   mp->mb_is_bind = is_bind;
6321   mp->mb_is_ip4 = is_ip4;
6322   mp->mb_ip_table_id = ntohl (ip_table_id);
6323   mp->mb_mpls_table_id = 0;
6324   mp->mb_label = ntohl (local_label);
6325   mp->mb_address_length = address_length;
6326
6327   if (is_ip4)
6328     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6329   else
6330     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6331
6332   /* send it... */
6333   S;
6334
6335   /* Wait for a reply... */
6336   W;
6337 }
6338
6339 static int
6340 api_proxy_arp_add_del (vat_main_t * vam)
6341 {
6342   unformat_input_t *i = vam->input;
6343   vl_api_proxy_arp_add_del_t *mp;
6344   f64 timeout;
6345   u32 vrf_id = 0;
6346   u8 is_add = 1;
6347   ip4_address_t lo, hi;
6348   u8 range_set = 0;
6349
6350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6351     {
6352       if (unformat (i, "vrf %d", &vrf_id))
6353         ;
6354       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6355                          unformat_ip4_address, &hi))
6356         range_set = 1;
6357       else if (unformat (i, "del"))
6358         is_add = 0;
6359       else
6360         {
6361           clib_warning ("parse error '%U'", format_unformat_error, i);
6362           return -99;
6363         }
6364     }
6365
6366   if (range_set == 0)
6367     {
6368       errmsg ("address range not set\n");
6369       return -99;
6370     }
6371
6372   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6373
6374   mp->vrf_id = ntohl (vrf_id);
6375   mp->is_add = is_add;
6376   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6377   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6378
6379   S;
6380   W;
6381   /* NOTREACHED */
6382   return 0;
6383 }
6384
6385 static int
6386 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6387 {
6388   unformat_input_t *i = vam->input;
6389   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6390   f64 timeout;
6391   u32 sw_if_index;
6392   u8 enable = 1;
6393   u8 sw_if_index_set = 0;
6394
6395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6396     {
6397       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6398         sw_if_index_set = 1;
6399       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6400         sw_if_index_set = 1;
6401       else if (unformat (i, "enable"))
6402         enable = 1;
6403       else if (unformat (i, "disable"))
6404         enable = 0;
6405       else
6406         {
6407           clib_warning ("parse error '%U'", format_unformat_error, i);
6408           return -99;
6409         }
6410     }
6411
6412   if (sw_if_index_set == 0)
6413     {
6414       errmsg ("missing interface name or sw_if_index\n");
6415       return -99;
6416     }
6417
6418   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6419
6420   mp->sw_if_index = ntohl (sw_if_index);
6421   mp->enable_disable = enable;
6422
6423   S;
6424   W;
6425   /* NOTREACHED */
6426   return 0;
6427 }
6428
6429 static int
6430 api_mpls_add_del_encap (vat_main_t * vam)
6431 {
6432   unformat_input_t *i = vam->input;
6433   vl_api_mpls_add_del_encap_t *mp;
6434   f64 timeout;
6435   u32 vrf_id = 0;
6436   u32 *labels = 0;
6437   u32 label;
6438   ip4_address_t dst_address;
6439   u8 is_add = 1;
6440
6441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6442     {
6443       if (unformat (i, "vrf %d", &vrf_id))
6444         ;
6445       else if (unformat (i, "label %d", &label))
6446         vec_add1 (labels, ntohl (label));
6447       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6448         ;
6449       else if (unformat (i, "del"))
6450         is_add = 0;
6451       else
6452         {
6453           clib_warning ("parse error '%U'", format_unformat_error, i);
6454           return -99;
6455         }
6456     }
6457
6458   if (vec_len (labels) == 0)
6459     {
6460       errmsg ("missing encap label stack\n");
6461       return -99;
6462     }
6463
6464   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6465       sizeof (u32) * vec_len (labels));
6466
6467   mp->vrf_id = ntohl (vrf_id);
6468   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6469   mp->is_add = is_add;
6470   mp->nlabels = vec_len (labels);
6471   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6472
6473   vec_free (labels);
6474
6475   S;
6476   W;
6477   /* NOTREACHED */
6478   return 0;
6479 }
6480
6481 static int
6482 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6483 {
6484   unformat_input_t *i = vam->input;
6485   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6486   f64 timeout;
6487   u32 inner_vrf_id = 0;
6488   ip4_address_t intfc_address;
6489   u8 dst_mac_address[6];
6490   int dst_set = 1;
6491   u32 tmp;
6492   u8 intfc_address_length = 0;
6493   u8 is_add = 1;
6494   u8 l2_only = 0;
6495   u32 tx_sw_if_index;
6496   int tx_sw_if_index_set = 0;
6497
6498   /* Shut up coverity */
6499   memset (dst_mac_address, 0, sizeof (dst_mac_address));
6500
6501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6502     {
6503       if (unformat (i, "vrf %d", &inner_vrf_id))
6504         ;
6505       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6506                          &intfc_address, &tmp))
6507         intfc_address_length = tmp;
6508       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6509         tx_sw_if_index_set = 1;
6510       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6511         tx_sw_if_index_set = 1;
6512       else if (unformat (i, "dst %U", unformat_ethernet_address,
6513                          dst_mac_address))
6514         dst_set = 1;
6515       else if (unformat (i, "l2-only"))
6516         l2_only = 1;
6517       else if (unformat (i, "del"))
6518         is_add = 0;
6519       else
6520         {
6521           clib_warning ("parse error '%U'", format_unformat_error, i);
6522           return -99;
6523         }
6524     }
6525
6526   if (!dst_set)
6527     {
6528       errmsg ("dst (mac address) not set\n");
6529       return -99;
6530     }
6531   if (!tx_sw_if_index_set)
6532     {
6533       errmsg ("tx-intfc not set\n");
6534       return -99;
6535     }
6536
6537   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6538
6539   mp->vrf_id = ntohl (inner_vrf_id);
6540   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6541   mp->adj_address_length = intfc_address_length;
6542   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6543                sizeof (dst_mac_address));
6544   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6545   mp->l2_only = l2_only;
6546   mp->is_add = is_add;
6547
6548   S;
6549   W;
6550   /* NOTREACHED */
6551   return 0;
6552 }
6553
6554 static int
6555 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6556 {
6557   unformat_input_t *i = vam->input;
6558   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6559   f64 timeout;
6560   u32 inner_vrf_id = 0;
6561   u32 outer_vrf_id = 0;
6562   ip4_address_t adj_address;
6563   int adj_address_set = 0;
6564   ip4_address_t next_hop_address;
6565   int next_hop_address_set = 0;
6566   u32 tmp;
6567   u8 adj_address_length = 0;
6568   u8 l2_only = 0;
6569   u8 is_add = 1;
6570   u32 resolve_attempts = 5;
6571   u8 resolve_if_needed = 1;
6572
6573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6574     {
6575       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6576         ;
6577       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6578         ;
6579       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6580                          &adj_address, &tmp))
6581         {
6582           adj_address_length = tmp;
6583           adj_address_set = 1;
6584         }
6585       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6586                          &next_hop_address))
6587         next_hop_address_set = 1;
6588       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6589         ;
6590       else if (unformat (i, "resolve-if-needed %d", &tmp))
6591         resolve_if_needed = tmp;
6592       else if (unformat (i, "l2-only"))
6593         l2_only = 1;
6594       else if (unformat (i, "del"))
6595         is_add = 0;
6596       else
6597         {
6598           clib_warning ("parse error '%U'", format_unformat_error, i);
6599           return -99;
6600         }
6601     }
6602
6603   if (!adj_address_set)
6604     {
6605       errmsg ("adjacency address/mask not set\n");
6606       return -99;
6607     }
6608   if (!next_hop_address_set)
6609     {
6610       errmsg ("ip4 next hop address (in outer fib) not set\n");
6611       return -99;
6612     }
6613
6614   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6615
6616   mp->inner_vrf_id = ntohl (inner_vrf_id);
6617   mp->outer_vrf_id = ntohl (outer_vrf_id);
6618   mp->resolve_attempts = ntohl (resolve_attempts);
6619   mp->resolve_if_needed = resolve_if_needed;
6620   mp->is_add = is_add;
6621   mp->l2_only = l2_only;
6622   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6623   mp->adj_address_length = adj_address_length;
6624   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6625                sizeof (next_hop_address));
6626
6627   S;
6628   W;
6629   /* NOTREACHED */
6630   return 0;
6631 }
6632
6633 static int
6634 api_sw_interface_set_unnumbered (vat_main_t * vam)
6635 {
6636   unformat_input_t *i = vam->input;
6637   vl_api_sw_interface_set_unnumbered_t *mp;
6638   f64 timeout;
6639   u32 sw_if_index;
6640   u32 unnum_sw_index = ~0;
6641   u8 is_add = 1;
6642   u8 sw_if_index_set = 0;
6643
6644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6645     {
6646       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6647         sw_if_index_set = 1;
6648       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6649         sw_if_index_set = 1;
6650       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6651         ;
6652       else if (unformat (i, "del"))
6653         is_add = 0;
6654       else
6655         {
6656           clib_warning ("parse error '%U'", format_unformat_error, i);
6657           return -99;
6658         }
6659     }
6660
6661   if (sw_if_index_set == 0)
6662     {
6663       errmsg ("missing interface name or sw_if_index\n");
6664       return -99;
6665     }
6666
6667   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6668
6669   mp->sw_if_index = ntohl (sw_if_index);
6670   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6671   mp->is_add = is_add;
6672
6673   S;
6674   W;
6675   /* NOTREACHED */
6676   return 0;
6677 }
6678
6679 static int
6680 api_ip_neighbor_add_del (vat_main_t * vam)
6681 {
6682   unformat_input_t *i = vam->input;
6683   vl_api_ip_neighbor_add_del_t *mp;
6684   f64 timeout;
6685   u32 sw_if_index;
6686   u8 sw_if_index_set = 0;
6687   u32 vrf_id = 0;
6688   u8 is_add = 1;
6689   u8 is_static = 0;
6690   u8 mac_address[6];
6691   u8 mac_set = 0;
6692   u8 v4_address_set = 0;
6693   u8 v6_address_set = 0;
6694   ip4_address_t v4address;
6695   ip6_address_t v6address;
6696
6697   memset (mac_address, 0, sizeof (mac_address));
6698
6699   /* Parse args required to build the message */
6700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6701     {
6702       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6703         {
6704           mac_set = 1;
6705         }
6706       else if (unformat (i, "del"))
6707         is_add = 0;
6708       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6709         sw_if_index_set = 1;
6710       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6711         sw_if_index_set = 1;
6712       else if (unformat (i, "is_static"))
6713         is_static = 1;
6714       else if (unformat (i, "vrf %d", &vrf_id))
6715         ;
6716       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6717         v4_address_set = 1;
6718       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6719         v6_address_set = 1;
6720       else
6721         {
6722           clib_warning ("parse error '%U'", format_unformat_error, i);
6723           return -99;
6724         }
6725     }
6726
6727   if (sw_if_index_set == 0)
6728     {
6729       errmsg ("missing interface name or sw_if_index\n");
6730       return -99;
6731     }
6732   if (v4_address_set && v6_address_set)
6733     {
6734       errmsg ("both v4 and v6 addresses set\n");
6735       return -99;
6736     }
6737   if (!v4_address_set && !v6_address_set)
6738     {
6739       errmsg ("no address set\n");
6740       return -99;
6741     }
6742
6743   /* Construct the API message */
6744   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6745
6746   mp->sw_if_index = ntohl (sw_if_index);
6747   mp->is_add = is_add;
6748   mp->vrf_id = ntohl (vrf_id);
6749   mp->is_static = is_static;
6750   if (mac_set)
6751     clib_memcpy (mp->mac_address, mac_address, 6);
6752   if (v6_address_set)
6753     {
6754       mp->is_ipv6 = 1;
6755       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6756     }
6757   else
6758     {
6759       /* mp->is_ipv6 = 0; via memset in M macro above */
6760       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6761     }
6762
6763   /* send it... */
6764   S;
6765
6766   /* Wait for a reply, return good/bad news  */
6767   W;
6768
6769   /* NOTREACHED */
6770   return 0;
6771 }
6772
6773 static int
6774 api_reset_vrf (vat_main_t * vam)
6775 {
6776   unformat_input_t *i = vam->input;
6777   vl_api_reset_vrf_t *mp;
6778   f64 timeout;
6779   u32 vrf_id = 0;
6780   u8 is_ipv6 = 0;
6781   u8 vrf_id_set = 0;
6782
6783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6784     {
6785       if (unformat (i, "vrf %d", &vrf_id))
6786         vrf_id_set = 1;
6787       else if (unformat (i, "ipv6"))
6788         is_ipv6 = 1;
6789       else
6790         {
6791           clib_warning ("parse error '%U'", format_unformat_error, i);
6792           return -99;
6793         }
6794     }
6795
6796   if (vrf_id_set == 0)
6797     {
6798       errmsg ("missing vrf id\n");
6799       return -99;
6800     }
6801
6802   M (RESET_VRF, reset_vrf);
6803
6804   mp->vrf_id = ntohl (vrf_id);
6805   mp->is_ipv6 = is_ipv6;
6806
6807   S;
6808   W;
6809   /* NOTREACHED */
6810   return 0;
6811 }
6812
6813 static int
6814 api_create_vlan_subif (vat_main_t * vam)
6815 {
6816   unformat_input_t *i = vam->input;
6817   vl_api_create_vlan_subif_t *mp;
6818   f64 timeout;
6819   u32 sw_if_index;
6820   u8 sw_if_index_set = 0;
6821   u32 vlan_id;
6822   u8 vlan_id_set = 0;
6823
6824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6825     {
6826       if (unformat (i, "sw_if_index %d", &sw_if_index))
6827         sw_if_index_set = 1;
6828       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6829         sw_if_index_set = 1;
6830       else if (unformat (i, "vlan %d", &vlan_id))
6831         vlan_id_set = 1;
6832       else
6833         {
6834           clib_warning ("parse error '%U'", format_unformat_error, i);
6835           return -99;
6836         }
6837     }
6838
6839   if (sw_if_index_set == 0)
6840     {
6841       errmsg ("missing interface name or sw_if_index\n");
6842       return -99;
6843     }
6844
6845   if (vlan_id_set == 0)
6846     {
6847       errmsg ("missing vlan_id\n");
6848       return -99;
6849     }
6850   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6851
6852   mp->sw_if_index = ntohl (sw_if_index);
6853   mp->vlan_id = ntohl (vlan_id);
6854
6855   S;
6856   W;
6857   /* NOTREACHED */
6858   return 0;
6859 }
6860
6861 #define foreach_create_subif_bit                \
6862 _(no_tags)                                      \
6863 _(one_tag)                                      \
6864 _(two_tags)                                     \
6865 _(dot1ad)                                       \
6866 _(exact_match)                                  \
6867 _(default_sub)                                  \
6868 _(outer_vlan_id_any)                            \
6869 _(inner_vlan_id_any)
6870
6871 static int
6872 api_create_subif (vat_main_t * vam)
6873 {
6874   unformat_input_t *i = vam->input;
6875   vl_api_create_subif_t *mp;
6876   f64 timeout;
6877   u32 sw_if_index;
6878   u8 sw_if_index_set = 0;
6879   u32 sub_id;
6880   u8 sub_id_set = 0;
6881   u32 no_tags = 0;
6882   u32 one_tag = 0;
6883   u32 two_tags = 0;
6884   u32 dot1ad = 0;
6885   u32 exact_match = 0;
6886   u32 default_sub = 0;
6887   u32 outer_vlan_id_any = 0;
6888   u32 inner_vlan_id_any = 0;
6889   u32 tmp;
6890   u16 outer_vlan_id = 0;
6891   u16 inner_vlan_id = 0;
6892
6893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6894     {
6895       if (unformat (i, "sw_if_index %d", &sw_if_index))
6896         sw_if_index_set = 1;
6897       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6898         sw_if_index_set = 1;
6899       else if (unformat (i, "sub_id %d", &sub_id))
6900         sub_id_set = 1;
6901       else if (unformat (i, "outer_vlan_id %d", &tmp))
6902         outer_vlan_id = tmp;
6903       else if (unformat (i, "inner_vlan_id %d", &tmp))
6904         inner_vlan_id = tmp;
6905
6906 #define _(a) else if (unformat (i, #a)) a = 1 ;
6907       foreach_create_subif_bit
6908 #undef _
6909         else
6910         {
6911           clib_warning ("parse error '%U'", format_unformat_error, i);
6912           return -99;
6913         }
6914     }
6915
6916   if (sw_if_index_set == 0)
6917     {
6918       errmsg ("missing interface name or sw_if_index\n");
6919       return -99;
6920     }
6921
6922   if (sub_id_set == 0)
6923     {
6924       errmsg ("missing sub_id\n");
6925       return -99;
6926     }
6927   M (CREATE_SUBIF, create_subif);
6928
6929   mp->sw_if_index = ntohl (sw_if_index);
6930   mp->sub_id = ntohl (sub_id);
6931
6932 #define _(a) mp->a = a;
6933   foreach_create_subif_bit;
6934 #undef _
6935
6936   mp->outer_vlan_id = ntohs (outer_vlan_id);
6937   mp->inner_vlan_id = ntohs (inner_vlan_id);
6938
6939   S;
6940   W;
6941   /* NOTREACHED */
6942   return 0;
6943 }
6944
6945 static int
6946 api_oam_add_del (vat_main_t * vam)
6947 {
6948   unformat_input_t *i = vam->input;
6949   vl_api_oam_add_del_t *mp;
6950   f64 timeout;
6951   u32 vrf_id = 0;
6952   u8 is_add = 1;
6953   ip4_address_t src, dst;
6954   u8 src_set = 0;
6955   u8 dst_set = 0;
6956
6957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6958     {
6959       if (unformat (i, "vrf %d", &vrf_id))
6960         ;
6961       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6962         src_set = 1;
6963       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6964         dst_set = 1;
6965       else if (unformat (i, "del"))
6966         is_add = 0;
6967       else
6968         {
6969           clib_warning ("parse error '%U'", format_unformat_error, i);
6970           return -99;
6971         }
6972     }
6973
6974   if (src_set == 0)
6975     {
6976       errmsg ("missing src addr\n");
6977       return -99;
6978     }
6979
6980   if (dst_set == 0)
6981     {
6982       errmsg ("missing dst addr\n");
6983       return -99;
6984     }
6985
6986   M (OAM_ADD_DEL, oam_add_del);
6987
6988   mp->vrf_id = ntohl (vrf_id);
6989   mp->is_add = is_add;
6990   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6991   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6992
6993   S;
6994   W;
6995   /* NOTREACHED */
6996   return 0;
6997 }
6998
6999 static int
7000 api_reset_fib (vat_main_t * vam)
7001 {
7002   unformat_input_t *i = vam->input;
7003   vl_api_reset_fib_t *mp;
7004   f64 timeout;
7005   u32 vrf_id = 0;
7006   u8 is_ipv6 = 0;
7007   u8 vrf_id_set = 0;
7008
7009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7010     {
7011       if (unformat (i, "vrf %d", &vrf_id))
7012         vrf_id_set = 1;
7013       else if (unformat (i, "ipv6"))
7014         is_ipv6 = 1;
7015       else
7016         {
7017           clib_warning ("parse error '%U'", format_unformat_error, i);
7018           return -99;
7019         }
7020     }
7021
7022   if (vrf_id_set == 0)
7023     {
7024       errmsg ("missing vrf id\n");
7025       return -99;
7026     }
7027
7028   M (RESET_FIB, reset_fib);
7029
7030   mp->vrf_id = ntohl (vrf_id);
7031   mp->is_ipv6 = is_ipv6;
7032
7033   S;
7034   W;
7035   /* NOTREACHED */
7036   return 0;
7037 }
7038
7039 static int
7040 api_dhcp_proxy_config (vat_main_t * vam)
7041 {
7042   unformat_input_t *i = vam->input;
7043   vl_api_dhcp_proxy_config_t *mp;
7044   f64 timeout;
7045   u32 vrf_id = 0;
7046   u8 is_add = 1;
7047   u8 insert_cid = 1;
7048   u8 v4_address_set = 0;
7049   u8 v6_address_set = 0;
7050   ip4_address_t v4address;
7051   ip6_address_t v6address;
7052   u8 v4_src_address_set = 0;
7053   u8 v6_src_address_set = 0;
7054   ip4_address_t v4srcaddress;
7055   ip6_address_t v6srcaddress;
7056
7057   /* Parse args required to build the message */
7058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7059     {
7060       if (unformat (i, "del"))
7061         is_add = 0;
7062       else if (unformat (i, "vrf %d", &vrf_id))
7063         ;
7064       else if (unformat (i, "insert-cid %d", &insert_cid))
7065         ;
7066       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7067         v4_address_set = 1;
7068       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7069         v6_address_set = 1;
7070       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7071         v4_src_address_set = 1;
7072       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7073         v6_src_address_set = 1;
7074       else
7075         break;
7076     }
7077
7078   if (v4_address_set && v6_address_set)
7079     {
7080       errmsg ("both v4 and v6 server addresses set\n");
7081       return -99;
7082     }
7083   if (!v4_address_set && !v6_address_set)
7084     {
7085       errmsg ("no server addresses set\n");
7086       return -99;
7087     }
7088
7089   if (v4_src_address_set && v6_src_address_set)
7090     {
7091       errmsg ("both v4 and v6  src addresses set\n");
7092       return -99;
7093     }
7094   if (!v4_src_address_set && !v6_src_address_set)
7095     {
7096       errmsg ("no src addresses set\n");
7097       return -99;
7098     }
7099
7100   if (!(v4_src_address_set && v4_address_set) &&
7101       !(v6_src_address_set && v6_address_set))
7102     {
7103       errmsg ("no matching server and src addresses set\n");
7104       return -99;
7105     }
7106
7107   /* Construct the API message */
7108   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7109
7110   mp->insert_circuit_id = insert_cid;
7111   mp->is_add = is_add;
7112   mp->vrf_id = ntohl (vrf_id);
7113   if (v6_address_set)
7114     {
7115       mp->is_ipv6 = 1;
7116       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7117       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7118     }
7119   else
7120     {
7121       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7122       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7123     }
7124
7125   /* send it... */
7126   S;
7127
7128   /* Wait for a reply, return good/bad news  */
7129   W;
7130   /* NOTREACHED */
7131   return 0;
7132 }
7133
7134 static int
7135 api_dhcp_proxy_config_2 (vat_main_t * vam)
7136 {
7137   unformat_input_t *i = vam->input;
7138   vl_api_dhcp_proxy_config_2_t *mp;
7139   f64 timeout;
7140   u32 rx_vrf_id = 0;
7141   u32 server_vrf_id = 0;
7142   u8 is_add = 1;
7143   u8 insert_cid = 1;
7144   u8 v4_address_set = 0;
7145   u8 v6_address_set = 0;
7146   ip4_address_t v4address;
7147   ip6_address_t v6address;
7148   u8 v4_src_address_set = 0;
7149   u8 v6_src_address_set = 0;
7150   ip4_address_t v4srcaddress;
7151   ip6_address_t v6srcaddress;
7152
7153   /* Parse args required to build the message */
7154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7155     {
7156       if (unformat (i, "del"))
7157         is_add = 0;
7158       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7159         ;
7160       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7161         ;
7162       else if (unformat (i, "insert-cid %d", &insert_cid))
7163         ;
7164       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7165         v4_address_set = 1;
7166       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7167         v6_address_set = 1;
7168       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7169         v4_src_address_set = 1;
7170       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7171         v6_src_address_set = 1;
7172       else
7173         break;
7174     }
7175
7176   if (v4_address_set && v6_address_set)
7177     {
7178       errmsg ("both v4 and v6 server addresses set\n");
7179       return -99;
7180     }
7181   if (!v4_address_set && !v6_address_set)
7182     {
7183       errmsg ("no server addresses set\n");
7184       return -99;
7185     }
7186
7187   if (v4_src_address_set && v6_src_address_set)
7188     {
7189       errmsg ("both v4 and v6  src addresses set\n");
7190       return -99;
7191     }
7192   if (!v4_src_address_set && !v6_src_address_set)
7193     {
7194       errmsg ("no src addresses set\n");
7195       return -99;
7196     }
7197
7198   if (!(v4_src_address_set && v4_address_set) &&
7199       !(v6_src_address_set && v6_address_set))
7200     {
7201       errmsg ("no matching server and src addresses set\n");
7202       return -99;
7203     }
7204
7205   /* Construct the API message */
7206   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7207
7208   mp->insert_circuit_id = insert_cid;
7209   mp->is_add = is_add;
7210   mp->rx_vrf_id = ntohl (rx_vrf_id);
7211   mp->server_vrf_id = ntohl (server_vrf_id);
7212   if (v6_address_set)
7213     {
7214       mp->is_ipv6 = 1;
7215       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7216       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7217     }
7218   else
7219     {
7220       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7221       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7222     }
7223
7224   /* send it... */
7225   S;
7226
7227   /* Wait for a reply, return good/bad news  */
7228   W;
7229   /* NOTREACHED */
7230   return 0;
7231 }
7232
7233 static int
7234 api_dhcp_proxy_set_vss (vat_main_t * vam)
7235 {
7236   unformat_input_t *i = vam->input;
7237   vl_api_dhcp_proxy_set_vss_t *mp;
7238   f64 timeout;
7239   u8 is_ipv6 = 0;
7240   u8 is_add = 1;
7241   u32 tbl_id;
7242   u8 tbl_id_set = 0;
7243   u32 oui;
7244   u8 oui_set = 0;
7245   u32 fib_id;
7246   u8 fib_id_set = 0;
7247
7248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7249     {
7250       if (unformat (i, "tbl_id %d", &tbl_id))
7251         tbl_id_set = 1;
7252       if (unformat (i, "fib_id %d", &fib_id))
7253         fib_id_set = 1;
7254       if (unformat (i, "oui %d", &oui))
7255         oui_set = 1;
7256       else if (unformat (i, "ipv6"))
7257         is_ipv6 = 1;
7258       else if (unformat (i, "del"))
7259         is_add = 0;
7260       else
7261         {
7262           clib_warning ("parse error '%U'", format_unformat_error, i);
7263           return -99;
7264         }
7265     }
7266
7267   if (tbl_id_set == 0)
7268     {
7269       errmsg ("missing tbl id\n");
7270       return -99;
7271     }
7272
7273   if (fib_id_set == 0)
7274     {
7275       errmsg ("missing fib id\n");
7276       return -99;
7277     }
7278   if (oui_set == 0)
7279     {
7280       errmsg ("missing oui\n");
7281       return -99;
7282     }
7283
7284   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7285   mp->tbl_id = ntohl (tbl_id);
7286   mp->fib_id = ntohl (fib_id);
7287   mp->oui = ntohl (oui);
7288   mp->is_ipv6 = is_ipv6;
7289   mp->is_add = is_add;
7290
7291   S;
7292   W;
7293   /* NOTREACHED */
7294   return 0;
7295 }
7296
7297 static int
7298 api_dhcp_client_config (vat_main_t * vam)
7299 {
7300   unformat_input_t *i = vam->input;
7301   vl_api_dhcp_client_config_t *mp;
7302   f64 timeout;
7303   u32 sw_if_index;
7304   u8 sw_if_index_set = 0;
7305   u8 is_add = 1;
7306   u8 *hostname = 0;
7307   u8 disable_event = 0;
7308
7309   /* Parse args required to build the message */
7310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7311     {
7312       if (unformat (i, "del"))
7313         is_add = 0;
7314       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7315         sw_if_index_set = 1;
7316       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7317         sw_if_index_set = 1;
7318       else if (unformat (i, "hostname %s", &hostname))
7319         ;
7320       else if (unformat (i, "disable_event"))
7321         disable_event = 1;
7322       else
7323         break;
7324     }
7325
7326   if (sw_if_index_set == 0)
7327     {
7328       errmsg ("missing interface name or sw_if_index\n");
7329       return -99;
7330     }
7331
7332   if (vec_len (hostname) > 63)
7333     {
7334       errmsg ("hostname too long\n");
7335     }
7336   vec_add1 (hostname, 0);
7337
7338   /* Construct the API message */
7339   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7340
7341   mp->sw_if_index = ntohl (sw_if_index);
7342   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7343   vec_free (hostname);
7344   mp->is_add = is_add;
7345   mp->want_dhcp_event = disable_event ? 0 : 1;
7346   mp->pid = getpid ();
7347
7348   /* send it... */
7349   S;
7350
7351   /* Wait for a reply, return good/bad news  */
7352   W;
7353   /* NOTREACHED */
7354   return 0;
7355 }
7356
7357 static int
7358 api_set_ip_flow_hash (vat_main_t * vam)
7359 {
7360   unformat_input_t *i = vam->input;
7361   vl_api_set_ip_flow_hash_t *mp;
7362   f64 timeout;
7363   u32 vrf_id = 0;
7364   u8 is_ipv6 = 0;
7365   u8 vrf_id_set = 0;
7366   u8 src = 0;
7367   u8 dst = 0;
7368   u8 sport = 0;
7369   u8 dport = 0;
7370   u8 proto = 0;
7371   u8 reverse = 0;
7372
7373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7374     {
7375       if (unformat (i, "vrf %d", &vrf_id))
7376         vrf_id_set = 1;
7377       else if (unformat (i, "ipv6"))
7378         is_ipv6 = 1;
7379       else if (unformat (i, "src"))
7380         src = 1;
7381       else if (unformat (i, "dst"))
7382         dst = 1;
7383       else if (unformat (i, "sport"))
7384         sport = 1;
7385       else if (unformat (i, "dport"))
7386         dport = 1;
7387       else if (unformat (i, "proto"))
7388         proto = 1;
7389       else if (unformat (i, "reverse"))
7390         reverse = 1;
7391
7392       else
7393         {
7394           clib_warning ("parse error '%U'", format_unformat_error, i);
7395           return -99;
7396         }
7397     }
7398
7399   if (vrf_id_set == 0)
7400     {
7401       errmsg ("missing vrf id\n");
7402       return -99;
7403     }
7404
7405   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7406   mp->src = src;
7407   mp->dst = dst;
7408   mp->sport = sport;
7409   mp->dport = dport;
7410   mp->proto = proto;
7411   mp->reverse = reverse;
7412   mp->vrf_id = ntohl (vrf_id);
7413   mp->is_ipv6 = is_ipv6;
7414
7415   S;
7416   W;
7417   /* NOTREACHED */
7418   return 0;
7419 }
7420
7421 static int
7422 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7423 {
7424   unformat_input_t *i = vam->input;
7425   vl_api_sw_interface_ip6_enable_disable_t *mp;
7426   f64 timeout;
7427   u32 sw_if_index;
7428   u8 sw_if_index_set = 0;
7429   u8 enable = 0;
7430
7431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7432     {
7433       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7434         sw_if_index_set = 1;
7435       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7436         sw_if_index_set = 1;
7437       else if (unformat (i, "enable"))
7438         enable = 1;
7439       else if (unformat (i, "disable"))
7440         enable = 0;
7441       else
7442         {
7443           clib_warning ("parse error '%U'", format_unformat_error, i);
7444           return -99;
7445         }
7446     }
7447
7448   if (sw_if_index_set == 0)
7449     {
7450       errmsg ("missing interface name or sw_if_index\n");
7451       return -99;
7452     }
7453
7454   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7455
7456   mp->sw_if_index = ntohl (sw_if_index);
7457   mp->enable = enable;
7458
7459   S;
7460   W;
7461   /* NOTREACHED */
7462   return 0;
7463 }
7464
7465 static int
7466 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7467 {
7468   unformat_input_t *i = vam->input;
7469   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7470   f64 timeout;
7471   u32 sw_if_index;
7472   u8 sw_if_index_set = 0;
7473   u32 address_length = 0;
7474   u8 v6_address_set = 0;
7475   ip6_address_t v6address;
7476
7477   /* Parse args required to build the message */
7478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7479     {
7480       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7481         sw_if_index_set = 1;
7482       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7483         sw_if_index_set = 1;
7484       else if (unformat (i, "%U/%d",
7485                          unformat_ip6_address, &v6address, &address_length))
7486         v6_address_set = 1;
7487       else
7488         break;
7489     }
7490
7491   if (sw_if_index_set == 0)
7492     {
7493       errmsg ("missing interface name or sw_if_index\n");
7494       return -99;
7495     }
7496   if (!v6_address_set)
7497     {
7498       errmsg ("no address set\n");
7499       return -99;
7500     }
7501
7502   /* Construct the API message */
7503   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7504      sw_interface_ip6_set_link_local_address);
7505
7506   mp->sw_if_index = ntohl (sw_if_index);
7507   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7508   mp->address_length = address_length;
7509
7510   /* send it... */
7511   S;
7512
7513   /* Wait for a reply, return good/bad news  */
7514   W;
7515
7516   /* NOTREACHED */
7517   return 0;
7518 }
7519
7520
7521 static int
7522 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7523 {
7524   unformat_input_t *i = vam->input;
7525   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7526   f64 timeout;
7527   u32 sw_if_index;
7528   u8 sw_if_index_set = 0;
7529   u32 address_length = 0;
7530   u8 v6_address_set = 0;
7531   ip6_address_t v6address;
7532   u8 use_default = 0;
7533   u8 no_advertise = 0;
7534   u8 off_link = 0;
7535   u8 no_autoconfig = 0;
7536   u8 no_onlink = 0;
7537   u8 is_no = 0;
7538   u32 val_lifetime = 0;
7539   u32 pref_lifetime = 0;
7540
7541   /* Parse args required to build the message */
7542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7543     {
7544       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7545         sw_if_index_set = 1;
7546       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7547         sw_if_index_set = 1;
7548       else if (unformat (i, "%U/%d",
7549                          unformat_ip6_address, &v6address, &address_length))
7550         v6_address_set = 1;
7551       else if (unformat (i, "val_life %d", &val_lifetime))
7552         ;
7553       else if (unformat (i, "pref_life %d", &pref_lifetime))
7554         ;
7555       else if (unformat (i, "def"))
7556         use_default = 1;
7557       else if (unformat (i, "noadv"))
7558         no_advertise = 1;
7559       else if (unformat (i, "offl"))
7560         off_link = 1;
7561       else if (unformat (i, "noauto"))
7562         no_autoconfig = 1;
7563       else if (unformat (i, "nolink"))
7564         no_onlink = 1;
7565       else if (unformat (i, "isno"))
7566         is_no = 1;
7567       else
7568         {
7569           clib_warning ("parse error '%U'", format_unformat_error, i);
7570           return -99;
7571         }
7572     }
7573
7574   if (sw_if_index_set == 0)
7575     {
7576       errmsg ("missing interface name or sw_if_index\n");
7577       return -99;
7578     }
7579   if (!v6_address_set)
7580     {
7581       errmsg ("no address set\n");
7582       return -99;
7583     }
7584
7585   /* Construct the API message */
7586   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7587
7588   mp->sw_if_index = ntohl (sw_if_index);
7589   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7590   mp->address_length = address_length;
7591   mp->use_default = use_default;
7592   mp->no_advertise = no_advertise;
7593   mp->off_link = off_link;
7594   mp->no_autoconfig = no_autoconfig;
7595   mp->no_onlink = no_onlink;
7596   mp->is_no = is_no;
7597   mp->val_lifetime = ntohl (val_lifetime);
7598   mp->pref_lifetime = ntohl (pref_lifetime);
7599
7600   /* send it... */
7601   S;
7602
7603   /* Wait for a reply, return good/bad news  */
7604   W;
7605
7606   /* NOTREACHED */
7607   return 0;
7608 }
7609
7610 static int
7611 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7612 {
7613   unformat_input_t *i = vam->input;
7614   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7615   f64 timeout;
7616   u32 sw_if_index;
7617   u8 sw_if_index_set = 0;
7618   u8 suppress = 0;
7619   u8 managed = 0;
7620   u8 other = 0;
7621   u8 ll_option = 0;
7622   u8 send_unicast = 0;
7623   u8 cease = 0;
7624   u8 is_no = 0;
7625   u8 default_router = 0;
7626   u32 max_interval = 0;
7627   u32 min_interval = 0;
7628   u32 lifetime = 0;
7629   u32 initial_count = 0;
7630   u32 initial_interval = 0;
7631
7632
7633   /* Parse args required to build the message */
7634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7635     {
7636       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7637         sw_if_index_set = 1;
7638       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7639         sw_if_index_set = 1;
7640       else if (unformat (i, "maxint %d", &max_interval))
7641         ;
7642       else if (unformat (i, "minint %d", &min_interval))
7643         ;
7644       else if (unformat (i, "life %d", &lifetime))
7645         ;
7646       else if (unformat (i, "count %d", &initial_count))
7647         ;
7648       else if (unformat (i, "interval %d", &initial_interval))
7649         ;
7650       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7651         suppress = 1;
7652       else if (unformat (i, "managed"))
7653         managed = 1;
7654       else if (unformat (i, "other"))
7655         other = 1;
7656       else if (unformat (i, "ll"))
7657         ll_option = 1;
7658       else if (unformat (i, "send"))
7659         send_unicast = 1;
7660       else if (unformat (i, "cease"))
7661         cease = 1;
7662       else if (unformat (i, "isno"))
7663         is_no = 1;
7664       else if (unformat (i, "def"))
7665         default_router = 1;
7666       else
7667         {
7668           clib_warning ("parse error '%U'", format_unformat_error, i);
7669           return -99;
7670         }
7671     }
7672
7673   if (sw_if_index_set == 0)
7674     {
7675       errmsg ("missing interface name or sw_if_index\n");
7676       return -99;
7677     }
7678
7679   /* Construct the API message */
7680   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7681
7682   mp->sw_if_index = ntohl (sw_if_index);
7683   mp->max_interval = ntohl (max_interval);
7684   mp->min_interval = ntohl (min_interval);
7685   mp->lifetime = ntohl (lifetime);
7686   mp->initial_count = ntohl (initial_count);
7687   mp->initial_interval = ntohl (initial_interval);
7688   mp->suppress = suppress;
7689   mp->managed = managed;
7690   mp->other = other;
7691   mp->ll_option = ll_option;
7692   mp->send_unicast = send_unicast;
7693   mp->cease = cease;
7694   mp->is_no = is_no;
7695   mp->default_router = default_router;
7696
7697   /* send it... */
7698   S;
7699
7700   /* Wait for a reply, return good/bad news  */
7701   W;
7702
7703   /* NOTREACHED */
7704   return 0;
7705 }
7706
7707 static int
7708 api_set_arp_neighbor_limit (vat_main_t * vam)
7709 {
7710   unformat_input_t *i = vam->input;
7711   vl_api_set_arp_neighbor_limit_t *mp;
7712   f64 timeout;
7713   u32 arp_nbr_limit;
7714   u8 limit_set = 0;
7715   u8 is_ipv6 = 0;
7716
7717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7718     {
7719       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7720         limit_set = 1;
7721       else if (unformat (i, "ipv6"))
7722         is_ipv6 = 1;
7723       else
7724         {
7725           clib_warning ("parse error '%U'", format_unformat_error, i);
7726           return -99;
7727         }
7728     }
7729
7730   if (limit_set == 0)
7731     {
7732       errmsg ("missing limit value\n");
7733       return -99;
7734     }
7735
7736   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7737
7738   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7739   mp->is_ipv6 = is_ipv6;
7740
7741   S;
7742   W;
7743   /* NOTREACHED */
7744   return 0;
7745 }
7746
7747 static int
7748 api_l2_patch_add_del (vat_main_t * vam)
7749 {
7750   unformat_input_t *i = vam->input;
7751   vl_api_l2_patch_add_del_t *mp;
7752   f64 timeout;
7753   u32 rx_sw_if_index;
7754   u8 rx_sw_if_index_set = 0;
7755   u32 tx_sw_if_index;
7756   u8 tx_sw_if_index_set = 0;
7757   u8 is_add = 1;
7758
7759   /* Parse args required to build the message */
7760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7761     {
7762       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7763         rx_sw_if_index_set = 1;
7764       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7765         tx_sw_if_index_set = 1;
7766       else if (unformat (i, "rx"))
7767         {
7768           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7769             {
7770               if (unformat (i, "%U", unformat_sw_if_index, vam,
7771                             &rx_sw_if_index))
7772                 rx_sw_if_index_set = 1;
7773             }
7774           else
7775             break;
7776         }
7777       else if (unformat (i, "tx"))
7778         {
7779           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7780             {
7781               if (unformat (i, "%U", unformat_sw_if_index, vam,
7782                             &tx_sw_if_index))
7783                 tx_sw_if_index_set = 1;
7784             }
7785           else
7786             break;
7787         }
7788       else if (unformat (i, "del"))
7789         is_add = 0;
7790       else
7791         break;
7792     }
7793
7794   if (rx_sw_if_index_set == 0)
7795     {
7796       errmsg ("missing rx interface name or rx_sw_if_index\n");
7797       return -99;
7798     }
7799
7800   if (tx_sw_if_index_set == 0)
7801     {
7802       errmsg ("missing tx interface name or tx_sw_if_index\n");
7803       return -99;
7804     }
7805
7806   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7807
7808   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7809   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7810   mp->is_add = is_add;
7811
7812   S;
7813   W;
7814   /* NOTREACHED */
7815   return 0;
7816 }
7817
7818 static int
7819 api_ioam_enable (vat_main_t * vam)
7820 {
7821   unformat_input_t *input = vam->input;
7822   vl_api_ioam_enable_t *mp;
7823   f64 timeout;
7824   u32 id = 0;
7825   int has_trace_option = 0;
7826   int has_pot_option = 0;
7827   int has_seqno_option = 0;
7828   int has_analyse_option = 0;
7829
7830   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7831     {
7832       if (unformat (input, "trace"))
7833         has_trace_option = 1;
7834       else if (unformat (input, "pot"))
7835         has_pot_option = 1;
7836       else if (unformat (input, "seqno"))
7837         has_seqno_option = 1;
7838       else if (unformat (input, "analyse"))
7839         has_analyse_option = 1;
7840       else
7841         break;
7842     }
7843   M (IOAM_ENABLE, ioam_enable);
7844   mp->id = htons (id);
7845   mp->seqno = has_seqno_option;
7846   mp->analyse = has_analyse_option;
7847   mp->pot_enable = has_pot_option;
7848   mp->trace_enable = has_trace_option;
7849
7850   S;
7851   W;
7852
7853   return (0);
7854
7855 }
7856
7857
7858 static int
7859 api_ioam_disable (vat_main_t * vam)
7860 {
7861   vl_api_ioam_disable_t *mp;
7862   f64 timeout;
7863
7864   M (IOAM_DISABLE, ioam_disable);
7865   S;
7866   W;
7867   return 0;
7868 }
7869
7870 static int
7871 api_sr_tunnel_add_del (vat_main_t * vam)
7872 {
7873   unformat_input_t *i = vam->input;
7874   vl_api_sr_tunnel_add_del_t *mp;
7875   f64 timeout;
7876   int is_del = 0;
7877   int pl_index;
7878   ip6_address_t src_address;
7879   int src_address_set = 0;
7880   ip6_address_t dst_address;
7881   u32 dst_mask_width;
7882   int dst_address_set = 0;
7883   u16 flags = 0;
7884   u32 rx_table_id = 0;
7885   u32 tx_table_id = 0;
7886   ip6_address_t *segments = 0;
7887   ip6_address_t *this_seg;
7888   ip6_address_t *tags = 0;
7889   ip6_address_t *this_tag;
7890   ip6_address_t next_address, tag;
7891   u8 *name = 0;
7892   u8 *policy_name = 0;
7893
7894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7895     {
7896       if (unformat (i, "del"))
7897         is_del = 1;
7898       else if (unformat (i, "name %s", &name))
7899         ;
7900       else if (unformat (i, "policy %s", &policy_name))
7901         ;
7902       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7903         ;
7904       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7905         ;
7906       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7907         src_address_set = 1;
7908       else if (unformat (i, "dst %U/%d",
7909                          unformat_ip6_address, &dst_address, &dst_mask_width))
7910         dst_address_set = 1;
7911       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7912         {
7913           vec_add2 (segments, this_seg, 1);
7914           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7915                        sizeof (*this_seg));
7916         }
7917       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7918         {
7919           vec_add2 (tags, this_tag, 1);
7920           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7921         }
7922       else if (unformat (i, "clean"))
7923         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7924       else if (unformat (i, "protected"))
7925         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7926       else if (unformat (i, "InPE %d", &pl_index))
7927         {
7928           if (pl_index <= 0 || pl_index > 4)
7929             {
7930             pl_index_range_error:
7931               errmsg ("pl index %d out of range\n", pl_index);
7932               return -99;
7933             }
7934           flags |=
7935             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7936         }
7937       else if (unformat (i, "EgPE %d", &pl_index))
7938         {
7939           if (pl_index <= 0 || pl_index > 4)
7940             goto pl_index_range_error;
7941           flags |=
7942             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7943         }
7944       else if (unformat (i, "OrgSrc %d", &pl_index))
7945         {
7946           if (pl_index <= 0 || pl_index > 4)
7947             goto pl_index_range_error;
7948           flags |=
7949             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7950         }
7951       else
7952         break;
7953     }
7954
7955   if (!src_address_set)
7956     {
7957       errmsg ("src address required\n");
7958       return -99;
7959     }
7960
7961   if (!dst_address_set)
7962     {
7963       errmsg ("dst address required\n");
7964       return -99;
7965     }
7966
7967   if (!segments)
7968     {
7969       errmsg ("at least one sr segment required\n");
7970       return -99;
7971     }
7972
7973   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7974       vec_len (segments) * sizeof (ip6_address_t)
7975       + vec_len (tags) * sizeof (ip6_address_t));
7976
7977   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7978   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7979   mp->dst_mask_width = dst_mask_width;
7980   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7981   mp->n_segments = vec_len (segments);
7982   mp->n_tags = vec_len (tags);
7983   mp->is_add = is_del == 0;
7984   clib_memcpy (mp->segs_and_tags, segments,
7985                vec_len (segments) * sizeof (ip6_address_t));
7986   clib_memcpy (mp->segs_and_tags +
7987                vec_len (segments) * sizeof (ip6_address_t), tags,
7988                vec_len (tags) * sizeof (ip6_address_t));
7989
7990   mp->outer_vrf_id = ntohl (rx_table_id);
7991   mp->inner_vrf_id = ntohl (tx_table_id);
7992   memcpy (mp->name, name, vec_len (name));
7993   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7994
7995   vec_free (segments);
7996   vec_free (tags);
7997
7998   S;
7999   W;
8000   /* NOTREACHED */
8001 }
8002
8003 static int
8004 api_sr_policy_add_del (vat_main_t * vam)
8005 {
8006   unformat_input_t *input = vam->input;
8007   vl_api_sr_policy_add_del_t *mp;
8008   f64 timeout;
8009   int is_del = 0;
8010   u8 *name = 0;
8011   u8 *tunnel_name = 0;
8012   u8 **tunnel_names = 0;
8013
8014   int name_set = 0;
8015   int tunnel_set = 0;
8016   int j = 0;
8017   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8018   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8019
8020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8021     {
8022       if (unformat (input, "del"))
8023         is_del = 1;
8024       else if (unformat (input, "name %s", &name))
8025         name_set = 1;
8026       else if (unformat (input, "tunnel %s", &tunnel_name))
8027         {
8028           if (tunnel_name)
8029             {
8030               vec_add1 (tunnel_names, tunnel_name);
8031               /* For serializer:
8032                  - length = #bytes to store in serial vector
8033                  - +1 = byte to store that length
8034                */
8035               tunnel_names_length += (vec_len (tunnel_name) + 1);
8036               tunnel_set = 1;
8037               tunnel_name = 0;
8038             }
8039         }
8040       else
8041         break;
8042     }
8043
8044   if (!name_set)
8045     {
8046       errmsg ("policy name required\n");
8047       return -99;
8048     }
8049
8050   if ((!tunnel_set) && (!is_del))
8051     {
8052       errmsg ("tunnel name required\n");
8053       return -99;
8054     }
8055
8056   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8057
8058
8059
8060   mp->is_add = !is_del;
8061
8062   memcpy (mp->name, name, vec_len (name));
8063   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8064   u8 *serial_orig = 0;
8065   vec_validate (serial_orig, tunnel_names_length);
8066   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8067   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8068
8069   for (j = 0; j < vec_len (tunnel_names); j++)
8070     {
8071       tun_name_len = vec_len (tunnel_names[j]);
8072       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8073       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8074       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8075       serial_orig += tun_name_len;      // Advance past the copy
8076     }
8077   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8078
8079   vec_free (tunnel_names);
8080   vec_free (tunnel_name);
8081
8082   S;
8083   W;
8084   /* NOTREACHED */
8085 }
8086
8087 static int
8088 api_sr_multicast_map_add_del (vat_main_t * vam)
8089 {
8090   unformat_input_t *input = vam->input;
8091   vl_api_sr_multicast_map_add_del_t *mp;
8092   f64 timeout;
8093   int is_del = 0;
8094   ip6_address_t multicast_address;
8095   u8 *policy_name = 0;
8096   int multicast_address_set = 0;
8097
8098   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8099     {
8100       if (unformat (input, "del"))
8101         is_del = 1;
8102       else
8103         if (unformat
8104             (input, "address %U", unformat_ip6_address, &multicast_address))
8105         multicast_address_set = 1;
8106       else if (unformat (input, "sr-policy %s", &policy_name))
8107         ;
8108       else
8109         break;
8110     }
8111
8112   if (!is_del && !policy_name)
8113     {
8114       errmsg ("sr-policy name required\n");
8115       return -99;
8116     }
8117
8118
8119   if (!multicast_address_set)
8120     {
8121       errmsg ("address required\n");
8122       return -99;
8123     }
8124
8125   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8126
8127   mp->is_add = !is_del;
8128   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8129   clib_memcpy (mp->multicast_address, &multicast_address,
8130                sizeof (mp->multicast_address));
8131
8132
8133   vec_free (policy_name);
8134
8135   S;
8136   W;
8137   /* NOTREACHED */
8138 }
8139
8140
8141 #define foreach_tcp_proto_field                 \
8142 _(src_port)                                     \
8143 _(dst_port)
8144
8145 #define foreach_udp_proto_field                 \
8146 _(src_port)                                     \
8147 _(dst_port)
8148
8149 #define foreach_ip4_proto_field                 \
8150 _(src_address)                                  \
8151 _(dst_address)                                  \
8152 _(tos)                                          \
8153 _(length)                                       \
8154 _(fragment_id)                                  \
8155 _(ttl)                                          \
8156 _(protocol)                                     \
8157 _(checksum)
8158
8159 uword
8160 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8161 {
8162   u8 **maskp = va_arg (*args, u8 **);
8163   u8 *mask = 0;
8164   u8 found_something = 0;
8165   tcp_header_t *tcp;
8166
8167 #define _(a) u8 a=0;
8168   foreach_tcp_proto_field;
8169 #undef _
8170
8171   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8172     {
8173       if (0);
8174 #define _(a) else if (unformat (input, #a)) a=1;
8175       foreach_tcp_proto_field
8176 #undef _
8177         else
8178         break;
8179     }
8180
8181 #define _(a) found_something += a;
8182   foreach_tcp_proto_field;
8183 #undef _
8184
8185   if (found_something == 0)
8186     return 0;
8187
8188   vec_validate (mask, sizeof (*tcp) - 1);
8189
8190   tcp = (tcp_header_t *) mask;
8191
8192 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8193   foreach_tcp_proto_field;
8194 #undef _
8195
8196   *maskp = mask;
8197   return 1;
8198 }
8199
8200 uword
8201 unformat_udp_mask (unformat_input_t * input, va_list * args)
8202 {
8203   u8 **maskp = va_arg (*args, u8 **);
8204   u8 *mask = 0;
8205   u8 found_something = 0;
8206   udp_header_t *udp;
8207
8208 #define _(a) u8 a=0;
8209   foreach_udp_proto_field;
8210 #undef _
8211
8212   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8213     {
8214       if (0);
8215 #define _(a) else if (unformat (input, #a)) a=1;
8216       foreach_udp_proto_field
8217 #undef _
8218         else
8219         break;
8220     }
8221
8222 #define _(a) found_something += a;
8223   foreach_udp_proto_field;
8224 #undef _
8225
8226   if (found_something == 0)
8227     return 0;
8228
8229   vec_validate (mask, sizeof (*udp) - 1);
8230
8231   udp = (udp_header_t *) mask;
8232
8233 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8234   foreach_udp_proto_field;
8235 #undef _
8236
8237   *maskp = mask;
8238   return 1;
8239 }
8240
8241 typedef struct
8242 {
8243   u16 src_port, dst_port;
8244 } tcpudp_header_t;
8245
8246 uword
8247 unformat_l4_mask (unformat_input_t * input, va_list * args)
8248 {
8249   u8 **maskp = va_arg (*args, u8 **);
8250   u16 src_port = 0, dst_port = 0;
8251   tcpudp_header_t *tcpudp;
8252
8253   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8254     {
8255       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8256         return 1;
8257       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8258         return 1;
8259       else if (unformat (input, "src_port"))
8260         src_port = 0xFFFF;
8261       else if (unformat (input, "dst_port"))
8262         dst_port = 0xFFFF;
8263       else
8264         return 0;
8265     }
8266
8267   if (!src_port && !dst_port)
8268     return 0;
8269
8270   u8 *mask = 0;
8271   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8272
8273   tcpudp = (tcpudp_header_t *) mask;
8274   tcpudp->src_port = src_port;
8275   tcpudp->dst_port = dst_port;
8276
8277   *maskp = mask;
8278
8279   return 1;
8280 }
8281
8282 uword
8283 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8284 {
8285   u8 **maskp = va_arg (*args, u8 **);
8286   u8 *mask = 0;
8287   u8 found_something = 0;
8288   ip4_header_t *ip;
8289
8290 #define _(a) u8 a=0;
8291   foreach_ip4_proto_field;
8292 #undef _
8293   u8 version = 0;
8294   u8 hdr_length = 0;
8295
8296
8297   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8298     {
8299       if (unformat (input, "version"))
8300         version = 1;
8301       else if (unformat (input, "hdr_length"))
8302         hdr_length = 1;
8303       else if (unformat (input, "src"))
8304         src_address = 1;
8305       else if (unformat (input, "dst"))
8306         dst_address = 1;
8307       else if (unformat (input, "proto"))
8308         protocol = 1;
8309
8310 #define _(a) else if (unformat (input, #a)) a=1;
8311       foreach_ip4_proto_field
8312 #undef _
8313         else
8314         break;
8315     }
8316
8317 #define _(a) found_something += a;
8318   foreach_ip4_proto_field;
8319 #undef _
8320
8321   if (found_something == 0)
8322     return 0;
8323
8324   vec_validate (mask, sizeof (*ip) - 1);
8325
8326   ip = (ip4_header_t *) mask;
8327
8328 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8329   foreach_ip4_proto_field;
8330 #undef _
8331
8332   ip->ip_version_and_header_length = 0;
8333
8334   if (version)
8335     ip->ip_version_and_header_length |= 0xF0;
8336
8337   if (hdr_length)
8338     ip->ip_version_and_header_length |= 0x0F;
8339
8340   *maskp = mask;
8341   return 1;
8342 }
8343
8344 #define foreach_ip6_proto_field                 \
8345 _(src_address)                                  \
8346 _(dst_address)                                  \
8347 _(payload_length)                               \
8348 _(hop_limit)                                    \
8349 _(protocol)
8350
8351 uword
8352 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8353 {
8354   u8 **maskp = va_arg (*args, u8 **);
8355   u8 *mask = 0;
8356   u8 found_something = 0;
8357   ip6_header_t *ip;
8358   u32 ip_version_traffic_class_and_flow_label;
8359
8360 #define _(a) u8 a=0;
8361   foreach_ip6_proto_field;
8362 #undef _
8363   u8 version = 0;
8364   u8 traffic_class = 0;
8365   u8 flow_label = 0;
8366
8367   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8368     {
8369       if (unformat (input, "version"))
8370         version = 1;
8371       else if (unformat (input, "traffic-class"))
8372         traffic_class = 1;
8373       else if (unformat (input, "flow-label"))
8374         flow_label = 1;
8375       else if (unformat (input, "src"))
8376         src_address = 1;
8377       else if (unformat (input, "dst"))
8378         dst_address = 1;
8379       else if (unformat (input, "proto"))
8380         protocol = 1;
8381
8382 #define _(a) else if (unformat (input, #a)) a=1;
8383       foreach_ip6_proto_field
8384 #undef _
8385         else
8386         break;
8387     }
8388
8389 #define _(a) found_something += a;
8390   foreach_ip6_proto_field;
8391 #undef _
8392
8393   if (found_something == 0)
8394     return 0;
8395
8396   vec_validate (mask, sizeof (*ip) - 1);
8397
8398   ip = (ip6_header_t *) mask;
8399
8400 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8401   foreach_ip6_proto_field;
8402 #undef _
8403
8404   ip_version_traffic_class_and_flow_label = 0;
8405
8406   if (version)
8407     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8408
8409   if (traffic_class)
8410     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8411
8412   if (flow_label)
8413     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8414
8415   ip->ip_version_traffic_class_and_flow_label =
8416     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8417
8418   *maskp = mask;
8419   return 1;
8420 }
8421
8422 uword
8423 unformat_l3_mask (unformat_input_t * input, va_list * args)
8424 {
8425   u8 **maskp = va_arg (*args, u8 **);
8426
8427   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8428     {
8429       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8430         return 1;
8431       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8432         return 1;
8433       else
8434         break;
8435     }
8436   return 0;
8437 }
8438
8439 uword
8440 unformat_l2_mask (unformat_input_t * input, va_list * args)
8441 {
8442   u8 **maskp = va_arg (*args, u8 **);
8443   u8 *mask = 0;
8444   u8 src = 0;
8445   u8 dst = 0;
8446   u8 proto = 0;
8447   u8 tag1 = 0;
8448   u8 tag2 = 0;
8449   u8 ignore_tag1 = 0;
8450   u8 ignore_tag2 = 0;
8451   u8 cos1 = 0;
8452   u8 cos2 = 0;
8453   u8 dot1q = 0;
8454   u8 dot1ad = 0;
8455   int len = 14;
8456
8457   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8458     {
8459       if (unformat (input, "src"))
8460         src = 1;
8461       else if (unformat (input, "dst"))
8462         dst = 1;
8463       else if (unformat (input, "proto"))
8464         proto = 1;
8465       else if (unformat (input, "tag1"))
8466         tag1 = 1;
8467       else if (unformat (input, "tag2"))
8468         tag2 = 1;
8469       else if (unformat (input, "ignore-tag1"))
8470         ignore_tag1 = 1;
8471       else if (unformat (input, "ignore-tag2"))
8472         ignore_tag2 = 1;
8473       else if (unformat (input, "cos1"))
8474         cos1 = 1;
8475       else if (unformat (input, "cos2"))
8476         cos2 = 1;
8477       else if (unformat (input, "dot1q"))
8478         dot1q = 1;
8479       else if (unformat (input, "dot1ad"))
8480         dot1ad = 1;
8481       else
8482         break;
8483     }
8484   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8485        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8486     return 0;
8487
8488   if (tag1 || ignore_tag1 || cos1 || dot1q)
8489     len = 18;
8490   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8491     len = 22;
8492
8493   vec_validate (mask, len - 1);
8494
8495   if (dst)
8496     memset (mask, 0xff, 6);
8497
8498   if (src)
8499     memset (mask + 6, 0xff, 6);
8500
8501   if (tag2 || dot1ad)
8502     {
8503       /* inner vlan tag */
8504       if (tag2)
8505         {
8506           mask[19] = 0xff;
8507           mask[18] = 0x0f;
8508         }
8509       if (cos2)
8510         mask[18] |= 0xe0;
8511       if (proto)
8512         mask[21] = mask[20] = 0xff;
8513       if (tag1)
8514         {
8515           mask[15] = 0xff;
8516           mask[14] = 0x0f;
8517         }
8518       if (cos1)
8519         mask[14] |= 0xe0;
8520       *maskp = mask;
8521       return 1;
8522     }
8523   if (tag1 | dot1q)
8524     {
8525       if (tag1)
8526         {
8527           mask[15] = 0xff;
8528           mask[14] = 0x0f;
8529         }
8530       if (cos1)
8531         mask[14] |= 0xe0;
8532       if (proto)
8533         mask[16] = mask[17] = 0xff;
8534
8535       *maskp = mask;
8536       return 1;
8537     }
8538   if (cos2)
8539     mask[18] |= 0xe0;
8540   if (cos1)
8541     mask[14] |= 0xe0;
8542   if (proto)
8543     mask[12] = mask[13] = 0xff;
8544
8545   *maskp = mask;
8546   return 1;
8547 }
8548
8549 uword
8550 unformat_classify_mask (unformat_input_t * input, va_list * args)
8551 {
8552   u8 **maskp = va_arg (*args, u8 **);
8553   u32 *skipp = va_arg (*args, u32 *);
8554   u32 *matchp = va_arg (*args, u32 *);
8555   u32 match;
8556   u8 *mask = 0;
8557   u8 *l2 = 0;
8558   u8 *l3 = 0;
8559   u8 *l4 = 0;
8560   int i;
8561
8562   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8563     {
8564       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8565         ;
8566       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8567         ;
8568       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8569         ;
8570       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8571         ;
8572       else
8573         break;
8574     }
8575
8576   if (l4 && !l3)
8577     {
8578       vec_free (mask);
8579       vec_free (l2);
8580       vec_free (l4);
8581       return 0;
8582     }
8583
8584   if (mask || l2 || l3 || l4)
8585     {
8586       if (l2 || l3 || l4)
8587         {
8588           /* "With a free Ethernet header in every package" */
8589           if (l2 == 0)
8590             vec_validate (l2, 13);
8591           mask = l2;
8592           if (vec_len (l3))
8593             {
8594               vec_append (mask, l3);
8595               vec_free (l3);
8596             }
8597           if (vec_len (l4))
8598             {
8599               vec_append (mask, l4);
8600               vec_free (l4);
8601             }
8602         }
8603
8604       /* Scan forward looking for the first significant mask octet */
8605       for (i = 0; i < vec_len (mask); i++)
8606         if (mask[i])
8607           break;
8608
8609       /* compute (skip, match) params */
8610       *skipp = i / sizeof (u32x4);
8611       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8612
8613       /* Pad mask to an even multiple of the vector size */
8614       while (vec_len (mask) % sizeof (u32x4))
8615         vec_add1 (mask, 0);
8616
8617       match = vec_len (mask) / sizeof (u32x4);
8618
8619       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8620         {
8621           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8622           if (*tmp || *(tmp + 1))
8623             break;
8624           match--;
8625         }
8626       if (match == 0)
8627         clib_warning ("BUG: match 0");
8628
8629       _vec_len (mask) = match * sizeof (u32x4);
8630
8631       *matchp = match;
8632       *maskp = mask;
8633
8634       return 1;
8635     }
8636
8637   return 0;
8638 }
8639
8640 #define foreach_l2_next                         \
8641 _(drop, DROP)                                   \
8642 _(ethernet, ETHERNET_INPUT)                     \
8643 _(ip4, IP4_INPUT)                               \
8644 _(ip6, IP6_INPUT)
8645
8646 uword
8647 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8648 {
8649   u32 *miss_next_indexp = va_arg (*args, u32 *);
8650   u32 next_index = 0;
8651   u32 tmp;
8652
8653 #define _(n,N) \
8654   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8655   foreach_l2_next;
8656 #undef _
8657
8658   if (unformat (input, "%d", &tmp))
8659     {
8660       next_index = tmp;
8661       goto out;
8662     }
8663
8664   return 0;
8665
8666 out:
8667   *miss_next_indexp = next_index;
8668   return 1;
8669 }
8670
8671 #define foreach_ip_next                         \
8672 _(drop, DROP)                                   \
8673 _(local, LOCAL)                                 \
8674 _(rewrite, REWRITE)
8675
8676 uword
8677 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8678 {
8679   u32 *miss_next_indexp = va_arg (*args, u32 *);
8680   u32 next_index = 0;
8681   u32 tmp;
8682
8683 #define _(n,N) \
8684   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8685   foreach_ip_next;
8686 #undef _
8687
8688   if (unformat (input, "%d", &tmp))
8689     {
8690       next_index = tmp;
8691       goto out;
8692     }
8693
8694   return 0;
8695
8696 out:
8697   *miss_next_indexp = next_index;
8698   return 1;
8699 }
8700
8701 #define foreach_acl_next                        \
8702 _(deny, DENY)
8703
8704 uword
8705 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8706 {
8707   u32 *miss_next_indexp = va_arg (*args, u32 *);
8708   u32 next_index = 0;
8709   u32 tmp;
8710
8711 #define _(n,N) \
8712   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8713   foreach_acl_next;
8714 #undef _
8715
8716   if (unformat (input, "permit"))
8717     {
8718       next_index = ~0;
8719       goto out;
8720     }
8721   else if (unformat (input, "%d", &tmp))
8722     {
8723       next_index = tmp;
8724       goto out;
8725     }
8726
8727   return 0;
8728
8729 out:
8730   *miss_next_indexp = next_index;
8731   return 1;
8732 }
8733
8734 uword
8735 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8736 {
8737   u32 *r = va_arg (*args, u32 *);
8738
8739   if (unformat (input, "conform-color"))
8740     *r = POLICE_CONFORM;
8741   else if (unformat (input, "exceed-color"))
8742     *r = POLICE_EXCEED;
8743   else
8744     return 0;
8745
8746   return 1;
8747 }
8748
8749 static int
8750 api_classify_add_del_table (vat_main_t * vam)
8751 {
8752   unformat_input_t *i = vam->input;
8753   vl_api_classify_add_del_table_t *mp;
8754
8755   u32 nbuckets = 2;
8756   u32 skip = ~0;
8757   u32 match = ~0;
8758   int is_add = 1;
8759   u32 table_index = ~0;
8760   u32 next_table_index = ~0;
8761   u32 miss_next_index = ~0;
8762   u32 memory_size = 32 << 20;
8763   u8 *mask = 0;
8764   f64 timeout;
8765   u32 current_data_flag = 0;
8766   int current_data_offset = 0;
8767
8768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8769     {
8770       if (unformat (i, "del"))
8771         is_add = 0;
8772       else if (unformat (i, "buckets %d", &nbuckets))
8773         ;
8774       else if (unformat (i, "memory_size %d", &memory_size))
8775         ;
8776       else if (unformat (i, "skip %d", &skip))
8777         ;
8778       else if (unformat (i, "match %d", &match))
8779         ;
8780       else if (unformat (i, "table %d", &table_index))
8781         ;
8782       else if (unformat (i, "mask %U", unformat_classify_mask,
8783                          &mask, &skip, &match))
8784         ;
8785       else if (unformat (i, "next-table %d", &next_table_index))
8786         ;
8787       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8788                          &miss_next_index))
8789         ;
8790       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8791                          &miss_next_index))
8792         ;
8793       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8794                          &miss_next_index))
8795         ;
8796       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8797         ;
8798       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8799         ;
8800       else
8801         break;
8802     }
8803
8804   if (is_add && mask == 0)
8805     {
8806       errmsg ("Mask required\n");
8807       return -99;
8808     }
8809
8810   if (is_add && skip == ~0)
8811     {
8812       errmsg ("skip count required\n");
8813       return -99;
8814     }
8815
8816   if (is_add && match == ~0)
8817     {
8818       errmsg ("match count required\n");
8819       return -99;
8820     }
8821
8822   if (!is_add && table_index == ~0)
8823     {
8824       errmsg ("table index required for delete\n");
8825       return -99;
8826     }
8827
8828   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8829
8830   mp->is_add = is_add;
8831   mp->table_index = ntohl (table_index);
8832   mp->nbuckets = ntohl (nbuckets);
8833   mp->memory_size = ntohl (memory_size);
8834   mp->skip_n_vectors = ntohl (skip);
8835   mp->match_n_vectors = ntohl (match);
8836   mp->next_table_index = ntohl (next_table_index);
8837   mp->miss_next_index = ntohl (miss_next_index);
8838   mp->current_data_flag = ntohl (current_data_flag);
8839   mp->current_data_offset = ntohl (current_data_offset);
8840   clib_memcpy (mp->mask, mask, vec_len (mask));
8841
8842   vec_free (mask);
8843
8844   S;
8845   W;
8846   /* NOTREACHED */
8847 }
8848
8849 uword
8850 unformat_l4_match (unformat_input_t * input, va_list * args)
8851 {
8852   u8 **matchp = va_arg (*args, u8 **);
8853
8854   u8 *proto_header = 0;
8855   int src_port = 0;
8856   int dst_port = 0;
8857
8858   tcpudp_header_t h;
8859
8860   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8861     {
8862       if (unformat (input, "src_port %d", &src_port))
8863         ;
8864       else if (unformat (input, "dst_port %d", &dst_port))
8865         ;
8866       else
8867         return 0;
8868     }
8869
8870   h.src_port = clib_host_to_net_u16 (src_port);
8871   h.dst_port = clib_host_to_net_u16 (dst_port);
8872   vec_validate (proto_header, sizeof (h) - 1);
8873   memcpy (proto_header, &h, sizeof (h));
8874
8875   *matchp = proto_header;
8876
8877   return 1;
8878 }
8879
8880 uword
8881 unformat_ip4_match (unformat_input_t * input, va_list * args)
8882 {
8883   u8 **matchp = va_arg (*args, u8 **);
8884   u8 *match = 0;
8885   ip4_header_t *ip;
8886   int version = 0;
8887   u32 version_val;
8888   int hdr_length = 0;
8889   u32 hdr_length_val;
8890   int src = 0, dst = 0;
8891   ip4_address_t src_val, dst_val;
8892   int proto = 0;
8893   u32 proto_val;
8894   int tos = 0;
8895   u32 tos_val;
8896   int length = 0;
8897   u32 length_val;
8898   int fragment_id = 0;
8899   u32 fragment_id_val;
8900   int ttl = 0;
8901   int ttl_val;
8902   int checksum = 0;
8903   u32 checksum_val;
8904
8905   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8906     {
8907       if (unformat (input, "version %d", &version_val))
8908         version = 1;
8909       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8910         hdr_length = 1;
8911       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8912         src = 1;
8913       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8914         dst = 1;
8915       else if (unformat (input, "proto %d", &proto_val))
8916         proto = 1;
8917       else if (unformat (input, "tos %d", &tos_val))
8918         tos = 1;
8919       else if (unformat (input, "length %d", &length_val))
8920         length = 1;
8921       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8922         fragment_id = 1;
8923       else if (unformat (input, "ttl %d", &ttl_val))
8924         ttl = 1;
8925       else if (unformat (input, "checksum %d", &checksum_val))
8926         checksum = 1;
8927       else
8928         break;
8929     }
8930
8931   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8932       + ttl + checksum == 0)
8933     return 0;
8934
8935   /*
8936    * Aligned because we use the real comparison functions
8937    */
8938   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8939
8940   ip = (ip4_header_t *) match;
8941
8942   /* These are realistically matched in practice */
8943   if (src)
8944     ip->src_address.as_u32 = src_val.as_u32;
8945
8946   if (dst)
8947     ip->dst_address.as_u32 = dst_val.as_u32;
8948
8949   if (proto)
8950     ip->protocol = proto_val;
8951
8952
8953   /* These are not, but they're included for completeness */
8954   if (version)
8955     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8956
8957   if (hdr_length)
8958     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8959
8960   if (tos)
8961     ip->tos = tos_val;
8962
8963   if (length)
8964     ip->length = clib_host_to_net_u16 (length_val);
8965
8966   if (ttl)
8967     ip->ttl = ttl_val;
8968
8969   if (checksum)
8970     ip->checksum = clib_host_to_net_u16 (checksum_val);
8971
8972   *matchp = match;
8973   return 1;
8974 }
8975
8976 uword
8977 unformat_ip6_match (unformat_input_t * input, va_list * args)
8978 {
8979   u8 **matchp = va_arg (*args, u8 **);
8980   u8 *match = 0;
8981   ip6_header_t *ip;
8982   int version = 0;
8983   u32 version_val;
8984   u8 traffic_class = 0;
8985   u32 traffic_class_val = 0;
8986   u8 flow_label = 0;
8987   u8 flow_label_val;
8988   int src = 0, dst = 0;
8989   ip6_address_t src_val, dst_val;
8990   int proto = 0;
8991   u32 proto_val;
8992   int payload_length = 0;
8993   u32 payload_length_val;
8994   int hop_limit = 0;
8995   int hop_limit_val;
8996   u32 ip_version_traffic_class_and_flow_label;
8997
8998   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8999     {
9000       if (unformat (input, "version %d", &version_val))
9001         version = 1;
9002       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9003         traffic_class = 1;
9004       else if (unformat (input, "flow_label %d", &flow_label_val))
9005         flow_label = 1;
9006       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9007         src = 1;
9008       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9009         dst = 1;
9010       else if (unformat (input, "proto %d", &proto_val))
9011         proto = 1;
9012       else if (unformat (input, "payload_length %d", &payload_length_val))
9013         payload_length = 1;
9014       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9015         hop_limit = 1;
9016       else
9017         break;
9018     }
9019
9020   if (version + traffic_class + flow_label + src + dst + proto +
9021       payload_length + hop_limit == 0)
9022     return 0;
9023
9024   /*
9025    * Aligned because we use the real comparison functions
9026    */
9027   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9028
9029   ip = (ip6_header_t *) match;
9030
9031   if (src)
9032     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9033
9034   if (dst)
9035     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9036
9037   if (proto)
9038     ip->protocol = proto_val;
9039
9040   ip_version_traffic_class_and_flow_label = 0;
9041
9042   if (version)
9043     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9044
9045   if (traffic_class)
9046     ip_version_traffic_class_and_flow_label |=
9047       (traffic_class_val & 0xFF) << 20;
9048
9049   if (flow_label)
9050     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9051
9052   ip->ip_version_traffic_class_and_flow_label =
9053     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9054
9055   if (payload_length)
9056     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9057
9058   if (hop_limit)
9059     ip->hop_limit = hop_limit_val;
9060
9061   *matchp = match;
9062   return 1;
9063 }
9064
9065 uword
9066 unformat_l3_match (unformat_input_t * input, va_list * args)
9067 {
9068   u8 **matchp = va_arg (*args, u8 **);
9069
9070   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9071     {
9072       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9073         return 1;
9074       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9075         return 1;
9076       else
9077         break;
9078     }
9079   return 0;
9080 }
9081
9082 uword
9083 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9084 {
9085   u8 *tagp = va_arg (*args, u8 *);
9086   u32 tag;
9087
9088   if (unformat (input, "%d", &tag))
9089     {
9090       tagp[0] = (tag >> 8) & 0x0F;
9091       tagp[1] = tag & 0xFF;
9092       return 1;
9093     }
9094
9095   return 0;
9096 }
9097
9098 uword
9099 unformat_l2_match (unformat_input_t * input, va_list * args)
9100 {
9101   u8 **matchp = va_arg (*args, u8 **);
9102   u8 *match = 0;
9103   u8 src = 0;
9104   u8 src_val[6];
9105   u8 dst = 0;
9106   u8 dst_val[6];
9107   u8 proto = 0;
9108   u16 proto_val;
9109   u8 tag1 = 0;
9110   u8 tag1_val[2];
9111   u8 tag2 = 0;
9112   u8 tag2_val[2];
9113   int len = 14;
9114   u8 ignore_tag1 = 0;
9115   u8 ignore_tag2 = 0;
9116   u8 cos1 = 0;
9117   u8 cos2 = 0;
9118   u32 cos1_val = 0;
9119   u32 cos2_val = 0;
9120
9121   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9122     {
9123       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9124         src = 1;
9125       else
9126         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9127         dst = 1;
9128       else if (unformat (input, "proto %U",
9129                          unformat_ethernet_type_host_byte_order, &proto_val))
9130         proto = 1;
9131       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9132         tag1 = 1;
9133       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9134         tag2 = 1;
9135       else if (unformat (input, "ignore-tag1"))
9136         ignore_tag1 = 1;
9137       else if (unformat (input, "ignore-tag2"))
9138         ignore_tag2 = 1;
9139       else if (unformat (input, "cos1 %d", &cos1_val))
9140         cos1 = 1;
9141       else if (unformat (input, "cos2 %d", &cos2_val))
9142         cos2 = 1;
9143       else
9144         break;
9145     }
9146   if ((src + dst + proto + tag1 + tag2 +
9147        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9148     return 0;
9149
9150   if (tag1 || ignore_tag1 || cos1)
9151     len = 18;
9152   if (tag2 || ignore_tag2 || cos2)
9153     len = 22;
9154
9155   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9156
9157   if (dst)
9158     clib_memcpy (match, dst_val, 6);
9159
9160   if (src)
9161     clib_memcpy (match + 6, src_val, 6);
9162
9163   if (tag2)
9164     {
9165       /* inner vlan tag */
9166       match[19] = tag2_val[1];
9167       match[18] = tag2_val[0];
9168       if (cos2)
9169         match[18] |= (cos2_val & 0x7) << 5;
9170       if (proto)
9171         {
9172           match[21] = proto_val & 0xff;
9173           match[20] = proto_val >> 8;
9174         }
9175       if (tag1)
9176         {
9177           match[15] = tag1_val[1];
9178           match[14] = tag1_val[0];
9179         }
9180       if (cos1)
9181         match[14] |= (cos1_val & 0x7) << 5;
9182       *matchp = match;
9183       return 1;
9184     }
9185   if (tag1)
9186     {
9187       match[15] = tag1_val[1];
9188       match[14] = tag1_val[0];
9189       if (proto)
9190         {
9191           match[17] = proto_val & 0xff;
9192           match[16] = proto_val >> 8;
9193         }
9194       if (cos1)
9195         match[14] |= (cos1_val & 0x7) << 5;
9196
9197       *matchp = match;
9198       return 1;
9199     }
9200   if (cos2)
9201     match[18] |= (cos2_val & 0x7) << 5;
9202   if (cos1)
9203     match[14] |= (cos1_val & 0x7) << 5;
9204   if (proto)
9205     {
9206       match[13] = proto_val & 0xff;
9207       match[12] = proto_val >> 8;
9208     }
9209
9210   *matchp = match;
9211   return 1;
9212 }
9213
9214
9215 uword
9216 unformat_classify_match (unformat_input_t * input, va_list * args)
9217 {
9218   u8 **matchp = va_arg (*args, u8 **);
9219   u32 skip_n_vectors = va_arg (*args, u32);
9220   u32 match_n_vectors = va_arg (*args, u32);
9221
9222   u8 *match = 0;
9223   u8 *l2 = 0;
9224   u8 *l3 = 0;
9225   u8 *l4 = 0;
9226
9227   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9228     {
9229       if (unformat (input, "hex %U", unformat_hex_string, &match))
9230         ;
9231       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9232         ;
9233       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9234         ;
9235       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9236         ;
9237       else
9238         break;
9239     }
9240
9241   if (l4 && !l3)
9242     {
9243       vec_free (match);
9244       vec_free (l2);
9245       vec_free (l4);
9246       return 0;
9247     }
9248
9249   if (match || l2 || l3 || l4)
9250     {
9251       if (l2 || l3 || l4)
9252         {
9253           /* "Win a free Ethernet header in every packet" */
9254           if (l2 == 0)
9255             vec_validate_aligned (l2, 13, sizeof (u32x4));
9256           match = l2;
9257           if (vec_len (l3))
9258             {
9259               vec_append_aligned (match, l3, sizeof (u32x4));
9260               vec_free (l3);
9261             }
9262           if (vec_len (l4))
9263             {
9264               vec_append_aligned (match, l4, sizeof (u32x4));
9265               vec_free (l4);
9266             }
9267         }
9268
9269       /* Make sure the vector is big enough even if key is all 0's */
9270       vec_validate_aligned
9271         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9272          sizeof (u32x4));
9273
9274       /* Set size, include skipped vectors */
9275       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9276
9277       *matchp = match;
9278
9279       return 1;
9280     }
9281
9282   return 0;
9283 }
9284
9285 static int
9286 api_classify_add_del_session (vat_main_t * vam)
9287 {
9288   unformat_input_t *i = vam->input;
9289   vl_api_classify_add_del_session_t *mp;
9290   int is_add = 1;
9291   u32 table_index = ~0;
9292   u32 hit_next_index = ~0;
9293   u32 opaque_index = ~0;
9294   u8 *match = 0;
9295   i32 advance = 0;
9296   f64 timeout;
9297   u32 skip_n_vectors = 0;
9298   u32 match_n_vectors = 0;
9299   u32 action = 0;
9300   u32 metadata = 0;
9301
9302   /*
9303    * Warning: you have to supply skip_n and match_n
9304    * because the API client cant simply look at the classify
9305    * table object.
9306    */
9307
9308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9309     {
9310       if (unformat (i, "del"))
9311         is_add = 0;
9312       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9313                          &hit_next_index))
9314         ;
9315       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9316                          &hit_next_index))
9317         ;
9318       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9319                          &hit_next_index))
9320         ;
9321       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9322         ;
9323       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9324         ;
9325       else if (unformat (i, "opaque-index %d", &opaque_index))
9326         ;
9327       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9328         ;
9329       else if (unformat (i, "match_n %d", &match_n_vectors))
9330         ;
9331       else if (unformat (i, "match %U", unformat_classify_match,
9332                          &match, skip_n_vectors, match_n_vectors))
9333         ;
9334       else if (unformat (i, "advance %d", &advance))
9335         ;
9336       else if (unformat (i, "table-index %d", &table_index))
9337         ;
9338       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9339         action = 1;
9340       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9341         action = 2;
9342       else if (unformat (i, "action %d", &action))
9343         ;
9344       else if (unformat (i, "metadata %d", &metadata))
9345         ;
9346       else
9347         break;
9348     }
9349
9350   if (table_index == ~0)
9351     {
9352       errmsg ("Table index required\n");
9353       return -99;
9354     }
9355
9356   if (is_add && match == 0)
9357     {
9358       errmsg ("Match value required\n");
9359       return -99;
9360     }
9361
9362   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9363
9364   mp->is_add = is_add;
9365   mp->table_index = ntohl (table_index);
9366   mp->hit_next_index = ntohl (hit_next_index);
9367   mp->opaque_index = ntohl (opaque_index);
9368   mp->advance = ntohl (advance);
9369   mp->action = action;
9370   mp->metadata = ntohl (metadata);
9371   clib_memcpy (mp->match, match, vec_len (match));
9372   vec_free (match);
9373
9374   S;
9375   W;
9376   /* NOTREACHED */
9377 }
9378
9379 static int
9380 api_classify_set_interface_ip_table (vat_main_t * vam)
9381 {
9382   unformat_input_t *i = vam->input;
9383   vl_api_classify_set_interface_ip_table_t *mp;
9384   f64 timeout;
9385   u32 sw_if_index;
9386   int sw_if_index_set;
9387   u32 table_index = ~0;
9388   u8 is_ipv6 = 0;
9389
9390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9391     {
9392       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9393         sw_if_index_set = 1;
9394       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9395         sw_if_index_set = 1;
9396       else if (unformat (i, "table %d", &table_index))
9397         ;
9398       else
9399         {
9400           clib_warning ("parse error '%U'", format_unformat_error, i);
9401           return -99;
9402         }
9403     }
9404
9405   if (sw_if_index_set == 0)
9406     {
9407       errmsg ("missing interface name or sw_if_index\n");
9408       return -99;
9409     }
9410
9411
9412   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9413
9414   mp->sw_if_index = ntohl (sw_if_index);
9415   mp->table_index = ntohl (table_index);
9416   mp->is_ipv6 = is_ipv6;
9417
9418   S;
9419   W;
9420   /* NOTREACHED */
9421   return 0;
9422 }
9423
9424 static int
9425 api_classify_set_interface_l2_tables (vat_main_t * vam)
9426 {
9427   unformat_input_t *i = vam->input;
9428   vl_api_classify_set_interface_l2_tables_t *mp;
9429   f64 timeout;
9430   u32 sw_if_index;
9431   int sw_if_index_set;
9432   u32 ip4_table_index = ~0;
9433   u32 ip6_table_index = ~0;
9434   u32 other_table_index = ~0;
9435   u32 is_input = 1;
9436
9437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9438     {
9439       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9440         sw_if_index_set = 1;
9441       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9442         sw_if_index_set = 1;
9443       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9444         ;
9445       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9446         ;
9447       else if (unformat (i, "other-table %d", &other_table_index))
9448         ;
9449       else if (unformat (i, "is-input %d", &is_input))
9450         ;
9451       else
9452         {
9453           clib_warning ("parse error '%U'", format_unformat_error, i);
9454           return -99;
9455         }
9456     }
9457
9458   if (sw_if_index_set == 0)
9459     {
9460       errmsg ("missing interface name or sw_if_index\n");
9461       return -99;
9462     }
9463
9464
9465   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9466
9467   mp->sw_if_index = ntohl (sw_if_index);
9468   mp->ip4_table_index = ntohl (ip4_table_index);
9469   mp->ip6_table_index = ntohl (ip6_table_index);
9470   mp->other_table_index = ntohl (other_table_index);
9471   mp->is_input = (u8) is_input;
9472
9473   S;
9474   W;
9475   /* NOTREACHED */
9476   return 0;
9477 }
9478
9479 static int
9480 api_set_ipfix_exporter (vat_main_t * vam)
9481 {
9482   unformat_input_t *i = vam->input;
9483   vl_api_set_ipfix_exporter_t *mp;
9484   ip4_address_t collector_address;
9485   u8 collector_address_set = 0;
9486   u32 collector_port = ~0;
9487   ip4_address_t src_address;
9488   u8 src_address_set = 0;
9489   u32 vrf_id = ~0;
9490   u32 path_mtu = ~0;
9491   u32 template_interval = ~0;
9492   u8 udp_checksum = 0;
9493   f64 timeout;
9494
9495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9496     {
9497       if (unformat (i, "collector_address %U", unformat_ip4_address,
9498                     &collector_address))
9499         collector_address_set = 1;
9500       else if (unformat (i, "collector_port %d", &collector_port))
9501         ;
9502       else if (unformat (i, "src_address %U", unformat_ip4_address,
9503                          &src_address))
9504         src_address_set = 1;
9505       else if (unformat (i, "vrf_id %d", &vrf_id))
9506         ;
9507       else if (unformat (i, "path_mtu %d", &path_mtu))
9508         ;
9509       else if (unformat (i, "template_interval %d", &template_interval))
9510         ;
9511       else if (unformat (i, "udp_checksum"))
9512         udp_checksum = 1;
9513       else
9514         break;
9515     }
9516
9517   if (collector_address_set == 0)
9518     {
9519       errmsg ("collector_address required\n");
9520       return -99;
9521     }
9522
9523   if (src_address_set == 0)
9524     {
9525       errmsg ("src_address required\n");
9526       return -99;
9527     }
9528
9529   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9530
9531   memcpy (mp->collector_address, collector_address.data,
9532           sizeof (collector_address.data));
9533   mp->collector_port = htons ((u16) collector_port);
9534   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9535   mp->vrf_id = htonl (vrf_id);
9536   mp->path_mtu = htonl (path_mtu);
9537   mp->template_interval = htonl (template_interval);
9538   mp->udp_checksum = udp_checksum;
9539
9540   S;
9541   W;
9542   /* NOTREACHED */
9543 }
9544
9545 static int
9546 api_set_ipfix_classify_stream (vat_main_t * vam)
9547 {
9548   unformat_input_t *i = vam->input;
9549   vl_api_set_ipfix_classify_stream_t *mp;
9550   u32 domain_id = 0;
9551   u32 src_port = UDP_DST_PORT_ipfix;
9552   f64 timeout;
9553
9554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9555     {
9556       if (unformat (i, "domain %d", &domain_id))
9557         ;
9558       else if (unformat (i, "src_port %d", &src_port))
9559         ;
9560       else
9561         {
9562           errmsg ("unknown input `%U'", format_unformat_error, i);
9563           return -99;
9564         }
9565     }
9566
9567   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9568
9569   mp->domain_id = htonl (domain_id);
9570   mp->src_port = htons ((u16) src_port);
9571
9572   S;
9573   W;
9574   /* NOTREACHED */
9575 }
9576
9577 static int
9578 api_ipfix_classify_table_add_del (vat_main_t * vam)
9579 {
9580   unformat_input_t *i = vam->input;
9581   vl_api_ipfix_classify_table_add_del_t *mp;
9582   int is_add = -1;
9583   u32 classify_table_index = ~0;
9584   u8 ip_version = 0;
9585   u8 transport_protocol = 255;
9586   f64 timeout;
9587
9588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9589     {
9590       if (unformat (i, "add"))
9591         is_add = 1;
9592       else if (unformat (i, "del"))
9593         is_add = 0;
9594       else if (unformat (i, "table %d", &classify_table_index))
9595         ;
9596       else if (unformat (i, "ip4"))
9597         ip_version = 4;
9598       else if (unformat (i, "ip6"))
9599         ip_version = 6;
9600       else if (unformat (i, "tcp"))
9601         transport_protocol = 6;
9602       else if (unformat (i, "udp"))
9603         transport_protocol = 17;
9604       else
9605         {
9606           errmsg ("unknown input `%U'", format_unformat_error, i);
9607           return -99;
9608         }
9609     }
9610
9611   if (is_add == -1)
9612     {
9613       errmsg ("expecting: add|del");
9614       return -99;
9615     }
9616   if (classify_table_index == ~0)
9617     {
9618       errmsg ("classifier table not specified");
9619       return -99;
9620     }
9621   if (ip_version == 0)
9622     {
9623       errmsg ("IP version not specified");
9624       return -99;
9625     }
9626
9627   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9628
9629   mp->is_add = is_add;
9630   mp->table_id = htonl (classify_table_index);
9631   mp->ip_version = ip_version;
9632   mp->transport_protocol = transport_protocol;
9633
9634   S;
9635   W;
9636   /* NOTREACHED */
9637 }
9638
9639 static int
9640 api_get_node_index (vat_main_t * vam)
9641 {
9642   unformat_input_t *i = vam->input;
9643   vl_api_get_node_index_t *mp;
9644   f64 timeout;
9645   u8 *name = 0;
9646
9647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9648     {
9649       if (unformat (i, "node %s", &name))
9650         ;
9651       else
9652         break;
9653     }
9654   if (name == 0)
9655     {
9656       errmsg ("node name required\n");
9657       return -99;
9658     }
9659   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9660     {
9661       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9662       return -99;
9663     }
9664
9665   M (GET_NODE_INDEX, get_node_index);
9666   clib_memcpy (mp->node_name, name, vec_len (name));
9667   vec_free (name);
9668
9669   S;
9670   W;
9671   /* NOTREACHED */
9672   return 0;
9673 }
9674
9675 static int
9676 api_get_next_index (vat_main_t * vam)
9677 {
9678   unformat_input_t *i = vam->input;
9679   vl_api_get_next_index_t *mp;
9680   f64 timeout;
9681   u8 *node_name = 0, *next_node_name = 0;
9682
9683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9684     {
9685       if (unformat (i, "node-name %s", &node_name))
9686         ;
9687       else if (unformat (i, "next-node-name %s", &next_node_name))
9688         break;
9689     }
9690
9691   if (node_name == 0)
9692     {
9693       errmsg ("node name required\n");
9694       return -99;
9695     }
9696   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9697     {
9698       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9699       return -99;
9700     }
9701
9702   if (next_node_name == 0)
9703     {
9704       errmsg ("next node name required\n");
9705       return -99;
9706     }
9707   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9708     {
9709       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9710       return -99;
9711     }
9712
9713   M (GET_NEXT_INDEX, get_next_index);
9714   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9715   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9716   vec_free (node_name);
9717   vec_free (next_node_name);
9718
9719   S;
9720   W;
9721   /* NOTREACHED */
9722   return 0;
9723 }
9724
9725 static int
9726 api_add_node_next (vat_main_t * vam)
9727 {
9728   unformat_input_t *i = vam->input;
9729   vl_api_add_node_next_t *mp;
9730   f64 timeout;
9731   u8 *name = 0;
9732   u8 *next = 0;
9733
9734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9735     {
9736       if (unformat (i, "node %s", &name))
9737         ;
9738       else if (unformat (i, "next %s", &next))
9739         ;
9740       else
9741         break;
9742     }
9743   if (name == 0)
9744     {
9745       errmsg ("node name required\n");
9746       return -99;
9747     }
9748   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9749     {
9750       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9751       return -99;
9752     }
9753   if (next == 0)
9754     {
9755       errmsg ("next node required\n");
9756       return -99;
9757     }
9758   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9759     {
9760       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9761       return -99;
9762     }
9763
9764   M (ADD_NODE_NEXT, add_node_next);
9765   clib_memcpy (mp->node_name, name, vec_len (name));
9766   clib_memcpy (mp->next_name, next, vec_len (next));
9767   vec_free (name);
9768   vec_free (next);
9769
9770   S;
9771   W;
9772   /* NOTREACHED */
9773   return 0;
9774 }
9775
9776 static int
9777 api_l2tpv3_create_tunnel (vat_main_t * vam)
9778 {
9779   unformat_input_t *i = vam->input;
9780   ip6_address_t client_address, our_address;
9781   int client_address_set = 0;
9782   int our_address_set = 0;
9783   u32 local_session_id = 0;
9784   u32 remote_session_id = 0;
9785   u64 local_cookie = 0;
9786   u64 remote_cookie = 0;
9787   u8 l2_sublayer_present = 0;
9788   vl_api_l2tpv3_create_tunnel_t *mp;
9789   f64 timeout;
9790
9791   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9792     {
9793       if (unformat (i, "client_address %U", unformat_ip6_address,
9794                     &client_address))
9795         client_address_set = 1;
9796       else if (unformat (i, "our_address %U", unformat_ip6_address,
9797                          &our_address))
9798         our_address_set = 1;
9799       else if (unformat (i, "local_session_id %d", &local_session_id))
9800         ;
9801       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9802         ;
9803       else if (unformat (i, "local_cookie %lld", &local_cookie))
9804         ;
9805       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9806         ;
9807       else if (unformat (i, "l2-sublayer-present"))
9808         l2_sublayer_present = 1;
9809       else
9810         break;
9811     }
9812
9813   if (client_address_set == 0)
9814     {
9815       errmsg ("client_address required\n");
9816       return -99;
9817     }
9818
9819   if (our_address_set == 0)
9820     {
9821       errmsg ("our_address required\n");
9822       return -99;
9823     }
9824
9825   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9826
9827   clib_memcpy (mp->client_address, client_address.as_u8,
9828                sizeof (mp->client_address));
9829
9830   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9831
9832   mp->local_session_id = ntohl (local_session_id);
9833   mp->remote_session_id = ntohl (remote_session_id);
9834   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9835   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9836   mp->l2_sublayer_present = l2_sublayer_present;
9837   mp->is_ipv6 = 1;
9838
9839   S;
9840   W;
9841   /* NOTREACHED */
9842   return 0;
9843 }
9844
9845 static int
9846 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9847 {
9848   unformat_input_t *i = vam->input;
9849   u32 sw_if_index;
9850   u8 sw_if_index_set = 0;
9851   u64 new_local_cookie = 0;
9852   u64 new_remote_cookie = 0;
9853   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9854   f64 timeout;
9855
9856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9857     {
9858       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9859         sw_if_index_set = 1;
9860       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9861         sw_if_index_set = 1;
9862       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9863         ;
9864       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9865         ;
9866       else
9867         break;
9868     }
9869
9870   if (sw_if_index_set == 0)
9871     {
9872       errmsg ("missing interface name or sw_if_index\n");
9873       return -99;
9874     }
9875
9876   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9877
9878   mp->sw_if_index = ntohl (sw_if_index);
9879   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9880   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9881
9882   S;
9883   W;
9884   /* NOTREACHED */
9885   return 0;
9886 }
9887
9888 static int
9889 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9890 {
9891   unformat_input_t *i = vam->input;
9892   vl_api_l2tpv3_interface_enable_disable_t *mp;
9893   f64 timeout;
9894   u32 sw_if_index;
9895   u8 sw_if_index_set = 0;
9896   u8 enable_disable = 1;
9897
9898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9899     {
9900       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9901         sw_if_index_set = 1;
9902       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9903         sw_if_index_set = 1;
9904       else if (unformat (i, "enable"))
9905         enable_disable = 1;
9906       else if (unformat (i, "disable"))
9907         enable_disable = 0;
9908       else
9909         break;
9910     }
9911
9912   if (sw_if_index_set == 0)
9913     {
9914       errmsg ("missing interface name or sw_if_index\n");
9915       return -99;
9916     }
9917
9918   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9919
9920   mp->sw_if_index = ntohl (sw_if_index);
9921   mp->enable_disable = enable_disable;
9922
9923   S;
9924   W;
9925   /* NOTREACHED */
9926   return 0;
9927 }
9928
9929 static int
9930 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9931 {
9932   unformat_input_t *i = vam->input;
9933   vl_api_l2tpv3_set_lookup_key_t *mp;
9934   f64 timeout;
9935   u8 key = ~0;
9936
9937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9938     {
9939       if (unformat (i, "lookup_v6_src"))
9940         key = L2T_LOOKUP_SRC_ADDRESS;
9941       else if (unformat (i, "lookup_v6_dst"))
9942         key = L2T_LOOKUP_DST_ADDRESS;
9943       else if (unformat (i, "lookup_session_id"))
9944         key = L2T_LOOKUP_SESSION_ID;
9945       else
9946         break;
9947     }
9948
9949   if (key == (u8) ~ 0)
9950     {
9951       errmsg ("l2tp session lookup key unset\n");
9952       return -99;
9953     }
9954
9955   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9956
9957   mp->key = key;
9958
9959   S;
9960   W;
9961   /* NOTREACHED */
9962   return 0;
9963 }
9964
9965 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9966   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9967 {
9968   vat_main_t *vam = &vat_main;
9969
9970   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9971            format_ip6_address, mp->our_address,
9972            format_ip6_address, mp->client_address,
9973            clib_net_to_host_u32 (mp->sw_if_index));
9974
9975   fformat (vam->ofp,
9976            "   local cookies %016llx %016llx remote cookie %016llx\n",
9977            clib_net_to_host_u64 (mp->local_cookie[0]),
9978            clib_net_to_host_u64 (mp->local_cookie[1]),
9979            clib_net_to_host_u64 (mp->remote_cookie));
9980
9981   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9982            clib_net_to_host_u32 (mp->local_session_id),
9983            clib_net_to_host_u32 (mp->remote_session_id));
9984
9985   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9986            mp->l2_sublayer_present ? "preset" : "absent");
9987
9988 }
9989
9990 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9991   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9992 {
9993   vat_main_t *vam = &vat_main;
9994   vat_json_node_t *node = NULL;
9995   struct in6_addr addr;
9996
9997   if (VAT_JSON_ARRAY != vam->json_tree.type)
9998     {
9999       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10000       vat_json_init_array (&vam->json_tree);
10001     }
10002   node = vat_json_array_add (&vam->json_tree);
10003
10004   vat_json_init_object (node);
10005
10006   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10007   vat_json_object_add_ip6 (node, "our_address", addr);
10008   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10009   vat_json_object_add_ip6 (node, "client_address", addr);
10010
10011   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10012   vat_json_init_array (lc);
10013   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10014   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10015   vat_json_object_add_uint (node, "remote_cookie",
10016                             clib_net_to_host_u64 (mp->remote_cookie));
10017
10018   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10019   vat_json_object_add_uint (node, "local_session_id",
10020                             clib_net_to_host_u32 (mp->local_session_id));
10021   vat_json_object_add_uint (node, "remote_session_id",
10022                             clib_net_to_host_u32 (mp->remote_session_id));
10023   vat_json_object_add_string_copy (node, "l2_sublayer",
10024                                    mp->l2_sublayer_present ? (u8 *) "present"
10025                                    : (u8 *) "absent");
10026 }
10027
10028 static int
10029 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10030 {
10031   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10032   f64 timeout;
10033
10034   /* Get list of l2tpv3-tunnel interfaces */
10035   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10036   S;
10037
10038   /* Use a control ping for synchronization */
10039   {
10040     vl_api_control_ping_t *mp;
10041     M (CONTROL_PING, control_ping);
10042     S;
10043   }
10044   W;
10045 }
10046
10047
10048 static void vl_api_sw_interface_tap_details_t_handler
10049   (vl_api_sw_interface_tap_details_t * mp)
10050 {
10051   vat_main_t *vam = &vat_main;
10052
10053   fformat (vam->ofp, "%-16s %d\n",
10054            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10055 }
10056
10057 static void vl_api_sw_interface_tap_details_t_handler_json
10058   (vl_api_sw_interface_tap_details_t * mp)
10059 {
10060   vat_main_t *vam = &vat_main;
10061   vat_json_node_t *node = NULL;
10062
10063   if (VAT_JSON_ARRAY != vam->json_tree.type)
10064     {
10065       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10066       vat_json_init_array (&vam->json_tree);
10067     }
10068   node = vat_json_array_add (&vam->json_tree);
10069
10070   vat_json_init_object (node);
10071   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10072   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10073 }
10074
10075 static int
10076 api_sw_interface_tap_dump (vat_main_t * vam)
10077 {
10078   vl_api_sw_interface_tap_dump_t *mp;
10079   f64 timeout;
10080
10081   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10082   /* Get list of tap interfaces */
10083   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10084   S;
10085
10086   /* Use a control ping for synchronization */
10087   {
10088     vl_api_control_ping_t *mp;
10089     M (CONTROL_PING, control_ping);
10090     S;
10091   }
10092   W;
10093 }
10094
10095 static uword unformat_vxlan_decap_next
10096   (unformat_input_t * input, va_list * args)
10097 {
10098   u32 *result = va_arg (*args, u32 *);
10099   u32 tmp;
10100
10101   if (unformat (input, "l2"))
10102     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10103   else if (unformat (input, "%d", &tmp))
10104     *result = tmp;
10105   else
10106     return 0;
10107   return 1;
10108 }
10109
10110 static int
10111 api_vxlan_add_del_tunnel (vat_main_t * vam)
10112 {
10113   unformat_input_t *line_input = vam->input;
10114   vl_api_vxlan_add_del_tunnel_t *mp;
10115   f64 timeout;
10116   ip4_address_t src4, dst4;
10117   ip6_address_t src6, dst6;
10118   u8 is_add = 1;
10119   u8 ipv4_set = 0, ipv6_set = 0;
10120   u8 src_set = 0;
10121   u8 dst_set = 0;
10122   u32 encap_vrf_id = 0;
10123   u32 decap_next_index = ~0;
10124   u32 vni = 0;
10125
10126   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10127     {
10128       if (unformat (line_input, "del"))
10129         is_add = 0;
10130       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10131         {
10132           ipv4_set = 1;
10133           src_set = 1;
10134         }
10135       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10136         {
10137           ipv4_set = 1;
10138           dst_set = 1;
10139         }
10140       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
10141         {
10142           ipv6_set = 1;
10143           src_set = 1;
10144         }
10145       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
10146         {
10147           ipv6_set = 1;
10148           dst_set = 1;
10149         }
10150       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10151         ;
10152       else if (unformat (line_input, "decap-next %U",
10153                          unformat_vxlan_decap_next, &decap_next_index))
10154         ;
10155       else if (unformat (line_input, "vni %d", &vni))
10156         ;
10157       else
10158         {
10159           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10160           return -99;
10161         }
10162     }
10163
10164   if (src_set == 0)
10165     {
10166       errmsg ("tunnel src address not specified\n");
10167       return -99;
10168     }
10169   if (dst_set == 0)
10170     {
10171       errmsg ("tunnel dst address not specified\n");
10172       return -99;
10173     }
10174
10175   if (ipv4_set && ipv6_set)
10176     {
10177       errmsg ("both IPv4 and IPv6 addresses specified");
10178       return -99;
10179     }
10180
10181   if ((vni == 0) || (vni >> 24))
10182     {
10183       errmsg ("vni not specified or out of range\n");
10184       return -99;
10185     }
10186
10187   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10188
10189   if (ipv6_set)
10190     {
10191       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
10192       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
10193     }
10194   else
10195     {
10196       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10197       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10198     }
10199   mp->encap_vrf_id = ntohl (encap_vrf_id);
10200   mp->decap_next_index = ntohl (decap_next_index);
10201   mp->vni = ntohl (vni);
10202   mp->is_add = is_add;
10203   mp->is_ipv6 = ipv6_set;
10204
10205   S;
10206   W;
10207   /* NOTREACHED */
10208   return 0;
10209 }
10210
10211 static void vl_api_vxlan_tunnel_details_t_handler
10212   (vl_api_vxlan_tunnel_details_t * mp)
10213 {
10214   vat_main_t *vam = &vat_main;
10215
10216   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
10217            ntohl (mp->sw_if_index),
10218            format_ip46_address, &(mp->src_address[0]),
10219            IP46_TYPE_ANY,
10220            format_ip46_address, &(mp->dst_address[0]),
10221            IP46_TYPE_ANY,
10222            ntohl (mp->encap_vrf_id),
10223            ntohl (mp->decap_next_index), ntohl (mp->vni));
10224 }
10225
10226 static void vl_api_vxlan_tunnel_details_t_handler_json
10227   (vl_api_vxlan_tunnel_details_t * mp)
10228 {
10229   vat_main_t *vam = &vat_main;
10230   vat_json_node_t *node = NULL;
10231   struct in_addr ip4;
10232   struct in6_addr ip6;
10233
10234   if (VAT_JSON_ARRAY != vam->json_tree.type)
10235     {
10236       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10237       vat_json_init_array (&vam->json_tree);
10238     }
10239   node = vat_json_array_add (&vam->json_tree);
10240
10241   vat_json_init_object (node);
10242   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10243   if (mp->is_ipv6)
10244     {
10245       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
10246       vat_json_object_add_ip6 (node, "src_address", ip6);
10247       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
10248       vat_json_object_add_ip6 (node, "dst_address", ip6);
10249     }
10250   else
10251     {
10252       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
10253       vat_json_object_add_ip4 (node, "src_address", ip4);
10254       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
10255       vat_json_object_add_ip4 (node, "dst_address", ip4);
10256     }
10257   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10258   vat_json_object_add_uint (node, "decap_next_index",
10259                             ntohl (mp->decap_next_index));
10260   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10261   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10262 }
10263
10264 static int
10265 api_vxlan_tunnel_dump (vat_main_t * vam)
10266 {
10267   unformat_input_t *i = vam->input;
10268   vl_api_vxlan_tunnel_dump_t *mp;
10269   f64 timeout;
10270   u32 sw_if_index;
10271   u8 sw_if_index_set = 0;
10272
10273   /* Parse args required to build the message */
10274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10275     {
10276       if (unformat (i, "sw_if_index %d", &sw_if_index))
10277         sw_if_index_set = 1;
10278       else
10279         break;
10280     }
10281
10282   if (sw_if_index_set == 0)
10283     {
10284       sw_if_index = ~0;
10285     }
10286
10287   if (!vam->json_output)
10288     {
10289       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
10290                "sw_if_index", "src_address", "dst_address",
10291                "encap_vrf_id", "decap_next_index", "vni");
10292     }
10293
10294   /* Get list of vxlan-tunnel interfaces */
10295   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10296
10297   mp->sw_if_index = htonl (sw_if_index);
10298
10299   S;
10300
10301   /* Use a control ping for synchronization */
10302   {
10303     vl_api_control_ping_t *mp;
10304     M (CONTROL_PING, control_ping);
10305     S;
10306   }
10307   W;
10308 }
10309
10310 static int
10311 api_gre_add_del_tunnel (vat_main_t * vam)
10312 {
10313   unformat_input_t *line_input = vam->input;
10314   vl_api_gre_add_del_tunnel_t *mp;
10315   f64 timeout;
10316   ip4_address_t src4, dst4;
10317   u8 is_add = 1;
10318   u8 teb = 0;
10319   u8 src_set = 0;
10320   u8 dst_set = 0;
10321   u32 outer_fib_id = 0;
10322
10323   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10324     {
10325       if (unformat (line_input, "del"))
10326         is_add = 0;
10327       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10328         src_set = 1;
10329       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10330         dst_set = 1;
10331       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10332         ;
10333       else if (unformat (line_input, "teb"))
10334         teb = 1;
10335       else
10336         {
10337           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10338           return -99;
10339         }
10340     }
10341
10342   if (src_set == 0)
10343     {
10344       errmsg ("tunnel src address not specified\n");
10345       return -99;
10346     }
10347   if (dst_set == 0)
10348     {
10349       errmsg ("tunnel dst address not specified\n");
10350       return -99;
10351     }
10352
10353
10354   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10355
10356   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10357   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10358   mp->outer_fib_id = ntohl (outer_fib_id);
10359   mp->is_add = is_add;
10360   mp->teb = teb;
10361
10362   S;
10363   W;
10364   /* NOTREACHED */
10365   return 0;
10366 }
10367
10368 static void vl_api_gre_tunnel_details_t_handler
10369   (vl_api_gre_tunnel_details_t * mp)
10370 {
10371   vat_main_t *vam = &vat_main;
10372
10373   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10374            ntohl (mp->sw_if_index),
10375            format_ip4_address, &mp->src_address,
10376            format_ip4_address, &mp->dst_address,
10377            mp->teb, ntohl (mp->outer_fib_id));
10378 }
10379
10380 static void vl_api_gre_tunnel_details_t_handler_json
10381   (vl_api_gre_tunnel_details_t * mp)
10382 {
10383   vat_main_t *vam = &vat_main;
10384   vat_json_node_t *node = NULL;
10385   struct in_addr ip4;
10386
10387   if (VAT_JSON_ARRAY != vam->json_tree.type)
10388     {
10389       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10390       vat_json_init_array (&vam->json_tree);
10391     }
10392   node = vat_json_array_add (&vam->json_tree);
10393
10394   vat_json_init_object (node);
10395   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10396   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10397   vat_json_object_add_ip4 (node, "src_address", ip4);
10398   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10399   vat_json_object_add_ip4 (node, "dst_address", ip4);
10400   vat_json_object_add_uint (node, "teb", mp->teb);
10401   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10402 }
10403
10404 static int
10405 api_gre_tunnel_dump (vat_main_t * vam)
10406 {
10407   unformat_input_t *i = vam->input;
10408   vl_api_gre_tunnel_dump_t *mp;
10409   f64 timeout;
10410   u32 sw_if_index;
10411   u8 sw_if_index_set = 0;
10412
10413   /* Parse args required to build the message */
10414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10415     {
10416       if (unformat (i, "sw_if_index %d", &sw_if_index))
10417         sw_if_index_set = 1;
10418       else
10419         break;
10420     }
10421
10422   if (sw_if_index_set == 0)
10423     {
10424       sw_if_index = ~0;
10425     }
10426
10427   if (!vam->json_output)
10428     {
10429       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10430                "sw_if_index", "src_address", "dst_address", "teb",
10431                "outer_fib_id");
10432     }
10433
10434   /* Get list of gre-tunnel interfaces */
10435   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10436
10437   mp->sw_if_index = htonl (sw_if_index);
10438
10439   S;
10440
10441   /* Use a control ping for synchronization */
10442   {
10443     vl_api_control_ping_t *mp;
10444     M (CONTROL_PING, control_ping);
10445     S;
10446   }
10447   W;
10448 }
10449
10450 static int
10451 api_l2_fib_clear_table (vat_main_t * vam)
10452 {
10453 //  unformat_input_t * i = vam->input;
10454   vl_api_l2_fib_clear_table_t *mp;
10455   f64 timeout;
10456
10457   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10458
10459   S;
10460   W;
10461   /* NOTREACHED */
10462   return 0;
10463 }
10464
10465 static int
10466 api_l2_interface_efp_filter (vat_main_t * vam)
10467 {
10468   unformat_input_t *i = vam->input;
10469   vl_api_l2_interface_efp_filter_t *mp;
10470   f64 timeout;
10471   u32 sw_if_index;
10472   u8 enable = 1;
10473   u8 sw_if_index_set = 0;
10474
10475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10476     {
10477       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10478         sw_if_index_set = 1;
10479       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10480         sw_if_index_set = 1;
10481       else if (unformat (i, "enable"))
10482         enable = 1;
10483       else if (unformat (i, "disable"))
10484         enable = 0;
10485       else
10486         {
10487           clib_warning ("parse error '%U'", format_unformat_error, i);
10488           return -99;
10489         }
10490     }
10491
10492   if (sw_if_index_set == 0)
10493     {
10494       errmsg ("missing sw_if_index\n");
10495       return -99;
10496     }
10497
10498   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10499
10500   mp->sw_if_index = ntohl (sw_if_index);
10501   mp->enable_disable = enable;
10502
10503   S;
10504   W;
10505   /* NOTREACHED */
10506   return 0;
10507 }
10508
10509 #define foreach_vtr_op                          \
10510 _("disable",  L2_VTR_DISABLED)                  \
10511 _("push-1",  L2_VTR_PUSH_1)                     \
10512 _("push-2",  L2_VTR_PUSH_2)                     \
10513 _("pop-1",  L2_VTR_POP_1)                       \
10514 _("pop-2",  L2_VTR_POP_2)                       \
10515 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10516 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10517 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10518 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10519
10520 static int
10521 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10522 {
10523   unformat_input_t *i = vam->input;
10524   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10525   f64 timeout;
10526   u32 sw_if_index;
10527   u8 sw_if_index_set = 0;
10528   u8 vtr_op_set = 0;
10529   u32 vtr_op = 0;
10530   u32 push_dot1q = 1;
10531   u32 tag1 = ~0;
10532   u32 tag2 = ~0;
10533
10534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10535     {
10536       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10537         sw_if_index_set = 1;
10538       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10539         sw_if_index_set = 1;
10540       else if (unformat (i, "vtr_op %d", &vtr_op))
10541         vtr_op_set = 1;
10542 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10543       foreach_vtr_op
10544 #undef _
10545         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10546         ;
10547       else if (unformat (i, "tag1 %d", &tag1))
10548         ;
10549       else if (unformat (i, "tag2 %d", &tag2))
10550         ;
10551       else
10552         {
10553           clib_warning ("parse error '%U'", format_unformat_error, i);
10554           return -99;
10555         }
10556     }
10557
10558   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10559     {
10560       errmsg ("missing vtr operation or sw_if_index\n");
10561       return -99;
10562     }
10563
10564   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10565     mp->sw_if_index = ntohl (sw_if_index);
10566   mp->vtr_op = ntohl (vtr_op);
10567   mp->push_dot1q = ntohl (push_dot1q);
10568   mp->tag1 = ntohl (tag1);
10569   mp->tag2 = ntohl (tag2);
10570
10571   S;
10572   W;
10573   /* NOTREACHED */
10574   return 0;
10575 }
10576
10577 static int
10578 api_create_vhost_user_if (vat_main_t * vam)
10579 {
10580   unformat_input_t *i = vam->input;
10581   vl_api_create_vhost_user_if_t *mp;
10582   f64 timeout;
10583   u8 *file_name;
10584   u8 is_server = 0;
10585   u8 file_name_set = 0;
10586   u32 custom_dev_instance = ~0;
10587   u8 hwaddr[6];
10588   u8 use_custom_mac = 0;
10589
10590   /* Shut up coverity */
10591   memset (hwaddr, 0, sizeof (hwaddr));
10592
10593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10594     {
10595       if (unformat (i, "socket %s", &file_name))
10596         {
10597           file_name_set = 1;
10598         }
10599       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10600         ;
10601       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10602         use_custom_mac = 1;
10603       else if (unformat (i, "server"))
10604         is_server = 1;
10605       else
10606         break;
10607     }
10608
10609   if (file_name_set == 0)
10610     {
10611       errmsg ("missing socket file name\n");
10612       return -99;
10613     }
10614
10615   if (vec_len (file_name) > 255)
10616     {
10617       errmsg ("socket file name too long\n");
10618       return -99;
10619     }
10620   vec_add1 (file_name, 0);
10621
10622   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10623
10624   mp->is_server = is_server;
10625   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10626   vec_free (file_name);
10627   if (custom_dev_instance != ~0)
10628     {
10629       mp->renumber = 1;
10630       mp->custom_dev_instance = ntohl (custom_dev_instance);
10631     }
10632   mp->use_custom_mac = use_custom_mac;
10633   clib_memcpy (mp->mac_address, hwaddr, 6);
10634
10635   S;
10636   W;
10637   /* NOTREACHED */
10638   return 0;
10639 }
10640
10641 static int
10642 api_modify_vhost_user_if (vat_main_t * vam)
10643 {
10644   unformat_input_t *i = vam->input;
10645   vl_api_modify_vhost_user_if_t *mp;
10646   f64 timeout;
10647   u8 *file_name;
10648   u8 is_server = 0;
10649   u8 file_name_set = 0;
10650   u32 custom_dev_instance = ~0;
10651   u8 sw_if_index_set = 0;
10652   u32 sw_if_index = (u32) ~ 0;
10653
10654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10655     {
10656       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10657         sw_if_index_set = 1;
10658       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10659         sw_if_index_set = 1;
10660       else if (unformat (i, "socket %s", &file_name))
10661         {
10662           file_name_set = 1;
10663         }
10664       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10665         ;
10666       else if (unformat (i, "server"))
10667         is_server = 1;
10668       else
10669         break;
10670     }
10671
10672   if (sw_if_index_set == 0)
10673     {
10674       errmsg ("missing sw_if_index or interface name\n");
10675       return -99;
10676     }
10677
10678   if (file_name_set == 0)
10679     {
10680       errmsg ("missing socket file name\n");
10681       return -99;
10682     }
10683
10684   if (vec_len (file_name) > 255)
10685     {
10686       errmsg ("socket file name too long\n");
10687       return -99;
10688     }
10689   vec_add1 (file_name, 0);
10690
10691   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10692
10693   mp->sw_if_index = ntohl (sw_if_index);
10694   mp->is_server = is_server;
10695   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10696   vec_free (file_name);
10697   if (custom_dev_instance != ~0)
10698     {
10699       mp->renumber = 1;
10700       mp->custom_dev_instance = ntohl (custom_dev_instance);
10701     }
10702
10703   S;
10704   W;
10705   /* NOTREACHED */
10706   return 0;
10707 }
10708
10709 static int
10710 api_delete_vhost_user_if (vat_main_t * vam)
10711 {
10712   unformat_input_t *i = vam->input;
10713   vl_api_delete_vhost_user_if_t *mp;
10714   f64 timeout;
10715   u32 sw_if_index = ~0;
10716   u8 sw_if_index_set = 0;
10717
10718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10719     {
10720       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10721         sw_if_index_set = 1;
10722       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10723         sw_if_index_set = 1;
10724       else
10725         break;
10726     }
10727
10728   if (sw_if_index_set == 0)
10729     {
10730       errmsg ("missing sw_if_index or interface name\n");
10731       return -99;
10732     }
10733
10734
10735   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10736
10737   mp->sw_if_index = ntohl (sw_if_index);
10738
10739   S;
10740   W;
10741   /* NOTREACHED */
10742   return 0;
10743 }
10744
10745 static void vl_api_sw_interface_vhost_user_details_t_handler
10746   (vl_api_sw_interface_vhost_user_details_t * mp)
10747 {
10748   vat_main_t *vam = &vat_main;
10749
10750   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10751            (char *) mp->interface_name,
10752            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10753            clib_net_to_host_u64 (mp->features), mp->is_server,
10754            ntohl (mp->num_regions), (char *) mp->sock_filename);
10755   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10756 }
10757
10758 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10759   (vl_api_sw_interface_vhost_user_details_t * mp)
10760 {
10761   vat_main_t *vam = &vat_main;
10762   vat_json_node_t *node = NULL;
10763
10764   if (VAT_JSON_ARRAY != vam->json_tree.type)
10765     {
10766       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10767       vat_json_init_array (&vam->json_tree);
10768     }
10769   node = vat_json_array_add (&vam->json_tree);
10770
10771   vat_json_init_object (node);
10772   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10773   vat_json_object_add_string_copy (node, "interface_name",
10774                                    mp->interface_name);
10775   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10776                             ntohl (mp->virtio_net_hdr_sz));
10777   vat_json_object_add_uint (node, "features",
10778                             clib_net_to_host_u64 (mp->features));
10779   vat_json_object_add_uint (node, "is_server", mp->is_server);
10780   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10781   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10782   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10783 }
10784
10785 static int
10786 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10787 {
10788   vl_api_sw_interface_vhost_user_dump_t *mp;
10789   f64 timeout;
10790   fformat (vam->ofp,
10791            "Interface name           idx hdr_sz features server regions filename\n");
10792
10793   /* Get list of vhost-user interfaces */
10794   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10795   S;
10796
10797   /* Use a control ping for synchronization */
10798   {
10799     vl_api_control_ping_t *mp;
10800     M (CONTROL_PING, control_ping);
10801     S;
10802   }
10803   W;
10804 }
10805
10806 static int
10807 api_show_version (vat_main_t * vam)
10808 {
10809   vl_api_show_version_t *mp;
10810   f64 timeout;
10811
10812   M (SHOW_VERSION, show_version);
10813
10814   S;
10815   W;
10816   /* NOTREACHED */
10817   return 0;
10818 }
10819
10820
10821 static int
10822 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10823 {
10824   unformat_input_t *line_input = vam->input;
10825   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10826   f64 timeout;
10827   ip4_address_t local4, remote4;
10828   ip6_address_t local6, remote6;
10829   u8 is_add = 1;
10830   u8 ipv4_set = 0, ipv6_set = 0;
10831   u8 local_set = 0;
10832   u8 remote_set = 0;
10833   u32 encap_vrf_id = 0;
10834   u32 decap_vrf_id = 0;
10835   u8 protocol = ~0;
10836   u32 vni;
10837   u8 vni_set = 0;
10838
10839   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10840     {
10841       if (unformat (line_input, "del"))
10842         is_add = 0;
10843       else if (unformat (line_input, "local %U",
10844                          unformat_ip4_address, &local4))
10845         {
10846           local_set = 1;
10847           ipv4_set = 1;
10848         }
10849       else if (unformat (line_input, "remote %U",
10850                          unformat_ip4_address, &remote4))
10851         {
10852           remote_set = 1;
10853           ipv4_set = 1;
10854         }
10855       else if (unformat (line_input, "local %U",
10856                          unformat_ip6_address, &local6))
10857         {
10858           local_set = 1;
10859           ipv6_set = 1;
10860         }
10861       else if (unformat (line_input, "remote %U",
10862                          unformat_ip6_address, &remote6))
10863         {
10864           remote_set = 1;
10865           ipv6_set = 1;
10866         }
10867       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10868         ;
10869       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10870         ;
10871       else if (unformat (line_input, "vni %d", &vni))
10872         vni_set = 1;
10873       else if (unformat (line_input, "next-ip4"))
10874         protocol = 1;
10875       else if (unformat (line_input, "next-ip6"))
10876         protocol = 2;
10877       else if (unformat (line_input, "next-ethernet"))
10878         protocol = 3;
10879       else if (unformat (line_input, "next-nsh"))
10880         protocol = 4;
10881       else
10882         {
10883           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10884           return -99;
10885         }
10886     }
10887
10888   if (local_set == 0)
10889     {
10890       errmsg ("tunnel local address not specified\n");
10891       return -99;
10892     }
10893   if (remote_set == 0)
10894     {
10895       errmsg ("tunnel remote address not specified\n");
10896       return -99;
10897     }
10898   if (ipv4_set && ipv6_set)
10899     {
10900       errmsg ("both IPv4 and IPv6 addresses specified");
10901       return -99;
10902     }
10903
10904   if (vni_set == 0)
10905     {
10906       errmsg ("vni not specified\n");
10907       return -99;
10908     }
10909
10910   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10911
10912
10913   if (ipv6_set)
10914     {
10915       clib_memcpy (&mp->local, &local6, sizeof (local6));
10916       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10917     }
10918   else
10919     {
10920       clib_memcpy (&mp->local, &local4, sizeof (local4));
10921       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10922     }
10923
10924   mp->encap_vrf_id = ntohl (encap_vrf_id);
10925   mp->decap_vrf_id = ntohl (decap_vrf_id);
10926   mp->protocol = ntohl (protocol);
10927   mp->vni = ntohl (vni);
10928   mp->is_add = is_add;
10929   mp->is_ipv6 = ipv6_set;
10930
10931   S;
10932   W;
10933   /* NOTREACHED */
10934   return 0;
10935 }
10936
10937 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10938   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10939 {
10940   vat_main_t *vam = &vat_main;
10941
10942   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10943            ntohl (mp->sw_if_index),
10944            format_ip46_address, &(mp->local[0]),
10945            format_ip46_address, &(mp->remote[0]),
10946            ntohl (mp->vni),
10947            ntohl (mp->protocol),
10948            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10949 }
10950
10951 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10952   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10953 {
10954   vat_main_t *vam = &vat_main;
10955   vat_json_node_t *node = NULL;
10956   struct in_addr ip4;
10957   struct in6_addr ip6;
10958
10959   if (VAT_JSON_ARRAY != vam->json_tree.type)
10960     {
10961       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10962       vat_json_init_array (&vam->json_tree);
10963     }
10964   node = vat_json_array_add (&vam->json_tree);
10965
10966   vat_json_init_object (node);
10967   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10968   if (mp->is_ipv6)
10969     {
10970       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10971       vat_json_object_add_ip6 (node, "local", ip6);
10972       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10973       vat_json_object_add_ip6 (node, "remote", ip6);
10974     }
10975   else
10976     {
10977       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10978       vat_json_object_add_ip4 (node, "local", ip4);
10979       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10980       vat_json_object_add_ip4 (node, "remote", ip4);
10981     }
10982   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10983   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10984   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10985   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10986   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10987 }
10988
10989 static int
10990 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10991 {
10992   unformat_input_t *i = vam->input;
10993   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10994   f64 timeout;
10995   u32 sw_if_index;
10996   u8 sw_if_index_set = 0;
10997
10998   /* Parse args required to build the message */
10999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11000     {
11001       if (unformat (i, "sw_if_index %d", &sw_if_index))
11002         sw_if_index_set = 1;
11003       else
11004         break;
11005     }
11006
11007   if (sw_if_index_set == 0)
11008     {
11009       sw_if_index = ~0;
11010     }
11011
11012   if (!vam->json_output)
11013     {
11014       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
11015                "sw_if_index", "local", "remote", "vni",
11016                "protocol", "encap_vrf_id", "decap_vrf_id");
11017     }
11018
11019   /* Get list of vxlan-tunnel interfaces */
11020   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11021
11022   mp->sw_if_index = htonl (sw_if_index);
11023
11024   S;
11025
11026   /* Use a control ping for synchronization */
11027   {
11028     vl_api_control_ping_t *mp;
11029     M (CONTROL_PING, control_ping);
11030     S;
11031   }
11032   W;
11033 }
11034
11035 u8 *
11036 format_l2_fib_mac_address (u8 * s, va_list * args)
11037 {
11038   u8 *a = va_arg (*args, u8 *);
11039
11040   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11041                  a[2], a[3], a[4], a[5], a[6], a[7]);
11042 }
11043
11044 static void vl_api_l2_fib_table_entry_t_handler
11045   (vl_api_l2_fib_table_entry_t * mp)
11046 {
11047   vat_main_t *vam = &vat_main;
11048
11049   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11050            "       %d       %d     %d\n",
11051            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11052            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11053            mp->bvi_mac);
11054 }
11055
11056 static void vl_api_l2_fib_table_entry_t_handler_json
11057   (vl_api_l2_fib_table_entry_t * mp)
11058 {
11059   vat_main_t *vam = &vat_main;
11060   vat_json_node_t *node = NULL;
11061
11062   if (VAT_JSON_ARRAY != vam->json_tree.type)
11063     {
11064       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11065       vat_json_init_array (&vam->json_tree);
11066     }
11067   node = vat_json_array_add (&vam->json_tree);
11068
11069   vat_json_init_object (node);
11070   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11071   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11072   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11073   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11074   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11075   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11076 }
11077
11078 static int
11079 api_l2_fib_table_dump (vat_main_t * vam)
11080 {
11081   unformat_input_t *i = vam->input;
11082   vl_api_l2_fib_table_dump_t *mp;
11083   f64 timeout;
11084   u32 bd_id;
11085   u8 bd_id_set = 0;
11086
11087   /* Parse args required to build the message */
11088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11089     {
11090       if (unformat (i, "bd_id %d", &bd_id))
11091         bd_id_set = 1;
11092       else
11093         break;
11094     }
11095
11096   if (bd_id_set == 0)
11097     {
11098       errmsg ("missing bridge domain\n");
11099       return -99;
11100     }
11101
11102   fformat (vam->ofp,
11103            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11104
11105   /* Get list of l2 fib entries */
11106   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11107
11108   mp->bd_id = ntohl (bd_id);
11109   S;
11110
11111   /* Use a control ping for synchronization */
11112   {
11113     vl_api_control_ping_t *mp;
11114     M (CONTROL_PING, control_ping);
11115     S;
11116   }
11117   W;
11118 }
11119
11120
11121 static int
11122 api_interface_name_renumber (vat_main_t * vam)
11123 {
11124   unformat_input_t *line_input = vam->input;
11125   vl_api_interface_name_renumber_t *mp;
11126   u32 sw_if_index = ~0;
11127   f64 timeout;
11128   u32 new_show_dev_instance = ~0;
11129
11130   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11131     {
11132       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11133                     &sw_if_index))
11134         ;
11135       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11136         ;
11137       else if (unformat (line_input, "new_show_dev_instance %d",
11138                          &new_show_dev_instance))
11139         ;
11140       else
11141         break;
11142     }
11143
11144   if (sw_if_index == ~0)
11145     {
11146       errmsg ("missing interface name or sw_if_index\n");
11147       return -99;
11148     }
11149
11150   if (new_show_dev_instance == ~0)
11151     {
11152       errmsg ("missing new_show_dev_instance\n");
11153       return -99;
11154     }
11155
11156   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11157
11158   mp->sw_if_index = ntohl (sw_if_index);
11159   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11160
11161   S;
11162   W;
11163 }
11164
11165 static int
11166 api_want_ip4_arp_events (vat_main_t * vam)
11167 {
11168   unformat_input_t *line_input = vam->input;
11169   vl_api_want_ip4_arp_events_t *mp;
11170   f64 timeout;
11171   ip4_address_t address;
11172   int address_set = 0;
11173   u32 enable_disable = 1;
11174
11175   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11176     {
11177       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11178         address_set = 1;
11179       else if (unformat (line_input, "del"))
11180         enable_disable = 0;
11181       else
11182         break;
11183     }
11184
11185   if (address_set == 0)
11186     {
11187       errmsg ("missing addresses\n");
11188       return -99;
11189     }
11190
11191   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11192   mp->enable_disable = enable_disable;
11193   mp->pid = getpid ();
11194   mp->address = address.as_u32;
11195
11196   S;
11197   W;
11198 }
11199
11200 static int
11201 api_want_ip6_nd_events (vat_main_t * vam)
11202 {
11203   unformat_input_t *line_input = vam->input;
11204   vl_api_want_ip6_nd_events_t *mp;
11205   f64 timeout;
11206   ip6_address_t address;
11207   int address_set = 0;
11208   u32 enable_disable = 1;
11209
11210   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11211     {
11212       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11213         address_set = 1;
11214       else if (unformat (line_input, "del"))
11215         enable_disable = 0;
11216       else
11217         break;
11218     }
11219
11220   if (address_set == 0)
11221     {
11222       errmsg ("missing addresses\n");
11223       return -99;
11224     }
11225
11226   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11227   mp->enable_disable = enable_disable;
11228   mp->pid = getpid ();
11229   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11230
11231   S;
11232   W;
11233 }
11234
11235 static int
11236 api_input_acl_set_interface (vat_main_t * vam)
11237 {
11238   unformat_input_t *i = vam->input;
11239   vl_api_input_acl_set_interface_t *mp;
11240   f64 timeout;
11241   u32 sw_if_index;
11242   int sw_if_index_set;
11243   u32 ip4_table_index = ~0;
11244   u32 ip6_table_index = ~0;
11245   u32 l2_table_index = ~0;
11246   u8 is_add = 1;
11247
11248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11249     {
11250       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11251         sw_if_index_set = 1;
11252       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11253         sw_if_index_set = 1;
11254       else if (unformat (i, "del"))
11255         is_add = 0;
11256       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11257         ;
11258       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11259         ;
11260       else if (unformat (i, "l2-table %d", &l2_table_index))
11261         ;
11262       else
11263         {
11264           clib_warning ("parse error '%U'", format_unformat_error, i);
11265           return -99;
11266         }
11267     }
11268
11269   if (sw_if_index_set == 0)
11270     {
11271       errmsg ("missing interface name or sw_if_index\n");
11272       return -99;
11273     }
11274
11275   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11276
11277   mp->sw_if_index = ntohl (sw_if_index);
11278   mp->ip4_table_index = ntohl (ip4_table_index);
11279   mp->ip6_table_index = ntohl (ip6_table_index);
11280   mp->l2_table_index = ntohl (l2_table_index);
11281   mp->is_add = is_add;
11282
11283   S;
11284   W;
11285   /* NOTREACHED */
11286   return 0;
11287 }
11288
11289 static int
11290 api_ip_address_dump (vat_main_t * vam)
11291 {
11292   unformat_input_t *i = vam->input;
11293   vl_api_ip_address_dump_t *mp;
11294   u32 sw_if_index = ~0;
11295   u8 sw_if_index_set = 0;
11296   u8 ipv4_set = 0;
11297   u8 ipv6_set = 0;
11298   f64 timeout;
11299
11300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11301     {
11302       if (unformat (i, "sw_if_index %d", &sw_if_index))
11303         sw_if_index_set = 1;
11304       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11305         sw_if_index_set = 1;
11306       else if (unformat (i, "ipv4"))
11307         ipv4_set = 1;
11308       else if (unformat (i, "ipv6"))
11309         ipv6_set = 1;
11310       else
11311         break;
11312     }
11313
11314   if (ipv4_set && ipv6_set)
11315     {
11316       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11317       return -99;
11318     }
11319
11320   if ((!ipv4_set) && (!ipv6_set))
11321     {
11322       errmsg ("no ipv4 nor ipv6 flag set\n");
11323       return -99;
11324     }
11325
11326   if (sw_if_index_set == 0)
11327     {
11328       errmsg ("missing interface name or sw_if_index\n");
11329       return -99;
11330     }
11331
11332   vam->current_sw_if_index = sw_if_index;
11333   vam->is_ipv6 = ipv6_set;
11334
11335   M (IP_ADDRESS_DUMP, ip_address_dump);
11336   mp->sw_if_index = ntohl (sw_if_index);
11337   mp->is_ipv6 = ipv6_set;
11338   S;
11339
11340   /* Use a control ping for synchronization */
11341   {
11342     vl_api_control_ping_t *mp;
11343     M (CONTROL_PING, control_ping);
11344     S;
11345   }
11346   W;
11347 }
11348
11349 static int
11350 api_ip_dump (vat_main_t * vam)
11351 {
11352   vl_api_ip_dump_t *mp;
11353   unformat_input_t *in = vam->input;
11354   int ipv4_set = 0;
11355   int ipv6_set = 0;
11356   int is_ipv6;
11357   f64 timeout;
11358   int i;
11359
11360   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11361     {
11362       if (unformat (in, "ipv4"))
11363         ipv4_set = 1;
11364       else if (unformat (in, "ipv6"))
11365         ipv6_set = 1;
11366       else
11367         break;
11368     }
11369
11370   if (ipv4_set && ipv6_set)
11371     {
11372       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11373       return -99;
11374     }
11375
11376   if ((!ipv4_set) && (!ipv6_set))
11377     {
11378       errmsg ("no ipv4 nor ipv6 flag set\n");
11379       return -99;
11380     }
11381
11382   is_ipv6 = ipv6_set;
11383   vam->is_ipv6 = is_ipv6;
11384
11385   /* free old data */
11386   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11387     {
11388       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11389     }
11390   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11391
11392   M (IP_DUMP, ip_dump);
11393   mp->is_ipv6 = ipv6_set;
11394   S;
11395
11396   /* Use a control ping for synchronization */
11397   {
11398     vl_api_control_ping_t *mp;
11399     M (CONTROL_PING, control_ping);
11400     S;
11401   }
11402   W;
11403 }
11404
11405 static int
11406 api_ipsec_spd_add_del (vat_main_t * vam)
11407 {
11408 #if DPDK > 0
11409   unformat_input_t *i = vam->input;
11410   vl_api_ipsec_spd_add_del_t *mp;
11411   f64 timeout;
11412   u32 spd_id = ~0;
11413   u8 is_add = 1;
11414
11415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11416     {
11417       if (unformat (i, "spd_id %d", &spd_id))
11418         ;
11419       else if (unformat (i, "del"))
11420         is_add = 0;
11421       else
11422         {
11423           clib_warning ("parse error '%U'", format_unformat_error, i);
11424           return -99;
11425         }
11426     }
11427   if (spd_id == ~0)
11428     {
11429       errmsg ("spd_id must be set\n");
11430       return -99;
11431     }
11432
11433   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11434
11435   mp->spd_id = ntohl (spd_id);
11436   mp->is_add = is_add;
11437
11438   S;
11439   W;
11440   /* NOTREACHED */
11441   return 0;
11442 #else
11443   clib_warning ("unsupported (no dpdk)");
11444   return -99;
11445 #endif
11446 }
11447
11448 static int
11449 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11450 {
11451 #if DPDK > 0
11452   unformat_input_t *i = vam->input;
11453   vl_api_ipsec_interface_add_del_spd_t *mp;
11454   f64 timeout;
11455   u32 sw_if_index;
11456   u8 sw_if_index_set = 0;
11457   u32 spd_id = (u32) ~ 0;
11458   u8 is_add = 1;
11459
11460   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11461     {
11462       if (unformat (i, "del"))
11463         is_add = 0;
11464       else if (unformat (i, "spd_id %d", &spd_id))
11465         ;
11466       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11467         sw_if_index_set = 1;
11468       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11469         sw_if_index_set = 1;
11470       else
11471         {
11472           clib_warning ("parse error '%U'", format_unformat_error, i);
11473           return -99;
11474         }
11475
11476     }
11477
11478   if (spd_id == (u32) ~ 0)
11479     {
11480       errmsg ("spd_id must be set\n");
11481       return -99;
11482     }
11483
11484   if (sw_if_index_set == 0)
11485     {
11486       errmsg ("missing interface name or sw_if_index\n");
11487       return -99;
11488     }
11489
11490   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11491
11492   mp->spd_id = ntohl (spd_id);
11493   mp->sw_if_index = ntohl (sw_if_index);
11494   mp->is_add = is_add;
11495
11496   S;
11497   W;
11498   /* NOTREACHED */
11499   return 0;
11500 #else
11501   clib_warning ("unsupported (no dpdk)");
11502   return -99;
11503 #endif
11504 }
11505
11506 static int
11507 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11508 {
11509 #if DPDK > 0
11510   unformat_input_t *i = vam->input;
11511   vl_api_ipsec_spd_add_del_entry_t *mp;
11512   f64 timeout;
11513   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11514   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11515   i32 priority = 0;
11516   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11517   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11518   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11519   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11520
11521   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11522   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11523   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11524   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11525   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11526   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11527
11528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11529     {
11530       if (unformat (i, "del"))
11531         is_add = 0;
11532       if (unformat (i, "outbound"))
11533         is_outbound = 1;
11534       if (unformat (i, "inbound"))
11535         is_outbound = 0;
11536       else if (unformat (i, "spd_id %d", &spd_id))
11537         ;
11538       else if (unformat (i, "sa_id %d", &sa_id))
11539         ;
11540       else if (unformat (i, "priority %d", &priority))
11541         ;
11542       else if (unformat (i, "protocol %d", &protocol))
11543         ;
11544       else if (unformat (i, "lport_start %d", &lport_start))
11545         ;
11546       else if (unformat (i, "lport_stop %d", &lport_stop))
11547         ;
11548       else if (unformat (i, "rport_start %d", &rport_start))
11549         ;
11550       else if (unformat (i, "rport_stop %d", &rport_stop))
11551         ;
11552       else
11553         if (unformat
11554             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11555         {
11556           is_ipv6 = 0;
11557           is_ip_any = 0;
11558         }
11559       else
11560         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11561         {
11562           is_ipv6 = 0;
11563           is_ip_any = 0;
11564         }
11565       else
11566         if (unformat
11567             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11568         {
11569           is_ipv6 = 0;
11570           is_ip_any = 0;
11571         }
11572       else
11573         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11574         {
11575           is_ipv6 = 0;
11576           is_ip_any = 0;
11577         }
11578       else
11579         if (unformat
11580             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11581         {
11582           is_ipv6 = 1;
11583           is_ip_any = 0;
11584         }
11585       else
11586         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11587         {
11588           is_ipv6 = 1;
11589           is_ip_any = 0;
11590         }
11591       else
11592         if (unformat
11593             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11594         {
11595           is_ipv6 = 1;
11596           is_ip_any = 0;
11597         }
11598       else
11599         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11600         {
11601           is_ipv6 = 1;
11602           is_ip_any = 0;
11603         }
11604       else
11605         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11606         {
11607           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11608             {
11609               clib_warning ("unsupported action: 'resolve'");
11610               return -99;
11611             }
11612         }
11613       else
11614         {
11615           clib_warning ("parse error '%U'", format_unformat_error, i);
11616           return -99;
11617         }
11618
11619     }
11620
11621   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11622
11623   mp->spd_id = ntohl (spd_id);
11624   mp->priority = ntohl (priority);
11625   mp->is_outbound = is_outbound;
11626
11627   mp->is_ipv6 = is_ipv6;
11628   if (is_ipv6 || is_ip_any)
11629     {
11630       clib_memcpy (mp->remote_address_start, &raddr6_start,
11631                    sizeof (ip6_address_t));
11632       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11633                    sizeof (ip6_address_t));
11634       clib_memcpy (mp->local_address_start, &laddr6_start,
11635                    sizeof (ip6_address_t));
11636       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11637                    sizeof (ip6_address_t));
11638     }
11639   else
11640     {
11641       clib_memcpy (mp->remote_address_start, &raddr4_start,
11642                    sizeof (ip4_address_t));
11643       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11644                    sizeof (ip4_address_t));
11645       clib_memcpy (mp->local_address_start, &laddr4_start,
11646                    sizeof (ip4_address_t));
11647       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11648                    sizeof (ip4_address_t));
11649     }
11650   mp->protocol = (u8) protocol;
11651   mp->local_port_start = ntohs ((u16) lport_start);
11652   mp->local_port_stop = ntohs ((u16) lport_stop);
11653   mp->remote_port_start = ntohs ((u16) rport_start);
11654   mp->remote_port_stop = ntohs ((u16) rport_stop);
11655   mp->policy = (u8) policy;
11656   mp->sa_id = ntohl (sa_id);
11657   mp->is_add = is_add;
11658   mp->is_ip_any = is_ip_any;
11659   S;
11660   W;
11661   /* NOTREACHED */
11662   return 0;
11663 #else
11664   clib_warning ("unsupported (no dpdk)");
11665   return -99;
11666 #endif
11667 }
11668
11669 static int
11670 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11671 {
11672 #if DPDK > 0
11673   unformat_input_t *i = vam->input;
11674   vl_api_ipsec_sad_add_del_entry_t *mp;
11675   f64 timeout;
11676   u32 sad_id = 0, spi = 0;
11677   u8 *ck = 0, *ik = 0;
11678   u8 is_add = 1;
11679
11680   u8 protocol = IPSEC_PROTOCOL_AH;
11681   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11682   u32 crypto_alg = 0, integ_alg = 0;
11683   ip4_address_t tun_src4;
11684   ip4_address_t tun_dst4;
11685   ip6_address_t tun_src6;
11686   ip6_address_t tun_dst6;
11687
11688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11689     {
11690       if (unformat (i, "del"))
11691         is_add = 0;
11692       else if (unformat (i, "sad_id %d", &sad_id))
11693         ;
11694       else if (unformat (i, "spi %d", &spi))
11695         ;
11696       else if (unformat (i, "esp"))
11697         protocol = IPSEC_PROTOCOL_ESP;
11698       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11699         {
11700           is_tunnel = 1;
11701           is_tunnel_ipv6 = 0;
11702         }
11703       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11704         {
11705           is_tunnel = 1;
11706           is_tunnel_ipv6 = 0;
11707         }
11708       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11709         {
11710           is_tunnel = 1;
11711           is_tunnel_ipv6 = 1;
11712         }
11713       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11714         {
11715           is_tunnel = 1;
11716           is_tunnel_ipv6 = 1;
11717         }
11718       else
11719         if (unformat
11720             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11721         {
11722           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11723               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
11724             {
11725               clib_warning ("unsupported crypto-alg: '%U'",
11726                             format_ipsec_crypto_alg, crypto_alg);
11727               return -99;
11728             }
11729         }
11730       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11731         ;
11732       else
11733         if (unformat
11734             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11735         {
11736           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11737               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
11738             {
11739               clib_warning ("unsupported integ-alg: '%U'",
11740                             format_ipsec_integ_alg, integ_alg);
11741               return -99;
11742             }
11743         }
11744       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11745         ;
11746       else
11747         {
11748           clib_warning ("parse error '%U'", format_unformat_error, i);
11749           return -99;
11750         }
11751
11752     }
11753
11754   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11755
11756   mp->sad_id = ntohl (sad_id);
11757   mp->is_add = is_add;
11758   mp->protocol = protocol;
11759   mp->spi = ntohl (spi);
11760   mp->is_tunnel = is_tunnel;
11761   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11762   mp->crypto_algorithm = crypto_alg;
11763   mp->integrity_algorithm = integ_alg;
11764   mp->crypto_key_length = vec_len (ck);
11765   mp->integrity_key_length = vec_len (ik);
11766
11767   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11768     mp->crypto_key_length = sizeof (mp->crypto_key);
11769
11770   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11771     mp->integrity_key_length = sizeof (mp->integrity_key);
11772
11773   if (ck)
11774     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11775   if (ik)
11776     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11777
11778   if (is_tunnel)
11779     {
11780       if (is_tunnel_ipv6)
11781         {
11782           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11783                        sizeof (ip6_address_t));
11784           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11785                        sizeof (ip6_address_t));
11786         }
11787       else
11788         {
11789           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11790                        sizeof (ip4_address_t));
11791           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11792                        sizeof (ip4_address_t));
11793         }
11794     }
11795
11796   S;
11797   W;
11798   /* NOTREACHED */
11799   return 0;
11800 #else
11801   clib_warning ("unsupported (no dpdk)");
11802   return -99;
11803 #endif
11804 }
11805
11806 static int
11807 api_ipsec_sa_set_key (vat_main_t * vam)
11808 {
11809 #if DPDK > 0
11810   unformat_input_t *i = vam->input;
11811   vl_api_ipsec_sa_set_key_t *mp;
11812   f64 timeout;
11813   u32 sa_id;
11814   u8 *ck = 0, *ik = 0;
11815
11816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11817     {
11818       if (unformat (i, "sa_id %d", &sa_id))
11819         ;
11820       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11821         ;
11822       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11823         ;
11824       else
11825         {
11826           clib_warning ("parse error '%U'", format_unformat_error, i);
11827           return -99;
11828         }
11829     }
11830
11831   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11832
11833   mp->sa_id = ntohl (sa_id);
11834   mp->crypto_key_length = vec_len (ck);
11835   mp->integrity_key_length = vec_len (ik);
11836
11837   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11838     mp->crypto_key_length = sizeof (mp->crypto_key);
11839
11840   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11841     mp->integrity_key_length = sizeof (mp->integrity_key);
11842
11843   if (ck)
11844     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11845   if (ik)
11846     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11847
11848   S;
11849   W;
11850   /* NOTREACHED */
11851   return 0;
11852 #else
11853   clib_warning ("unsupported (no dpdk)");
11854   return -99;
11855 #endif
11856 }
11857
11858 static int
11859 api_ikev2_profile_add_del (vat_main_t * vam)
11860 {
11861 #if DPDK > 0
11862   unformat_input_t *i = vam->input;
11863   vl_api_ikev2_profile_add_del_t *mp;
11864   f64 timeout;
11865   u8 is_add = 1;
11866   u8 *name = 0;
11867
11868   const char *valid_chars = "a-zA-Z0-9_";
11869
11870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11871     {
11872       if (unformat (i, "del"))
11873         is_add = 0;
11874       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11875         vec_add1 (name, 0);
11876       else
11877         {
11878           errmsg ("parse error '%U'", format_unformat_error, i);
11879           return -99;
11880         }
11881     }
11882
11883   if (!vec_len (name))
11884     {
11885       errmsg ("profile name must be specified");
11886       return -99;
11887     }
11888
11889   if (vec_len (name) > 64)
11890     {
11891       errmsg ("profile name too long");
11892       return -99;
11893     }
11894
11895   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11896
11897   clib_memcpy (mp->name, name, vec_len (name));
11898   mp->is_add = is_add;
11899   vec_free (name);
11900
11901   S;
11902   W;
11903   /* NOTREACHED */
11904   return 0;
11905 #else
11906   clib_warning ("unsupported (no dpdk)");
11907   return -99;
11908 #endif
11909 }
11910
11911 static int
11912 api_ikev2_profile_set_auth (vat_main_t * vam)
11913 {
11914 #if DPDK > 0
11915   unformat_input_t *i = vam->input;
11916   vl_api_ikev2_profile_set_auth_t *mp;
11917   f64 timeout;
11918   u8 *name = 0;
11919   u8 *data = 0;
11920   u32 auth_method = 0;
11921   u8 is_hex = 0;
11922
11923   const char *valid_chars = "a-zA-Z0-9_";
11924
11925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11926     {
11927       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11928         vec_add1 (name, 0);
11929       else if (unformat (i, "auth_method %U",
11930                          unformat_ikev2_auth_method, &auth_method))
11931         ;
11932       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11933         is_hex = 1;
11934       else if (unformat (i, "auth_data %v", &data))
11935         ;
11936       else
11937         {
11938           errmsg ("parse error '%U'", format_unformat_error, i);
11939           return -99;
11940         }
11941     }
11942
11943   if (!vec_len (name))
11944     {
11945       errmsg ("profile name must be specified");
11946       return -99;
11947     }
11948
11949   if (vec_len (name) > 64)
11950     {
11951       errmsg ("profile name too long");
11952       return -99;
11953     }
11954
11955   if (!vec_len (data))
11956     {
11957       errmsg ("auth_data must be specified");
11958       return -99;
11959     }
11960
11961   if (!auth_method)
11962     {
11963       errmsg ("auth_method must be specified");
11964       return -99;
11965     }
11966
11967   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11968
11969   mp->is_hex = is_hex;
11970   mp->auth_method = (u8) auth_method;
11971   mp->data_len = vec_len (data);
11972   clib_memcpy (mp->name, name, vec_len (name));
11973   clib_memcpy (mp->data, data, vec_len (data));
11974   vec_free (name);
11975   vec_free (data);
11976
11977   S;
11978   W;
11979   /* NOTREACHED */
11980   return 0;
11981 #else
11982   clib_warning ("unsupported (no dpdk)");
11983   return -99;
11984 #endif
11985 }
11986
11987 static int
11988 api_ikev2_profile_set_id (vat_main_t * vam)
11989 {
11990 #if DPDK > 0
11991   unformat_input_t *i = vam->input;
11992   vl_api_ikev2_profile_set_id_t *mp;
11993   f64 timeout;
11994   u8 *name = 0;
11995   u8 *data = 0;
11996   u8 is_local = 0;
11997   u32 id_type = 0;
11998   ip4_address_t ip4;
11999
12000   const char *valid_chars = "a-zA-Z0-9_";
12001
12002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12003     {
12004       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12005         vec_add1 (name, 0);
12006       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12007         ;
12008       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12009         {
12010           data = vec_new (u8, 4);
12011           clib_memcpy (data, ip4.as_u8, 4);
12012         }
12013       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12014         ;
12015       else if (unformat (i, "id_data %v", &data))
12016         ;
12017       else if (unformat (i, "local"))
12018         is_local = 1;
12019       else if (unformat (i, "remote"))
12020         is_local = 0;
12021       else
12022         {
12023           errmsg ("parse error '%U'", format_unformat_error, i);
12024           return -99;
12025         }
12026     }
12027
12028   if (!vec_len (name))
12029     {
12030       errmsg ("profile name must be specified");
12031       return -99;
12032     }
12033
12034   if (vec_len (name) > 64)
12035     {
12036       errmsg ("profile name too long");
12037       return -99;
12038     }
12039
12040   if (!vec_len (data))
12041     {
12042       errmsg ("id_data must be specified");
12043       return -99;
12044     }
12045
12046   if (!id_type)
12047     {
12048       errmsg ("id_type must be specified");
12049       return -99;
12050     }
12051
12052   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12053
12054   mp->is_local = is_local;
12055   mp->id_type = (u8) id_type;
12056   mp->data_len = vec_len (data);
12057   clib_memcpy (mp->name, name, vec_len (name));
12058   clib_memcpy (mp->data, data, vec_len (data));
12059   vec_free (name);
12060   vec_free (data);
12061
12062   S;
12063   W;
12064   /* NOTREACHED */
12065   return 0;
12066 #else
12067   clib_warning ("unsupported (no dpdk)");
12068   return -99;
12069 #endif
12070 }
12071
12072 static int
12073 api_ikev2_profile_set_ts (vat_main_t * vam)
12074 {
12075 #if DPDK > 0
12076   unformat_input_t *i = vam->input;
12077   vl_api_ikev2_profile_set_ts_t *mp;
12078   f64 timeout;
12079   u8 *name = 0;
12080   u8 is_local = 0;
12081   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12082   ip4_address_t start_addr, end_addr;
12083
12084   const char *valid_chars = "a-zA-Z0-9_";
12085
12086   start_addr.as_u32 = 0;
12087   end_addr.as_u32 = (u32) ~ 0;
12088
12089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12090     {
12091       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12092         vec_add1 (name, 0);
12093       else if (unformat (i, "protocol %d", &proto))
12094         ;
12095       else if (unformat (i, "start_port %d", &start_port))
12096         ;
12097       else if (unformat (i, "end_port %d", &end_port))
12098         ;
12099       else
12100         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12101         ;
12102       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12103         ;
12104       else if (unformat (i, "local"))
12105         is_local = 1;
12106       else if (unformat (i, "remote"))
12107         is_local = 0;
12108       else
12109         {
12110           errmsg ("parse error '%U'", format_unformat_error, i);
12111           return -99;
12112         }
12113     }
12114
12115   if (!vec_len (name))
12116     {
12117       errmsg ("profile name must be specified");
12118       return -99;
12119     }
12120
12121   if (vec_len (name) > 64)
12122     {
12123       errmsg ("profile name too long");
12124       return -99;
12125     }
12126
12127   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12128
12129   mp->is_local = is_local;
12130   mp->proto = (u8) proto;
12131   mp->start_port = (u16) start_port;
12132   mp->end_port = (u16) end_port;
12133   mp->start_addr = start_addr.as_u32;
12134   mp->end_addr = end_addr.as_u32;
12135   clib_memcpy (mp->name, name, vec_len (name));
12136   vec_free (name);
12137
12138   S;
12139   W;
12140   /* NOTREACHED */
12141   return 0;
12142 #else
12143   clib_warning ("unsupported (no dpdk)");
12144   return -99;
12145 #endif
12146 }
12147
12148 static int
12149 api_ikev2_set_local_key (vat_main_t * vam)
12150 {
12151 #if DPDK > 0
12152   unformat_input_t *i = vam->input;
12153   vl_api_ikev2_set_local_key_t *mp;
12154   f64 timeout;
12155   u8 *file = 0;
12156
12157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12158     {
12159       if (unformat (i, "file %v", &file))
12160         vec_add1 (file, 0);
12161       else
12162         {
12163           errmsg ("parse error '%U'", format_unformat_error, i);
12164           return -99;
12165         }
12166     }
12167
12168   if (!vec_len (file))
12169     {
12170       errmsg ("RSA key file must be specified");
12171       return -99;
12172     }
12173
12174   if (vec_len (file) > 256)
12175     {
12176       errmsg ("file name too long");
12177       return -99;
12178     }
12179
12180   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12181
12182   clib_memcpy (mp->key_file, file, vec_len (file));
12183   vec_free (file);
12184
12185   S;
12186   W;
12187   /* NOTREACHED */
12188   return 0;
12189 #else
12190   clib_warning ("unsupported (no dpdk)");
12191   return -99;
12192 #endif
12193 }
12194
12195 /*
12196  * MAP
12197  */
12198 static int
12199 api_map_add_domain (vat_main_t * vam)
12200 {
12201   unformat_input_t *i = vam->input;
12202   vl_api_map_add_domain_t *mp;
12203   f64 timeout;
12204
12205   ip4_address_t ip4_prefix;
12206   ip6_address_t ip6_prefix;
12207   ip6_address_t ip6_src;
12208   u32 num_m_args = 0;
12209   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12210     0, psid_length = 0;
12211   u8 is_translation = 0;
12212   u32 mtu = 0;
12213   u32 ip6_src_len = 128;
12214
12215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12216     {
12217       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12218                     &ip4_prefix, &ip4_prefix_len))
12219         num_m_args++;
12220       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12221                          &ip6_prefix, &ip6_prefix_len))
12222         num_m_args++;
12223       else
12224         if (unformat
12225             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12226              &ip6_src_len))
12227         num_m_args++;
12228       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12229         num_m_args++;
12230       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12231         num_m_args++;
12232       else if (unformat (i, "psid-offset %d", &psid_offset))
12233         num_m_args++;
12234       else if (unformat (i, "psid-len %d", &psid_length))
12235         num_m_args++;
12236       else if (unformat (i, "mtu %d", &mtu))
12237         num_m_args++;
12238       else if (unformat (i, "map-t"))
12239         is_translation = 1;
12240       else
12241         {
12242           clib_warning ("parse error '%U'", format_unformat_error, i);
12243           return -99;
12244         }
12245     }
12246
12247   if (num_m_args < 3)
12248     {
12249       errmsg ("mandatory argument(s) missing\n");
12250       return -99;
12251     }
12252
12253   /* Construct the API message */
12254   M (MAP_ADD_DOMAIN, map_add_domain);
12255
12256   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12257   mp->ip4_prefix_len = ip4_prefix_len;
12258
12259   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12260   mp->ip6_prefix_len = ip6_prefix_len;
12261
12262   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12263   mp->ip6_src_prefix_len = ip6_src_len;
12264
12265   mp->ea_bits_len = ea_bits_len;
12266   mp->psid_offset = psid_offset;
12267   mp->psid_length = psid_length;
12268   mp->is_translation = is_translation;
12269   mp->mtu = htons (mtu);
12270
12271   /* send it... */
12272   S;
12273
12274   /* Wait for a reply, return good/bad news  */
12275   W;
12276 }
12277
12278 static int
12279 api_map_del_domain (vat_main_t * vam)
12280 {
12281   unformat_input_t *i = vam->input;
12282   vl_api_map_del_domain_t *mp;
12283   f64 timeout;
12284
12285   u32 num_m_args = 0;
12286   u32 index;
12287
12288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12289     {
12290       if (unformat (i, "index %d", &index))
12291         num_m_args++;
12292       else
12293         {
12294           clib_warning ("parse error '%U'", format_unformat_error, i);
12295           return -99;
12296         }
12297     }
12298
12299   if (num_m_args != 1)
12300     {
12301       errmsg ("mandatory argument(s) missing\n");
12302       return -99;
12303     }
12304
12305   /* Construct the API message */
12306   M (MAP_DEL_DOMAIN, map_del_domain);
12307
12308   mp->index = ntohl (index);
12309
12310   /* send it... */
12311   S;
12312
12313   /* Wait for a reply, return good/bad news  */
12314   W;
12315 }
12316
12317 static int
12318 api_map_add_del_rule (vat_main_t * vam)
12319 {
12320   unformat_input_t *i = vam->input;
12321   vl_api_map_add_del_rule_t *mp;
12322   f64 timeout;
12323   u8 is_add = 1;
12324   ip6_address_t ip6_dst;
12325   u32 num_m_args = 0, index, psid = 0;
12326
12327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12328     {
12329       if (unformat (i, "index %d", &index))
12330         num_m_args++;
12331       else if (unformat (i, "psid %d", &psid))
12332         num_m_args++;
12333       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12334         num_m_args++;
12335       else if (unformat (i, "del"))
12336         {
12337           is_add = 0;
12338         }
12339       else
12340         {
12341           clib_warning ("parse error '%U'", format_unformat_error, i);
12342           return -99;
12343         }
12344     }
12345
12346   /* Construct the API message */
12347   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12348
12349   mp->index = ntohl (index);
12350   mp->is_add = is_add;
12351   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12352   mp->psid = ntohs (psid);
12353
12354   /* send it... */
12355   S;
12356
12357   /* Wait for a reply, return good/bad news  */
12358   W;
12359 }
12360
12361 static int
12362 api_map_domain_dump (vat_main_t * vam)
12363 {
12364   vl_api_map_domain_dump_t *mp;
12365   f64 timeout;
12366
12367   /* Construct the API message */
12368   M (MAP_DOMAIN_DUMP, map_domain_dump);
12369
12370   /* send it... */
12371   S;
12372
12373   /* Use a control ping for synchronization */
12374   {
12375     vl_api_control_ping_t *mp;
12376     M (CONTROL_PING, control_ping);
12377     S;
12378   }
12379   W;
12380 }
12381
12382 static int
12383 api_map_rule_dump (vat_main_t * vam)
12384 {
12385   unformat_input_t *i = vam->input;
12386   vl_api_map_rule_dump_t *mp;
12387   f64 timeout;
12388   u32 domain_index = ~0;
12389
12390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12391     {
12392       if (unformat (i, "index %u", &domain_index))
12393         ;
12394       else
12395         break;
12396     }
12397
12398   if (domain_index == ~0)
12399     {
12400       clib_warning ("parse error: domain index expected");
12401       return -99;
12402     }
12403
12404   /* Construct the API message */
12405   M (MAP_RULE_DUMP, map_rule_dump);
12406
12407   mp->domain_index = htonl (domain_index);
12408
12409   /* send it... */
12410   S;
12411
12412   /* Use a control ping for synchronization */
12413   {
12414     vl_api_control_ping_t *mp;
12415     M (CONTROL_PING, control_ping);
12416     S;
12417   }
12418   W;
12419 }
12420
12421 static void vl_api_map_add_domain_reply_t_handler
12422   (vl_api_map_add_domain_reply_t * mp)
12423 {
12424   vat_main_t *vam = &vat_main;
12425   i32 retval = ntohl (mp->retval);
12426
12427   if (vam->async_mode)
12428     {
12429       vam->async_errors += (retval < 0);
12430     }
12431   else
12432     {
12433       vam->retval = retval;
12434       vam->result_ready = 1;
12435     }
12436 }
12437
12438 static void vl_api_map_add_domain_reply_t_handler_json
12439   (vl_api_map_add_domain_reply_t * mp)
12440 {
12441   vat_main_t *vam = &vat_main;
12442   vat_json_node_t node;
12443
12444   vat_json_init_object (&node);
12445   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12446   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12447
12448   vat_json_print (vam->ofp, &node);
12449   vat_json_free (&node);
12450
12451   vam->retval = ntohl (mp->retval);
12452   vam->result_ready = 1;
12453 }
12454
12455 static int
12456 api_get_first_msg_id (vat_main_t * vam)
12457 {
12458   vl_api_get_first_msg_id_t *mp;
12459   f64 timeout;
12460   unformat_input_t *i = vam->input;
12461   u8 *name;
12462   u8 name_set = 0;
12463
12464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12465     {
12466       if (unformat (i, "client %s", &name))
12467         name_set = 1;
12468       else
12469         break;
12470     }
12471
12472   if (name_set == 0)
12473     {
12474       errmsg ("missing client name\n");
12475       return -99;
12476     }
12477   vec_add1 (name, 0);
12478
12479   if (vec_len (name) > 63)
12480     {
12481       errmsg ("client name too long\n");
12482       return -99;
12483     }
12484
12485   M (GET_FIRST_MSG_ID, get_first_msg_id);
12486   clib_memcpy (mp->name, name, vec_len (name));
12487   S;
12488   W;
12489   /* NOTREACHED */
12490   return 0;
12491 }
12492
12493 static int
12494 api_cop_interface_enable_disable (vat_main_t * vam)
12495 {
12496   unformat_input_t *line_input = vam->input;
12497   vl_api_cop_interface_enable_disable_t *mp;
12498   f64 timeout;
12499   u32 sw_if_index = ~0;
12500   u8 enable_disable = 1;
12501
12502   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12503     {
12504       if (unformat (line_input, "disable"))
12505         enable_disable = 0;
12506       if (unformat (line_input, "enable"))
12507         enable_disable = 1;
12508       else if (unformat (line_input, "%U", unformat_sw_if_index,
12509                          vam, &sw_if_index))
12510         ;
12511       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12512         ;
12513       else
12514         break;
12515     }
12516
12517   if (sw_if_index == ~0)
12518     {
12519       errmsg ("missing interface name or sw_if_index\n");
12520       return -99;
12521     }
12522
12523   /* Construct the API message */
12524   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12525   mp->sw_if_index = ntohl (sw_if_index);
12526   mp->enable_disable = enable_disable;
12527
12528   /* send it... */
12529   S;
12530   /* Wait for the reply */
12531   W;
12532 }
12533
12534 static int
12535 api_cop_whitelist_enable_disable (vat_main_t * vam)
12536 {
12537   unformat_input_t *line_input = vam->input;
12538   vl_api_cop_whitelist_enable_disable_t *mp;
12539   f64 timeout;
12540   u32 sw_if_index = ~0;
12541   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12542   u32 fib_id = 0;
12543
12544   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12545     {
12546       if (unformat (line_input, "ip4"))
12547         ip4 = 1;
12548       else if (unformat (line_input, "ip6"))
12549         ip6 = 1;
12550       else if (unformat (line_input, "default"))
12551         default_cop = 1;
12552       else if (unformat (line_input, "%U", unformat_sw_if_index,
12553                          vam, &sw_if_index))
12554         ;
12555       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12556         ;
12557       else if (unformat (line_input, "fib-id %d", &fib_id))
12558         ;
12559       else
12560         break;
12561     }
12562
12563   if (sw_if_index == ~0)
12564     {
12565       errmsg ("missing interface name or sw_if_index\n");
12566       return -99;
12567     }
12568
12569   /* Construct the API message */
12570   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12571   mp->sw_if_index = ntohl (sw_if_index);
12572   mp->fib_id = ntohl (fib_id);
12573   mp->ip4 = ip4;
12574   mp->ip6 = ip6;
12575   mp->default_cop = default_cop;
12576
12577   /* send it... */
12578   S;
12579   /* Wait for the reply */
12580   W;
12581 }
12582
12583 static int
12584 api_get_node_graph (vat_main_t * vam)
12585 {
12586   vl_api_get_node_graph_t *mp;
12587   f64 timeout;
12588
12589   M (GET_NODE_GRAPH, get_node_graph);
12590
12591   /* send it... */
12592   S;
12593   /* Wait for the reply */
12594   W;
12595 }
12596
12597 /* *INDENT-OFF* */
12598 /** Used for parsing LISP eids */
12599 typedef CLIB_PACKED(struct{
12600   u8 addr[16];   /**< eid address */
12601   u32 len;       /**< prefix length if IP */
12602   u8 type;      /**< type of eid */
12603 }) lisp_eid_vat_t;
12604 /* *INDENT-ON* */
12605
12606 static uword
12607 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12608 {
12609   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12610
12611   memset (a, 0, sizeof (a[0]));
12612
12613   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12614     {
12615       a->type = 0;              /* ipv4 type */
12616     }
12617   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12618     {
12619       a->type = 1;              /* ipv6 type */
12620     }
12621   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12622     {
12623       a->type = 2;              /* mac type */
12624     }
12625   else
12626     {
12627       return 0;
12628     }
12629
12630   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12631     {
12632       return 0;
12633     }
12634
12635   return 1;
12636 }
12637
12638 static int
12639 lisp_eid_size_vat (u8 type)
12640 {
12641   switch (type)
12642     {
12643     case 0:
12644       return 4;
12645     case 1:
12646       return 16;
12647     case 2:
12648       return 6;
12649     }
12650   return 0;
12651 }
12652
12653 static void
12654 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12655 {
12656   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12657 }
12658
12659 /* *INDENT-OFF* */
12660 /** Used for transferring locators via VPP API */
12661 typedef CLIB_PACKED(struct
12662 {
12663   u32 sw_if_index; /**< locator sw_if_index */
12664   u8 priority; /**< locator priority */
12665   u8 weight;   /**< locator weight */
12666 }) ls_locator_t;
12667 /* *INDENT-ON* */
12668
12669 static int
12670 api_lisp_add_del_locator_set (vat_main_t * vam)
12671 {
12672   unformat_input_t *input = vam->input;
12673   vl_api_lisp_add_del_locator_set_t *mp;
12674   f64 timeout = ~0;
12675   u8 is_add = 1;
12676   u8 *locator_set_name = NULL;
12677   u8 locator_set_name_set = 0;
12678   ls_locator_t locator, *locators = 0;
12679   u32 sw_if_index, priority, weight;
12680   u32 data_len = 0;
12681
12682   /* Parse args required to build the message */
12683   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12684     {
12685       if (unformat (input, "del"))
12686         {
12687           is_add = 0;
12688         }
12689       else if (unformat (input, "locator-set %s", &locator_set_name))
12690         {
12691           locator_set_name_set = 1;
12692         }
12693       else if (unformat (input, "sw_if_index %u p %u w %u",
12694                          &sw_if_index, &priority, &weight))
12695         {
12696           locator.sw_if_index = htonl (sw_if_index);
12697           locator.priority = priority;
12698           locator.weight = weight;
12699           vec_add1 (locators, locator);
12700         }
12701       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12702                          vam, &sw_if_index, &priority, &weight))
12703         {
12704           locator.sw_if_index = htonl (sw_if_index);
12705           locator.priority = priority;
12706           locator.weight = weight;
12707           vec_add1 (locators, locator);
12708         }
12709       else
12710         break;
12711     }
12712
12713   if (locator_set_name_set == 0)
12714     {
12715       errmsg ("missing locator-set name");
12716       vec_free (locators);
12717       return -99;
12718     }
12719
12720   if (vec_len (locator_set_name) > 64)
12721     {
12722       errmsg ("locator-set name too long\n");
12723       vec_free (locator_set_name);
12724       vec_free (locators);
12725       return -99;
12726     }
12727   vec_add1 (locator_set_name, 0);
12728
12729   data_len = sizeof (ls_locator_t) * vec_len (locators);
12730
12731   /* Construct the API message */
12732   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12733
12734   mp->is_add = is_add;
12735   clib_memcpy (mp->locator_set_name, locator_set_name,
12736                vec_len (locator_set_name));
12737   vec_free (locator_set_name);
12738
12739   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12740   if (locators)
12741     clib_memcpy (mp->locators, locators, data_len);
12742   vec_free (locators);
12743
12744   /* send it... */
12745   S;
12746
12747   /* Wait for a reply... */
12748   W;
12749
12750   /* NOTREACHED */
12751   return 0;
12752 }
12753
12754 static int
12755 api_lisp_add_del_locator (vat_main_t * vam)
12756 {
12757   unformat_input_t *input = vam->input;
12758   vl_api_lisp_add_del_locator_t *mp;
12759   f64 timeout = ~0;
12760   u32 tmp_if_index = ~0;
12761   u32 sw_if_index = ~0;
12762   u8 sw_if_index_set = 0;
12763   u8 sw_if_index_if_name_set = 0;
12764   u32 priority = ~0;
12765   u8 priority_set = 0;
12766   u32 weight = ~0;
12767   u8 weight_set = 0;
12768   u8 is_add = 1;
12769   u8 *locator_set_name = NULL;
12770   u8 locator_set_name_set = 0;
12771
12772   /* Parse args required to build the message */
12773   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12774     {
12775       if (unformat (input, "del"))
12776         {
12777           is_add = 0;
12778         }
12779       else if (unformat (input, "locator-set %s", &locator_set_name))
12780         {
12781           locator_set_name_set = 1;
12782         }
12783       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12784                          &tmp_if_index))
12785         {
12786           sw_if_index_if_name_set = 1;
12787           sw_if_index = tmp_if_index;
12788         }
12789       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12790         {
12791           sw_if_index_set = 1;
12792           sw_if_index = tmp_if_index;
12793         }
12794       else if (unformat (input, "p %d", &priority))
12795         {
12796           priority_set = 1;
12797         }
12798       else if (unformat (input, "w %d", &weight))
12799         {
12800           weight_set = 1;
12801         }
12802       else
12803         break;
12804     }
12805
12806   if (locator_set_name_set == 0)
12807     {
12808       errmsg ("missing locator-set name");
12809       return -99;
12810     }
12811
12812   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12813     {
12814       errmsg ("missing sw_if_index");
12815       vec_free (locator_set_name);
12816       return -99;
12817     }
12818
12819   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12820     {
12821       errmsg ("cannot use both params interface name and sw_if_index");
12822       vec_free (locator_set_name);
12823       return -99;
12824     }
12825
12826   if (priority_set == 0)
12827     {
12828       errmsg ("missing locator-set priority\n");
12829       vec_free (locator_set_name);
12830       return -99;
12831     }
12832
12833   if (weight_set == 0)
12834     {
12835       errmsg ("missing locator-set weight\n");
12836       vec_free (locator_set_name);
12837       return -99;
12838     }
12839
12840   if (vec_len (locator_set_name) > 64)
12841     {
12842       errmsg ("locator-set name too long\n");
12843       vec_free (locator_set_name);
12844       return -99;
12845     }
12846   vec_add1 (locator_set_name, 0);
12847
12848   /* Construct the API message */
12849   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12850
12851   mp->is_add = is_add;
12852   mp->sw_if_index = ntohl (sw_if_index);
12853   mp->priority = priority;
12854   mp->weight = weight;
12855   clib_memcpy (mp->locator_set_name, locator_set_name,
12856                vec_len (locator_set_name));
12857   vec_free (locator_set_name);
12858
12859   /* send it... */
12860   S;
12861
12862   /* Wait for a reply... */
12863   W;
12864
12865   /* NOTREACHED */
12866   return 0;
12867 }
12868
12869 static int
12870 api_lisp_add_del_local_eid (vat_main_t * vam)
12871 {
12872   unformat_input_t *input = vam->input;
12873   vl_api_lisp_add_del_local_eid_t *mp;
12874   f64 timeout = ~0;
12875   u8 is_add = 1;
12876   u8 eid_set = 0;
12877   lisp_eid_vat_t _eid, *eid = &_eid;
12878   u8 *locator_set_name = 0;
12879   u8 locator_set_name_set = 0;
12880   u32 vni = 0;
12881
12882   /* Parse args required to build the message */
12883   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12884     {
12885       if (unformat (input, "del"))
12886         {
12887           is_add = 0;
12888         }
12889       else if (unformat (input, "vni %d", &vni))
12890         {
12891           ;
12892         }
12893       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12894         {
12895           eid_set = 1;
12896         }
12897       else if (unformat (input, "locator-set %s", &locator_set_name))
12898         {
12899           locator_set_name_set = 1;
12900         }
12901       else
12902         break;
12903     }
12904
12905   if (locator_set_name_set == 0)
12906     {
12907       errmsg ("missing locator-set name\n");
12908       return -99;
12909     }
12910
12911   if (0 == eid_set)
12912     {
12913       errmsg ("EID address not set!");
12914       vec_free (locator_set_name);
12915       return -99;
12916     }
12917
12918   if (vec_len (locator_set_name) > 64)
12919     {
12920       errmsg ("locator-set name too long\n");
12921       vec_free (locator_set_name);
12922       return -99;
12923     }
12924   vec_add1 (locator_set_name, 0);
12925
12926   /* Construct the API message */
12927   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12928
12929   mp->is_add = is_add;
12930   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12931   mp->eid_type = eid->type;
12932   mp->prefix_len = eid->len;
12933   mp->vni = clib_host_to_net_u32 (vni);
12934   clib_memcpy (mp->locator_set_name, locator_set_name,
12935                vec_len (locator_set_name));
12936
12937   vec_free (locator_set_name);
12938
12939   /* send it... */
12940   S;
12941
12942   /* Wait for a reply... */
12943   W;
12944
12945   /* NOTREACHED */
12946   return 0;
12947 }
12948
12949 /* *INDENT-OFF* */
12950 /** Used for transferring locators via VPP API */
12951 typedef CLIB_PACKED(struct
12952 {
12953   u8 is_ip4; /**< is locator an IPv4 address? */
12954   u8 priority; /**< locator priority */
12955   u8 weight;   /**< locator weight */
12956   u8 addr[16]; /**< IPv4/IPv6 address */
12957 }) rloc_t;
12958 /* *INDENT-ON* */
12959
12960 static int
12961 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12962 {
12963   unformat_input_t *input = vam->input;
12964   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12965   f64 timeout = ~0;
12966   u8 is_add = 1;
12967   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12968   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12969   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12970   u32 action = ~0, p, w;
12971   ip4_address_t rmt_rloc4, lcl_rloc4;
12972   ip6_address_t rmt_rloc6, lcl_rloc6;
12973   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12974
12975   memset (&rloc, 0, sizeof (rloc));
12976
12977   /* Parse args required to build the message */
12978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12979     {
12980       if (unformat (input, "del"))
12981         {
12982           is_add = 0;
12983         }
12984       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12985         {
12986           rmt_eid_set = 1;
12987         }
12988       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12989         {
12990           lcl_eid_set = 1;
12991         }
12992       else if (unformat (input, "p %d w %d", &p, &w))
12993         {
12994           if (!curr_rloc)
12995             {
12996               errmsg ("No RLOC configured for setting priority/weight!");
12997               return -99;
12998             }
12999           curr_rloc->priority = p;
13000           curr_rloc->weight = w;
13001         }
13002       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13003                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13004         {
13005           rloc.is_ip4 = 1;
13006
13007           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13008           rloc.priority = rloc.weight = 0;
13009           vec_add1 (lcl_locs, rloc);
13010
13011           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13012           vec_add1 (rmt_locs, rloc);
13013           /* priority and weight saved in rmt loc */
13014           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13015         }
13016       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13017                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13018         {
13019           rloc.is_ip4 = 0;
13020           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13021           rloc.priority = rloc.weight = 0;
13022           vec_add1 (lcl_locs, rloc);
13023
13024           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13025           vec_add1 (rmt_locs, rloc);
13026           /* priority and weight saved in rmt loc */
13027           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13028         }
13029       else if (unformat (input, "action %d", &action))
13030         {
13031           ;
13032         }
13033       else
13034         {
13035           clib_warning ("parse error '%U'", format_unformat_error, input);
13036           return -99;
13037         }
13038     }
13039
13040   if (!rmt_eid_set)
13041     {
13042       errmsg ("remote eid addresses not set\n");
13043       return -99;
13044     }
13045
13046   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13047     {
13048       errmsg ("eid types don't match\n");
13049       return -99;
13050     }
13051
13052   if (0 == rmt_locs && (u32) ~ 0 == action)
13053     {
13054       errmsg ("action not set for negative mapping\n");
13055       return -99;
13056     }
13057
13058   /* Construct the API message */
13059   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13060
13061   mp->is_add = is_add;
13062   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13063   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13064   mp->eid_type = rmt_eid->type;
13065   mp->rmt_len = rmt_eid->len;
13066   mp->lcl_len = lcl_eid->len;
13067   mp->action = action;
13068
13069   if (0 != rmt_locs && 0 != lcl_locs)
13070     {
13071       mp->loc_num = vec_len (rmt_locs);
13072       clib_memcpy (mp->lcl_locs, lcl_locs,
13073                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13074       clib_memcpy (mp->rmt_locs, rmt_locs,
13075                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13076     }
13077   vec_free (lcl_locs);
13078   vec_free (rmt_locs);
13079
13080   /* send it... */
13081   S;
13082
13083   /* Wait for a reply... */
13084   W;
13085
13086   /* NOTREACHED */
13087   return 0;
13088 }
13089
13090 static int
13091 api_lisp_add_del_map_resolver (vat_main_t * vam)
13092 {
13093   unformat_input_t *input = vam->input;
13094   vl_api_lisp_add_del_map_resolver_t *mp;
13095   f64 timeout = ~0;
13096   u8 is_add = 1;
13097   u8 ipv4_set = 0;
13098   u8 ipv6_set = 0;
13099   ip4_address_t ipv4;
13100   ip6_address_t ipv6;
13101
13102   /* Parse args required to build the message */
13103   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13104     {
13105       if (unformat (input, "del"))
13106         {
13107           is_add = 0;
13108         }
13109       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13110         {
13111           ipv4_set = 1;
13112         }
13113       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13114         {
13115           ipv6_set = 1;
13116         }
13117       else
13118         break;
13119     }
13120
13121   if (ipv4_set && ipv6_set)
13122     {
13123       errmsg ("both eid v4 and v6 addresses set\n");
13124       return -99;
13125     }
13126
13127   if (!ipv4_set && !ipv6_set)
13128     {
13129       errmsg ("eid addresses not set\n");
13130       return -99;
13131     }
13132
13133   /* Construct the API message */
13134   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13135
13136   mp->is_add = is_add;
13137   if (ipv6_set)
13138     {
13139       mp->is_ipv6 = 1;
13140       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13141     }
13142   else
13143     {
13144       mp->is_ipv6 = 0;
13145       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13146     }
13147
13148   /* send it... */
13149   S;
13150
13151   /* Wait for a reply... */
13152   W;
13153
13154   /* NOTREACHED */
13155   return 0;
13156 }
13157
13158 static int
13159 api_lisp_gpe_enable_disable (vat_main_t * vam)
13160 {
13161   unformat_input_t *input = vam->input;
13162   vl_api_lisp_gpe_enable_disable_t *mp;
13163   f64 timeout = ~0;
13164   u8 is_set = 0;
13165   u8 is_en = 1;
13166
13167   /* Parse args required to build the message */
13168   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13169     {
13170       if (unformat (input, "enable"))
13171         {
13172           is_set = 1;
13173           is_en = 1;
13174         }
13175       else if (unformat (input, "disable"))
13176         {
13177           is_set = 1;
13178           is_en = 0;
13179         }
13180       else
13181         break;
13182     }
13183
13184   if (is_set == 0)
13185     {
13186       errmsg ("Value not set\n");
13187       return -99;
13188     }
13189
13190   /* Construct the API message */
13191   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13192
13193   mp->is_en = is_en;
13194
13195   /* send it... */
13196   S;
13197
13198   /* Wait for a reply... */
13199   W;
13200
13201   /* NOTREACHED */
13202   return 0;
13203 }
13204
13205 static int
13206 api_lisp_enable_disable (vat_main_t * vam)
13207 {
13208   unformat_input_t *input = vam->input;
13209   vl_api_lisp_enable_disable_t *mp;
13210   f64 timeout = ~0;
13211   u8 is_set = 0;
13212   u8 is_en = 0;
13213
13214   /* Parse args required to build the message */
13215   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13216     {
13217       if (unformat (input, "enable"))
13218         {
13219           is_set = 1;
13220           is_en = 1;
13221         }
13222       else if (unformat (input, "disable"))
13223         {
13224           is_set = 1;
13225         }
13226       else
13227         break;
13228     }
13229
13230   if (!is_set)
13231     {
13232       errmsg ("Value not set\n");
13233       return -99;
13234     }
13235
13236   /* Construct the API message */
13237   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13238
13239   mp->is_en = is_en;
13240
13241   /* send it... */
13242   S;
13243
13244   /* Wait for a reply... */
13245   W;
13246
13247   /* NOTREACHED */
13248   return 0;
13249 }
13250
13251 static int
13252 api_show_lisp_map_request_mode (vat_main_t * vam)
13253 {
13254   f64 timeout = ~0;
13255   vl_api_show_lisp_map_request_mode_t *mp;
13256
13257   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13258
13259   /* send */
13260   S;
13261
13262   /* wait for reply */
13263   W;
13264
13265   return 0;
13266 }
13267
13268 static int
13269 api_lisp_map_request_mode (vat_main_t * vam)
13270 {
13271   f64 timeout = ~0;
13272   unformat_input_t *input = vam->input;
13273   vl_api_lisp_map_request_mode_t *mp;
13274   u8 mode = 0;
13275
13276   /* Parse args required to build the message */
13277   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13278     {
13279       if (unformat (input, "dst-only"))
13280         mode = 0;
13281       else if (unformat (input, "src-dst"))
13282         mode = 1;
13283       else
13284         {
13285           errmsg ("parse error '%U'", format_unformat_error, input);
13286           return -99;
13287         }
13288     }
13289
13290   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13291
13292   mp->mode = mode;
13293
13294   /* send */
13295   S;
13296
13297   /* wait for reply */
13298   W;
13299
13300   /* notreached */
13301   return 0;
13302 }
13303
13304 /**
13305  * Enable/disable LISP proxy ITR.
13306  *
13307  * @param vam vpp API test context
13308  * @return return code
13309  */
13310 static int
13311 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13312 {
13313   f64 timeout = ~0;
13314   u8 ls_name_set = 0;
13315   unformat_input_t *input = vam->input;
13316   vl_api_lisp_pitr_set_locator_set_t *mp;
13317   u8 is_add = 1;
13318   u8 *ls_name = 0;
13319
13320   /* Parse args required to build the message */
13321   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13322     {
13323       if (unformat (input, "del"))
13324         is_add = 0;
13325       else if (unformat (input, "locator-set %s", &ls_name))
13326         ls_name_set = 1;
13327       else
13328         {
13329           errmsg ("parse error '%U'", format_unformat_error, input);
13330           return -99;
13331         }
13332     }
13333
13334   if (!ls_name_set)
13335     {
13336       errmsg ("locator-set name not set!");
13337       return -99;
13338     }
13339
13340   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13341
13342   mp->is_add = is_add;
13343   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13344   vec_free (ls_name);
13345
13346   /* send */
13347   S;
13348
13349   /* wait for reply */
13350   W;
13351
13352   /* notreached */
13353   return 0;
13354 }
13355
13356 static int
13357 api_show_lisp_pitr (vat_main_t * vam)
13358 {
13359   vl_api_show_lisp_pitr_t *mp;
13360   f64 timeout = ~0;
13361
13362   if (!vam->json_output)
13363     {
13364       fformat (vam->ofp, "%=20s\n", "lisp status:");
13365     }
13366
13367   M (SHOW_LISP_PITR, show_lisp_pitr);
13368   /* send it... */
13369   S;
13370
13371   /* Wait for a reply... */
13372   W;
13373
13374   /* NOTREACHED */
13375   return 0;
13376 }
13377
13378 /**
13379  * Add/delete mapping between vni and vrf
13380  */
13381 static int
13382 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13383 {
13384   f64 timeout = ~0;
13385   unformat_input_t *input = vam->input;
13386   vl_api_lisp_eid_table_add_del_map_t *mp;
13387   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13388   u32 vni, vrf, bd_index;
13389
13390   /* Parse args required to build the message */
13391   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13392     {
13393       if (unformat (input, "del"))
13394         is_add = 0;
13395       else if (unformat (input, "vrf %d", &vrf))
13396         vrf_set = 1;
13397       else if (unformat (input, "bd_index %d", &bd_index))
13398         bd_index_set = 1;
13399       else if (unformat (input, "vni %d", &vni))
13400         vni_set = 1;
13401       else
13402         break;
13403     }
13404
13405   if (!vni_set || (!vrf_set && !bd_index_set))
13406     {
13407       errmsg ("missing arguments!");
13408       return -99;
13409     }
13410
13411   if (vrf_set && bd_index_set)
13412     {
13413       errmsg ("error: both vrf and bd entered!");
13414       return -99;
13415     }
13416
13417   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13418
13419   mp->is_add = is_add;
13420   mp->vni = htonl (vni);
13421   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13422   mp->is_l2 = bd_index_set;
13423
13424   /* send */
13425   S;
13426
13427   /* wait for reply */
13428   W;
13429
13430   /* notreached */
13431   return 0;
13432 }
13433
13434 uword
13435 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13436 {
13437   u32 *action = va_arg (*args, u32 *);
13438   u8 *s = 0;
13439
13440   if (unformat (input, "%s", &s))
13441     {
13442       if (!strcmp ((char *) s, "no-action"))
13443         action[0] = 0;
13444       else if (!strcmp ((char *) s, "natively-forward"))
13445         action[0] = 1;
13446       else if (!strcmp ((char *) s, "send-map-request"))
13447         action[0] = 2;
13448       else if (!strcmp ((char *) s, "drop"))
13449         action[0] = 3;
13450       else
13451         {
13452           clib_warning ("invalid action: '%s'", s);
13453           action[0] = 3;
13454         }
13455     }
13456   else
13457     return 0;
13458
13459   vec_free (s);
13460   return 1;
13461 }
13462
13463 /**
13464  * Add/del remote mapping to/from LISP control plane
13465  *
13466  * @param vam vpp API test context
13467  * @return return code
13468  */
13469 static int
13470 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13471 {
13472   unformat_input_t *input = vam->input;
13473   vl_api_lisp_add_del_remote_mapping_t *mp;
13474   f64 timeout = ~0;
13475   u32 vni = 0;
13476   lisp_eid_vat_t _eid, *eid = &_eid;
13477   lisp_eid_vat_t _seid, *seid = &_seid;
13478   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13479   u32 action = ~0, p, w, data_len;
13480   ip4_address_t rloc4;
13481   ip6_address_t rloc6;
13482   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13483
13484   memset (&rloc, 0, sizeof (rloc));
13485
13486   /* Parse args required to build the message */
13487   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13488     {
13489       if (unformat (input, "del-all"))
13490         {
13491           del_all = 1;
13492         }
13493       else if (unformat (input, "del"))
13494         {
13495           is_add = 0;
13496         }
13497       else if (unformat (input, "add"))
13498         {
13499           is_add = 1;
13500         }
13501       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13502         {
13503           eid_set = 1;
13504         }
13505       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13506         {
13507           seid_set = 1;
13508         }
13509       else if (unformat (input, "vni %d", &vni))
13510         {
13511           ;
13512         }
13513       else if (unformat (input, "p %d w %d", &p, &w))
13514         {
13515           if (!curr_rloc)
13516             {
13517               errmsg ("No RLOC configured for setting priority/weight!");
13518               return -99;
13519             }
13520           curr_rloc->priority = p;
13521           curr_rloc->weight = w;
13522         }
13523       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13524         {
13525           rloc.is_ip4 = 1;
13526           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13527           vec_add1 (rlocs, rloc);
13528           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13529         }
13530       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13531         {
13532           rloc.is_ip4 = 0;
13533           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13534           vec_add1 (rlocs, rloc);
13535           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13536         }
13537       else if (unformat (input, "action %U",
13538                          unformat_negative_mapping_action, &action))
13539         {
13540           ;
13541         }
13542       else
13543         {
13544           clib_warning ("parse error '%U'", format_unformat_error, input);
13545           return -99;
13546         }
13547     }
13548
13549   if (0 == eid_set)
13550     {
13551       errmsg ("missing params!");
13552       return -99;
13553     }
13554
13555   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13556     {
13557       errmsg ("no action set for negative map-reply!");
13558       return -99;
13559     }
13560
13561   data_len = vec_len (rlocs) * sizeof (rloc_t);
13562
13563   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13564   mp->is_add = is_add;
13565   mp->vni = htonl (vni);
13566   mp->action = (u8) action;
13567   mp->is_src_dst = seid_set;
13568   mp->eid_len = eid->len;
13569   mp->seid_len = seid->len;
13570   mp->del_all = del_all;
13571   mp->eid_type = eid->type;
13572   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13573   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13574
13575   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13576   clib_memcpy (mp->rlocs, rlocs, data_len);
13577   vec_free (rlocs);
13578
13579   /* send it... */
13580   S;
13581
13582   /* Wait for a reply... */
13583   W;
13584
13585   /* NOTREACHED */
13586   return 0;
13587 }
13588
13589 /**
13590  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13591  * forwarding entries in data-plane accordingly.
13592  *
13593  * @param vam vpp API test context
13594  * @return return code
13595  */
13596 static int
13597 api_lisp_add_del_adjacency (vat_main_t * vam)
13598 {
13599   unformat_input_t *input = vam->input;
13600   vl_api_lisp_add_del_adjacency_t *mp;
13601   f64 timeout = ~0;
13602   u32 vni = 0;
13603   ip4_address_t leid4, reid4;
13604   ip6_address_t leid6, reid6;
13605   u8 reid_mac[6] = { 0 };
13606   u8 leid_mac[6] = { 0 };
13607   u8 reid_type, leid_type;
13608   u32 leid_len = 0, reid_len = 0, len;
13609   u8 is_add = 1;
13610
13611   leid_type = reid_type = (u8) ~ 0;
13612
13613   /* Parse args required to build the message */
13614   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13615     {
13616       if (unformat (input, "del"))
13617         {
13618           is_add = 0;
13619         }
13620       else if (unformat (input, "add"))
13621         {
13622           is_add = 1;
13623         }
13624       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13625                          &reid4, &len))
13626         {
13627           reid_type = 0;        /* ipv4 */
13628           reid_len = len;
13629         }
13630       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13631                          &reid6, &len))
13632         {
13633           reid_type = 1;        /* ipv6 */
13634           reid_len = len;
13635         }
13636       else if (unformat (input, "reid %U", unformat_ethernet_address,
13637                          reid_mac))
13638         {
13639           reid_type = 2;        /* mac */
13640         }
13641       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13642                          &leid4, &len))
13643         {
13644           leid_type = 0;        /* ipv4 */
13645           leid_len = len;
13646         }
13647       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13648                          &leid6, &len))
13649         {
13650           leid_type = 1;        /* ipv6 */
13651           leid_len = len;
13652         }
13653       else if (unformat (input, "leid %U", unformat_ethernet_address,
13654                          leid_mac))
13655         {
13656           leid_type = 2;        /* mac */
13657         }
13658       else if (unformat (input, "vni %d", &vni))
13659         {
13660           ;
13661         }
13662       else
13663         {
13664           errmsg ("parse error '%U'", format_unformat_error, input);
13665           return -99;
13666         }
13667     }
13668
13669   if ((u8) ~ 0 == reid_type)
13670     {
13671       errmsg ("missing params!");
13672       return -99;
13673     }
13674
13675   if (leid_type != reid_type)
13676     {
13677       errmsg ("remote and local EIDs are of different types!");
13678       return -99;
13679     }
13680
13681   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13682   mp->is_add = is_add;
13683   mp->vni = htonl (vni);
13684   mp->leid_len = leid_len;
13685   mp->reid_len = reid_len;
13686   mp->eid_type = reid_type;
13687
13688   switch (mp->eid_type)
13689     {
13690     case 0:
13691       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13692       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13693       break;
13694     case 1:
13695       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13696       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13697       break;
13698     case 2:
13699       clib_memcpy (mp->leid, leid_mac, 6);
13700       clib_memcpy (mp->reid, reid_mac, 6);
13701       break;
13702     default:
13703       errmsg ("unknown EID type %d!", mp->eid_type);
13704       return 0;
13705     }
13706
13707   /* send it... */
13708   S;
13709
13710   /* Wait for a reply... */
13711   W;
13712
13713   /* NOTREACHED */
13714   return 0;
13715 }
13716
13717 static int
13718 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13719 {
13720   unformat_input_t *input = vam->input;
13721   vl_api_lisp_gpe_add_del_iface_t *mp;
13722   f64 timeout = ~0;
13723   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13724   u32 dp_table = 0, vni = 0;
13725
13726   /* Parse args required to build the message */
13727   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13728     {
13729       if (unformat (input, "up"))
13730         {
13731           action_set = 1;
13732           is_add = 1;
13733         }
13734       else if (unformat (input, "down"))
13735         {
13736           action_set = 1;
13737           is_add = 0;
13738         }
13739       else if (unformat (input, "table_id %d", &dp_table))
13740         {
13741           dp_table_set = 1;
13742         }
13743       else if (unformat (input, "bd_id %d", &dp_table))
13744         {
13745           dp_table_set = 1;
13746           is_l2 = 1;
13747         }
13748       else if (unformat (input, "vni %d", &vni))
13749         {
13750           vni_set = 1;
13751         }
13752       else
13753         break;
13754     }
13755
13756   if (action_set == 0)
13757     {
13758       errmsg ("Action not set\n");
13759       return -99;
13760     }
13761   if (dp_table_set == 0 || vni_set == 0)
13762     {
13763       errmsg ("vni and dp_table must be set\n");
13764       return -99;
13765     }
13766
13767   /* Construct the API message */
13768   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13769
13770   mp->is_add = is_add;
13771   mp->dp_table = dp_table;
13772   mp->is_l2 = is_l2;
13773   mp->vni = vni;
13774
13775   /* send it... */
13776   S;
13777
13778   /* Wait for a reply... */
13779   W;
13780
13781   /* NOTREACHED */
13782   return 0;
13783 }
13784
13785 /**
13786  * Add/del map request itr rlocs from LISP control plane and updates
13787  *
13788  * @param vam vpp API test context
13789  * @return return code
13790  */
13791 static int
13792 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13793 {
13794   unformat_input_t *input = vam->input;
13795   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13796   f64 timeout = ~0;
13797   u8 *locator_set_name = 0;
13798   u8 locator_set_name_set = 0;
13799   u8 is_add = 1;
13800
13801   /* Parse args required to build the message */
13802   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13803     {
13804       if (unformat (input, "del"))
13805         {
13806           is_add = 0;
13807         }
13808       else if (unformat (input, "%_%v%_", &locator_set_name))
13809         {
13810           locator_set_name_set = 1;
13811         }
13812       else
13813         {
13814           clib_warning ("parse error '%U'", format_unformat_error, input);
13815           return -99;
13816         }
13817     }
13818
13819   if (is_add && !locator_set_name_set)
13820     {
13821       errmsg ("itr-rloc is not set!");
13822       return -99;
13823     }
13824
13825   if (is_add && vec_len (locator_set_name) > 64)
13826     {
13827       errmsg ("itr-rloc locator-set name too long\n");
13828       vec_free (locator_set_name);
13829       return -99;
13830     }
13831
13832   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13833   mp->is_add = is_add;
13834   if (is_add)
13835     {
13836       clib_memcpy (mp->locator_set_name, locator_set_name,
13837                    vec_len (locator_set_name));
13838     }
13839   else
13840     {
13841       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13842     }
13843   vec_free (locator_set_name);
13844
13845   /* send it... */
13846   S;
13847
13848   /* Wait for a reply... */
13849   W;
13850
13851   /* NOTREACHED */
13852   return 0;
13853 }
13854
13855 static int
13856 api_lisp_locator_dump (vat_main_t * vam)
13857 {
13858   unformat_input_t *input = vam->input;
13859   vl_api_lisp_locator_dump_t *mp;
13860   f64 timeout = ~0;
13861   u8 is_index_set = 0, is_name_set = 0;
13862   u8 *ls_name = 0;
13863   u32 ls_index = ~0;
13864
13865   /* Parse args required to build the message */
13866   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13867     {
13868       if (unformat (input, "ls_name %_%v%_", &ls_name))
13869         {
13870           is_name_set = 1;
13871         }
13872       else if (unformat (input, "ls_index %d", &ls_index))
13873         {
13874           is_index_set = 1;
13875         }
13876       else
13877         {
13878           errmsg ("parse error '%U'", format_unformat_error, input);
13879           return -99;
13880         }
13881     }
13882
13883   if (!is_index_set && !is_name_set)
13884     {
13885       errmsg ("error: expected one of index or name!\n");
13886       return -99;
13887     }
13888
13889   if (is_index_set && is_name_set)
13890     {
13891       errmsg ("error: only one param expected!\n");
13892       return -99;
13893     }
13894
13895   if (vec_len (ls_name) > 62)
13896     {
13897       errmsg ("error: locator set name too long!");
13898       return -99;
13899     }
13900
13901   if (!vam->json_output)
13902     {
13903       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13904                "weight");
13905     }
13906
13907   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13908   mp->is_index_set = is_index_set;
13909
13910   if (is_index_set)
13911     mp->ls_index = clib_host_to_net_u32 (ls_index);
13912   else
13913     {
13914       vec_add1 (ls_name, 0);
13915       strncpy ((char *) mp->ls_name, (char *) ls_name,
13916                sizeof (mp->ls_name) - 1);
13917     }
13918
13919   /* send it... */
13920   S;
13921
13922   /* Use a control ping for synchronization */
13923   {
13924     vl_api_control_ping_t *mp;
13925     M (CONTROL_PING, control_ping);
13926     S;
13927   }
13928   /* Wait for a reply... */
13929   W;
13930
13931   /* NOTREACHED */
13932   return 0;
13933 }
13934
13935 static int
13936 api_lisp_locator_set_dump (vat_main_t * vam)
13937 {
13938   vl_api_lisp_locator_set_dump_t *mp;
13939   unformat_input_t *input = vam->input;
13940   f64 timeout = ~0;
13941   u8 filter = 0;
13942
13943   /* Parse args required to build the message */
13944   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13945     {
13946       if (unformat (input, "local"))
13947         {
13948           filter = 1;
13949         }
13950       else if (unformat (input, "remote"))
13951         {
13952           filter = 2;
13953         }
13954       else
13955         {
13956           errmsg ("parse error '%U'", format_unformat_error, input);
13957           return -99;
13958         }
13959     }
13960
13961   if (!vam->json_output)
13962     {
13963       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13964     }
13965
13966   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13967
13968   mp->filter = filter;
13969
13970   /* send it... */
13971   S;
13972
13973   /* Use a control ping for synchronization */
13974   {
13975     vl_api_control_ping_t *mp;
13976     M (CONTROL_PING, control_ping);
13977     S;
13978   }
13979   /* Wait for a reply... */
13980   W;
13981
13982   /* NOTREACHED */
13983   return 0;
13984 }
13985
13986 static int
13987 api_lisp_eid_table_map_dump (vat_main_t * vam)
13988 {
13989   u8 is_l2 = 0;
13990   u8 mode_set = 0;
13991   unformat_input_t *input = vam->input;
13992   vl_api_lisp_eid_table_map_dump_t *mp;
13993   f64 timeout = ~0;
13994
13995   /* Parse args required to build the message */
13996   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13997     {
13998       if (unformat (input, "l2"))
13999         {
14000           is_l2 = 1;
14001           mode_set = 1;
14002         }
14003       else if (unformat (input, "l3"))
14004         {
14005           is_l2 = 0;
14006           mode_set = 1;
14007         }
14008       else
14009         {
14010           errmsg ("parse error '%U'", format_unformat_error, input);
14011           return -99;
14012         }
14013     }
14014
14015   if (!mode_set)
14016     {
14017       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
14018       return -99;
14019     }
14020
14021   if (!vam->json_output)
14022     {
14023       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
14024     }
14025
14026   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14027   mp->is_l2 = is_l2;
14028
14029   /* send it... */
14030   S;
14031
14032   /* Use a control ping for synchronization */
14033   {
14034     vl_api_control_ping_t *mp;
14035     M (CONTROL_PING, control_ping);
14036     S;
14037   }
14038   /* Wait for a reply... */
14039   W;
14040
14041   /* NOTREACHED */
14042   return 0;
14043 }
14044
14045 static int
14046 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14047 {
14048   vl_api_lisp_eid_table_vni_dump_t *mp;
14049   f64 timeout = ~0;
14050
14051   if (!vam->json_output)
14052     {
14053       fformat (vam->ofp, "VNI\n");
14054     }
14055
14056   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14057
14058   /* send it... */
14059   S;
14060
14061   /* Use a control ping for synchronization */
14062   {
14063     vl_api_control_ping_t *mp;
14064     M (CONTROL_PING, control_ping);
14065     S;
14066   }
14067   /* Wait for a reply... */
14068   W;
14069
14070   /* NOTREACHED */
14071   return 0;
14072 }
14073
14074 static int
14075 api_lisp_eid_table_dump (vat_main_t * vam)
14076 {
14077   unformat_input_t *i = vam->input;
14078   vl_api_lisp_eid_table_dump_t *mp;
14079   f64 timeout = ~0;
14080   struct in_addr ip4;
14081   struct in6_addr ip6;
14082   u8 mac[6];
14083   u8 eid_type = ~0, eid_set = 0;
14084   u32 prefix_length = ~0, t, vni = 0;
14085   u8 filter = 0;
14086
14087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14088     {
14089       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14090         {
14091           eid_set = 1;
14092           eid_type = 0;
14093           prefix_length = t;
14094         }
14095       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14096         {
14097           eid_set = 1;
14098           eid_type = 1;
14099           prefix_length = t;
14100         }
14101       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14102         {
14103           eid_set = 1;
14104           eid_type = 2;
14105         }
14106       else if (unformat (i, "vni %d", &t))
14107         {
14108           vni = t;
14109         }
14110       else if (unformat (i, "local"))
14111         {
14112           filter = 1;
14113         }
14114       else if (unformat (i, "remote"))
14115         {
14116           filter = 2;
14117         }
14118       else
14119         {
14120           errmsg ("parse error '%U'", format_unformat_error, i);
14121           return -99;
14122         }
14123     }
14124
14125   if (!vam->json_output)
14126     {
14127       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
14128                "ls_index", "ttl", "authoritative");
14129     }
14130
14131   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14132
14133   mp->filter = filter;
14134   if (eid_set)
14135     {
14136       mp->eid_set = 1;
14137       mp->vni = htonl (vni);
14138       mp->eid_type = eid_type;
14139       switch (eid_type)
14140         {
14141         case 0:
14142           mp->prefix_length = prefix_length;
14143           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14144           break;
14145         case 1:
14146           mp->prefix_length = prefix_length;
14147           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14148           break;
14149         case 2:
14150           clib_memcpy (mp->eid, mac, sizeof (mac));
14151           break;
14152         default:
14153           errmsg ("unknown EID type %d!", eid_type);
14154           return -99;
14155         }
14156     }
14157
14158   /* send it... */
14159   S;
14160
14161   /* Use a control ping for synchronization */
14162   {
14163     vl_api_control_ping_t *mp;
14164     M (CONTROL_PING, control_ping);
14165     S;
14166   }
14167
14168   /* Wait for a reply... */
14169   W;
14170
14171   /* NOTREACHED */
14172   return 0;
14173 }
14174
14175 static int
14176 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14177 {
14178   vl_api_lisp_gpe_tunnel_dump_t *mp;
14179   f64 timeout = ~0;
14180
14181   if (!vam->json_output)
14182     {
14183       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14184                "%=16s%=16s%=16s%=16s%=16s\n",
14185                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14186                "Decap next", "Lisp version", "Flags", "Next protocol",
14187                "ver_res", "res", "iid");
14188     }
14189
14190   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14191   /* send it... */
14192   S;
14193
14194   /* Use a control ping for synchronization */
14195   {
14196     vl_api_control_ping_t *mp;
14197     M (CONTROL_PING, control_ping);
14198     S;
14199   }
14200   /* Wait for a reply... */
14201   W;
14202
14203   /* NOTREACHED */
14204   return 0;
14205 }
14206
14207 static int
14208 api_lisp_adjacencies_get (vat_main_t * vam)
14209 {
14210   unformat_input_t *i = vam->input;
14211   vl_api_lisp_adjacencies_get_t *mp;
14212   f64 timeout = ~0;
14213   u8 vni_set = 0;
14214   u32 vni = ~0;
14215
14216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14217     {
14218       if (unformat (i, "vni %d", &vni))
14219         {
14220           vni_set = 1;
14221         }
14222       else
14223         {
14224           errmsg ("parse error '%U'\n", format_unformat_error, i);
14225           return -99;
14226         }
14227     }
14228
14229   if (!vni_set)
14230     {
14231       errmsg ("vni not set!\n");
14232       return -99;
14233     }
14234
14235   if (!vam->json_output)
14236     {
14237       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14238     }
14239
14240   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14241   mp->vni = clib_host_to_net_u32 (vni);
14242
14243   /* send it... */
14244   S;
14245
14246   /* Wait for a reply... */
14247   W;
14248
14249   /* NOTREACHED */
14250   return 0;
14251 }
14252
14253 static int
14254 api_lisp_map_resolver_dump (vat_main_t * vam)
14255 {
14256   vl_api_lisp_map_resolver_dump_t *mp;
14257   f64 timeout = ~0;
14258
14259   if (!vam->json_output)
14260     {
14261       fformat (vam->ofp, "%=20s\n", "Map resolver");
14262     }
14263
14264   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14265   /* send it... */
14266   S;
14267
14268   /* Use a control ping for synchronization */
14269   {
14270     vl_api_control_ping_t *mp;
14271     M (CONTROL_PING, control_ping);
14272     S;
14273   }
14274   /* Wait for a reply... */
14275   W;
14276
14277   /* NOTREACHED */
14278   return 0;
14279 }
14280
14281 static int
14282 api_show_lisp_status (vat_main_t * vam)
14283 {
14284   vl_api_show_lisp_status_t *mp;
14285   f64 timeout = ~0;
14286
14287   if (!vam->json_output)
14288     {
14289       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14290     }
14291
14292   M (SHOW_LISP_STATUS, show_lisp_status);
14293   /* send it... */
14294   S;
14295   /* Wait for a reply... */
14296   W;
14297
14298   /* NOTREACHED */
14299   return 0;
14300 }
14301
14302 static int
14303 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14304 {
14305   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14306   f64 timeout = ~0;
14307
14308   if (!vam->json_output)
14309     {
14310       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14311     }
14312
14313   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14314   /* send it... */
14315   S;
14316   /* Wait for a reply... */
14317   W;
14318
14319   /* NOTREACHED */
14320   return 0;
14321 }
14322
14323 static int
14324 api_af_packet_create (vat_main_t * vam)
14325 {
14326   unformat_input_t *i = vam->input;
14327   vl_api_af_packet_create_t *mp;
14328   f64 timeout;
14329   u8 *host_if_name = 0;
14330   u8 hw_addr[6];
14331   u8 random_hw_addr = 1;
14332
14333   memset (hw_addr, 0, sizeof (hw_addr));
14334
14335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14336     {
14337       if (unformat (i, "name %s", &host_if_name))
14338         vec_add1 (host_if_name, 0);
14339       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14340         random_hw_addr = 0;
14341       else
14342         break;
14343     }
14344
14345   if (!vec_len (host_if_name))
14346     {
14347       errmsg ("host-interface name must be specified");
14348       return -99;
14349     }
14350
14351   if (vec_len (host_if_name) > 64)
14352     {
14353       errmsg ("host-interface name too long");
14354       return -99;
14355     }
14356
14357   M (AF_PACKET_CREATE, af_packet_create);
14358
14359   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14360   clib_memcpy (mp->hw_addr, hw_addr, 6);
14361   mp->use_random_hw_addr = random_hw_addr;
14362   vec_free (host_if_name);
14363
14364   S;
14365   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14366   /* NOTREACHED */
14367   return 0;
14368 }
14369
14370 static int
14371 api_af_packet_delete (vat_main_t * vam)
14372 {
14373   unformat_input_t *i = vam->input;
14374   vl_api_af_packet_delete_t *mp;
14375   f64 timeout;
14376   u8 *host_if_name = 0;
14377
14378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14379     {
14380       if (unformat (i, "name %s", &host_if_name))
14381         vec_add1 (host_if_name, 0);
14382       else
14383         break;
14384     }
14385
14386   if (!vec_len (host_if_name))
14387     {
14388       errmsg ("host-interface name must be specified");
14389       return -99;
14390     }
14391
14392   if (vec_len (host_if_name) > 64)
14393     {
14394       errmsg ("host-interface name too long");
14395       return -99;
14396     }
14397
14398   M (AF_PACKET_DELETE, af_packet_delete);
14399
14400   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14401   vec_free (host_if_name);
14402
14403   S;
14404   W;
14405   /* NOTREACHED */
14406   return 0;
14407 }
14408
14409 static int
14410 api_policer_add_del (vat_main_t * vam)
14411 {
14412   unformat_input_t *i = vam->input;
14413   vl_api_policer_add_del_t *mp;
14414   f64 timeout;
14415   u8 is_add = 1;
14416   u8 *name = 0;
14417   u32 cir = 0;
14418   u32 eir = 0;
14419   u64 cb = 0;
14420   u64 eb = 0;
14421   u8 rate_type = 0;
14422   u8 round_type = 0;
14423   u8 type = 0;
14424   u8 color_aware = 0;
14425   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14426
14427   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14428   conform_action.dscp = 0;
14429   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14430   exceed_action.dscp = 0;
14431   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14432   violate_action.dscp = 0;
14433
14434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14435     {
14436       if (unformat (i, "del"))
14437         is_add = 0;
14438       else if (unformat (i, "name %s", &name))
14439         vec_add1 (name, 0);
14440       else if (unformat (i, "cir %u", &cir))
14441         ;
14442       else if (unformat (i, "eir %u", &eir))
14443         ;
14444       else if (unformat (i, "cb %u", &cb))
14445         ;
14446       else if (unformat (i, "eb %u", &eb))
14447         ;
14448       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14449                          &rate_type))
14450         ;
14451       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14452                          &round_type))
14453         ;
14454       else if (unformat (i, "type %U", unformat_policer_type, &type))
14455         ;
14456       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14457                          &conform_action))
14458         ;
14459       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14460                          &exceed_action))
14461         ;
14462       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14463                          &violate_action))
14464         ;
14465       else if (unformat (i, "color-aware"))
14466         color_aware = 1;
14467       else
14468         break;
14469     }
14470
14471   if (!vec_len (name))
14472     {
14473       errmsg ("policer name must be specified");
14474       return -99;
14475     }
14476
14477   if (vec_len (name) > 64)
14478     {
14479       errmsg ("policer name too long");
14480       return -99;
14481     }
14482
14483   M (POLICER_ADD_DEL, policer_add_del);
14484
14485   clib_memcpy (mp->name, name, vec_len (name));
14486   vec_free (name);
14487   mp->is_add = is_add;
14488   mp->cir = cir;
14489   mp->eir = eir;
14490   mp->cb = cb;
14491   mp->eb = eb;
14492   mp->rate_type = rate_type;
14493   mp->round_type = round_type;
14494   mp->type = type;
14495   mp->conform_action_type = conform_action.action_type;
14496   mp->conform_dscp = conform_action.dscp;
14497   mp->exceed_action_type = exceed_action.action_type;
14498   mp->exceed_dscp = exceed_action.dscp;
14499   mp->violate_action_type = violate_action.action_type;
14500   mp->violate_dscp = violate_action.dscp;
14501   mp->color_aware = color_aware;
14502
14503   S;
14504   W;
14505   /* NOTREACHED */
14506   return 0;
14507 }
14508
14509 static int
14510 api_policer_dump (vat_main_t * vam)
14511 {
14512   unformat_input_t *i = vam->input;
14513   vl_api_policer_dump_t *mp;
14514   f64 timeout = ~0;
14515   u8 *match_name = 0;
14516   u8 match_name_valid = 0;
14517
14518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14519     {
14520       if (unformat (i, "name %s", &match_name))
14521         {
14522           vec_add1 (match_name, 0);
14523           match_name_valid = 1;
14524         }
14525       else
14526         break;
14527     }
14528
14529   M (POLICER_DUMP, policer_dump);
14530   mp->match_name_valid = match_name_valid;
14531   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14532   vec_free (match_name);
14533   /* send it... */
14534   S;
14535
14536   /* Use a control ping for synchronization */
14537   {
14538     vl_api_control_ping_t *mp;
14539     M (CONTROL_PING, control_ping);
14540     S;
14541   }
14542   /* Wait for a reply... */
14543   W;
14544
14545   /* NOTREACHED */
14546   return 0;
14547 }
14548
14549 static int
14550 api_policer_classify_set_interface (vat_main_t * vam)
14551 {
14552   unformat_input_t *i = vam->input;
14553   vl_api_policer_classify_set_interface_t *mp;
14554   f64 timeout;
14555   u32 sw_if_index;
14556   int sw_if_index_set;
14557   u32 ip4_table_index = ~0;
14558   u32 ip6_table_index = ~0;
14559   u32 l2_table_index = ~0;
14560   u8 is_add = 1;
14561
14562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14563     {
14564       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14565         sw_if_index_set = 1;
14566       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14567         sw_if_index_set = 1;
14568       else if (unformat (i, "del"))
14569         is_add = 0;
14570       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14571         ;
14572       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14573         ;
14574       else if (unformat (i, "l2-table %d", &l2_table_index))
14575         ;
14576       else
14577         {
14578           clib_warning ("parse error '%U'", format_unformat_error, i);
14579           return -99;
14580         }
14581     }
14582
14583   if (sw_if_index_set == 0)
14584     {
14585       errmsg ("missing interface name or sw_if_index\n");
14586       return -99;
14587     }
14588
14589   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14590
14591   mp->sw_if_index = ntohl (sw_if_index);
14592   mp->ip4_table_index = ntohl (ip4_table_index);
14593   mp->ip6_table_index = ntohl (ip6_table_index);
14594   mp->l2_table_index = ntohl (l2_table_index);
14595   mp->is_add = is_add;
14596
14597   S;
14598   W;
14599   /* NOTREACHED */
14600   return 0;
14601 }
14602
14603 static int
14604 api_policer_classify_dump (vat_main_t * vam)
14605 {
14606   unformat_input_t *i = vam->input;
14607   vl_api_policer_classify_dump_t *mp;
14608   f64 timeout = ~0;
14609   u8 type = POLICER_CLASSIFY_N_TABLES;
14610
14611   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14612     ;
14613   else
14614     {
14615       errmsg ("classify table type must be specified\n");
14616       return -99;
14617     }
14618
14619   if (!vam->json_output)
14620     {
14621       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14622     }
14623
14624   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14625   mp->type = type;
14626   /* send it... */
14627   S;
14628
14629   /* Use a control ping for synchronization */
14630   {
14631     vl_api_control_ping_t *mp;
14632     M (CONTROL_PING, control_ping);
14633     S;
14634   }
14635   /* Wait for a reply... */
14636   W;
14637
14638   /* NOTREACHED */
14639   return 0;
14640 }
14641
14642 static int
14643 api_netmap_create (vat_main_t * vam)
14644 {
14645   unformat_input_t *i = vam->input;
14646   vl_api_netmap_create_t *mp;
14647   f64 timeout;
14648   u8 *if_name = 0;
14649   u8 hw_addr[6];
14650   u8 random_hw_addr = 1;
14651   u8 is_pipe = 0;
14652   u8 is_master = 0;
14653
14654   memset (hw_addr, 0, sizeof (hw_addr));
14655
14656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14657     {
14658       if (unformat (i, "name %s", &if_name))
14659         vec_add1 (if_name, 0);
14660       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14661         random_hw_addr = 0;
14662       else if (unformat (i, "pipe"))
14663         is_pipe = 1;
14664       else if (unformat (i, "master"))
14665         is_master = 1;
14666       else if (unformat (i, "slave"))
14667         is_master = 0;
14668       else
14669         break;
14670     }
14671
14672   if (!vec_len (if_name))
14673     {
14674       errmsg ("interface name must be specified");
14675       return -99;
14676     }
14677
14678   if (vec_len (if_name) > 64)
14679     {
14680       errmsg ("interface name too long");
14681       return -99;
14682     }
14683
14684   M (NETMAP_CREATE, netmap_create);
14685
14686   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14687   clib_memcpy (mp->hw_addr, hw_addr, 6);
14688   mp->use_random_hw_addr = random_hw_addr;
14689   mp->is_pipe = is_pipe;
14690   mp->is_master = is_master;
14691   vec_free (if_name);
14692
14693   S;
14694   W;
14695   /* NOTREACHED */
14696   return 0;
14697 }
14698
14699 static int
14700 api_netmap_delete (vat_main_t * vam)
14701 {
14702   unformat_input_t *i = vam->input;
14703   vl_api_netmap_delete_t *mp;
14704   f64 timeout;
14705   u8 *if_name = 0;
14706
14707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14708     {
14709       if (unformat (i, "name %s", &if_name))
14710         vec_add1 (if_name, 0);
14711       else
14712         break;
14713     }
14714
14715   if (!vec_len (if_name))
14716     {
14717       errmsg ("interface name must be specified");
14718       return -99;
14719     }
14720
14721   if (vec_len (if_name) > 64)
14722     {
14723       errmsg ("interface name too long");
14724       return -99;
14725     }
14726
14727   M (NETMAP_DELETE, netmap_delete);
14728
14729   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14730   vec_free (if_name);
14731
14732   S;
14733   W;
14734   /* NOTREACHED */
14735   return 0;
14736 }
14737
14738 static void vl_api_mpls_eth_tunnel_details_t_handler
14739   (vl_api_mpls_eth_tunnel_details_t * mp)
14740 {
14741   vat_main_t *vam = &vat_main;
14742   i32 i;
14743   i32 len = ntohl (mp->nlabels);
14744
14745   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14746            ntohl (mp->tunnel_index),
14747            format_ethernet_address, &mp->tunnel_dst_mac,
14748            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14749   for (i = 0; i < len; i++)
14750     {
14751       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14752     }
14753   fformat (vam->ofp, "\n");
14754   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14755            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14756 }
14757
14758 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14759   (vl_api_mpls_eth_tunnel_details_t * mp)
14760 {
14761   vat_main_t *vam = &vat_main;
14762   vat_json_node_t *node = NULL;
14763   struct in_addr ip4;
14764   i32 i;
14765   i32 len = ntohl (mp->nlabels);
14766
14767   if (VAT_JSON_ARRAY != vam->json_tree.type)
14768     {
14769       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14770       vat_json_init_array (&vam->json_tree);
14771     }
14772   node = vat_json_array_add (&vam->json_tree);
14773
14774   vat_json_init_object (node);
14775   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14776   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14777   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14778   vat_json_object_add_uint (node, "inner_fib_index",
14779                             ntohl (mp->inner_fib_index));
14780   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14781   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14782   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14783   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14784   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14785                                    format (0, "%U", format_ethernet_address,
14786                                            &mp->tunnel_dst_mac));
14787   vat_json_object_add_uint (node, "tx_sw_if_index",
14788                             ntohl (mp->tx_sw_if_index));
14789   vat_json_object_add_uint (node, "label_count", len);
14790   for (i = 0; i < len; i++)
14791     {
14792       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14793     }
14794 }
14795
14796 static int
14797 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14798 {
14799   vl_api_mpls_eth_tunnel_dump_t *mp;
14800   f64 timeout;
14801   i32 index = -1;
14802
14803   /* Parse args required to build the message */
14804   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14805     {
14806       if (!unformat (vam->input, "tunnel_index %d", &index))
14807         {
14808           index = -1;
14809           break;
14810         }
14811     }
14812
14813   fformat (vam->ofp, "  tunnel_index %d\n", index);
14814
14815   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14816   mp->tunnel_index = htonl (index);
14817   S;
14818
14819   /* Use a control ping for synchronization */
14820   {
14821     vl_api_control_ping_t *mp;
14822     M (CONTROL_PING, control_ping);
14823     S;
14824   }
14825   W;
14826 }
14827
14828 static void vl_api_mpls_fib_encap_details_t_handler
14829   (vl_api_mpls_fib_encap_details_t * mp)
14830 {
14831   vat_main_t *vam = &vat_main;
14832   i32 i;
14833   i32 len = ntohl (mp->nlabels);
14834
14835   fformat (vam->ofp, "table %d, dest %U, label ",
14836            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14837   for (i = 0; i < len; i++)
14838     {
14839       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14840     }
14841   fformat (vam->ofp, "\n");
14842 }
14843
14844 static void vl_api_mpls_fib_encap_details_t_handler_json
14845   (vl_api_mpls_fib_encap_details_t * mp)
14846 {
14847   vat_main_t *vam = &vat_main;
14848   vat_json_node_t *node = NULL;
14849   i32 i;
14850   i32 len = ntohl (mp->nlabels);
14851   struct in_addr ip4;
14852
14853   if (VAT_JSON_ARRAY != vam->json_tree.type)
14854     {
14855       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14856       vat_json_init_array (&vam->json_tree);
14857     }
14858   node = vat_json_array_add (&vam->json_tree);
14859
14860   vat_json_init_object (node);
14861   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14862   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14863   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14864   vat_json_object_add_ip4 (node, "dest", ip4);
14865   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14866   vat_json_object_add_uint (node, "label_count", len);
14867   for (i = 0; i < len; i++)
14868     {
14869       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14870     }
14871 }
14872
14873 static int
14874 api_mpls_fib_encap_dump (vat_main_t * vam)
14875 {
14876   vl_api_mpls_fib_encap_dump_t *mp;
14877   f64 timeout;
14878
14879   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14880   S;
14881
14882   /* Use a control ping for synchronization */
14883   {
14884     vl_api_control_ping_t *mp;
14885     M (CONTROL_PING, control_ping);
14886     S;
14887   }
14888   W;
14889 }
14890
14891 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
14892 #define vl_api_mpls_fib_details_t_print vl_noop_handler
14893
14894 static void
14895 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
14896 {
14897   vat_main_t *vam = &vat_main;
14898   int count = ntohl (mp->count);
14899   vl_api_fib_path_t *fp;
14900   int i;
14901
14902   fformat (vam->ofp,
14903            "table-id %d, label %u, ess_bit %u\n",
14904            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
14905   fp = mp->path;
14906   for (i = 0; i < count; i++)
14907     {
14908       if (fp->afi == IP46_TYPE_IP6)
14909         fformat (vam->ofp,
14910                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14911                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14912                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14913                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14914                  format_ip6_address, fp->next_hop);
14915       else if (fp->afi == IP46_TYPE_IP4)
14916         fformat (vam->ofp,
14917                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14918                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14919                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14920                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14921                  format_ip4_address, fp->next_hop);
14922       fp++;
14923     }
14924 }
14925
14926 static void vl_api_mpls_fib_details_t_handler_json
14927   (vl_api_mpls_fib_details_t * mp)
14928 {
14929   vat_main_t *vam = &vat_main;
14930   int count = ntohl (mp->count);
14931   vat_json_node_t *node = NULL;
14932   struct in_addr ip4;
14933   struct in6_addr ip6;
14934   vl_api_fib_path_t *fp;
14935   int i;
14936
14937   if (VAT_JSON_ARRAY != vam->json_tree.type)
14938     {
14939       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14940       vat_json_init_array (&vam->json_tree);
14941     }
14942   node = vat_json_array_add (&vam->json_tree);
14943
14944   vat_json_init_object (node);
14945   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
14946   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
14947   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14948   vat_json_object_add_uint (node, "path_count", count);
14949   fp = mp->path;
14950   for (i = 0; i < count; i++)
14951     {
14952       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
14953       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
14954       vat_json_object_add_uint (node, "is_local", fp->is_local);
14955       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
14956       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
14957       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
14958       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
14959       if (fp->afi == IP46_TYPE_IP4)
14960         {
14961           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
14962           vat_json_object_add_ip4 (node, "next_hop", ip4);
14963         }
14964       else if (fp->afi == IP46_TYPE_IP6)
14965         {
14966           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
14967           vat_json_object_add_ip6 (node, "next_hop", ip6);
14968         }
14969     }
14970 }
14971
14972 static int
14973 api_mpls_fib_dump (vat_main_t * vam)
14974 {
14975   vl_api_mpls_fib_dump_t *mp;
14976   f64 timeout;
14977
14978   M (MPLS_FIB_DUMP, mpls_fib_dump);
14979   S;
14980
14981   /* Use a control ping for synchronization */
14982   {
14983     vl_api_control_ping_t *mp;
14984     M (CONTROL_PING, control_ping);
14985     S;
14986   }
14987   W;
14988 }
14989
14990 #define vl_api_ip_fib_details_t_endian vl_noop_handler
14991 #define vl_api_ip_fib_details_t_print vl_noop_handler
14992
14993 static void
14994 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
14995 {
14996   vat_main_t *vam = &vat_main;
14997   int count = ntohl (mp->count);
14998   vl_api_fib_path_t *fp;
14999   int i;
15000
15001   fformat (vam->ofp,
15002            "table-id %d, prefix %U/%d\n",
15003            ntohl (mp->table_id), format_ip4_address, mp->address,
15004            mp->address_length);
15005   fp = mp->path;
15006   for (i = 0; i < count; i++)
15007     {
15008       if (fp->afi == IP46_TYPE_IP6)
15009         fformat (vam->ofp,
15010                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15011                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15012                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15013                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15014                  format_ip6_address, fp->next_hop);
15015       else if (fp->afi == IP46_TYPE_IP4)
15016         fformat (vam->ofp,
15017                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15018                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15019                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15020                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15021                  format_ip4_address, fp->next_hop);
15022       fp++;
15023     }
15024 }
15025
15026 static void vl_api_ip_fib_details_t_handler_json
15027   (vl_api_ip_fib_details_t * mp)
15028 {
15029   vat_main_t *vam = &vat_main;
15030   int count = ntohl (mp->count);
15031   vat_json_node_t *node = NULL;
15032   struct in_addr ip4;
15033   struct in6_addr ip6;
15034   vl_api_fib_path_t *fp;
15035   int i;
15036
15037   if (VAT_JSON_ARRAY != vam->json_tree.type)
15038     {
15039       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15040       vat_json_init_array (&vam->json_tree);
15041     }
15042   node = vat_json_array_add (&vam->json_tree);
15043
15044   vat_json_init_object (node);
15045   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15046   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15047   vat_json_object_add_ip4 (node, "prefix", ip4);
15048   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15049   vat_json_object_add_uint (node, "path_count", count);
15050   fp = mp->path;
15051   for (i = 0; i < count; i++)
15052     {
15053       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15054       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15055       vat_json_object_add_uint (node, "is_local", fp->is_local);
15056       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15057       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15058       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15059       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15060       if (fp->afi == IP46_TYPE_IP4)
15061         {
15062           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15063           vat_json_object_add_ip4 (node, "next_hop", ip4);
15064         }
15065       else if (fp->afi == IP46_TYPE_IP6)
15066         {
15067           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15068           vat_json_object_add_ip6 (node, "next_hop", ip6);
15069         }
15070     }
15071 }
15072
15073 static int
15074 api_ip_fib_dump (vat_main_t * vam)
15075 {
15076   vl_api_ip_fib_dump_t *mp;
15077   f64 timeout;
15078
15079   M (IP_FIB_DUMP, ip_fib_dump);
15080   S;
15081
15082   /* Use a control ping for synchronization */
15083   {
15084     vl_api_control_ping_t *mp;
15085     M (CONTROL_PING, control_ping);
15086     S;
15087   }
15088   W;
15089 }
15090
15091 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15092 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15093
15094 static void
15095 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15096 {
15097   vat_main_t *vam = &vat_main;
15098   int count = ntohl (mp->count);
15099   vl_api_fib_path_t *fp;
15100   int i;
15101
15102   fformat (vam->ofp,
15103            "table-id %d, prefix %U/%d\n",
15104            ntohl (mp->table_id), format_ip6_address, mp->address,
15105            mp->address_length);
15106   fp = mp->path;
15107   for (i = 0; i < count; i++)
15108     {
15109       if (fp->afi == IP46_TYPE_IP6)
15110         fformat (vam->ofp,
15111                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15112                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15113                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15114                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15115                  format_ip6_address, fp->next_hop);
15116       else if (fp->afi == IP46_TYPE_IP4)
15117         fformat (vam->ofp,
15118                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15119                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15120                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15121                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15122                  format_ip4_address, fp->next_hop);
15123       fp++;
15124     }
15125 }
15126
15127 static void vl_api_ip6_fib_details_t_handler_json
15128   (vl_api_ip6_fib_details_t * mp)
15129 {
15130   vat_main_t *vam = &vat_main;
15131   int count = ntohl (mp->count);
15132   vat_json_node_t *node = NULL;
15133   struct in_addr ip4;
15134   struct in6_addr ip6;
15135   vl_api_fib_path_t *fp;
15136   int i;
15137
15138   if (VAT_JSON_ARRAY != vam->json_tree.type)
15139     {
15140       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15141       vat_json_init_array (&vam->json_tree);
15142     }
15143   node = vat_json_array_add (&vam->json_tree);
15144
15145   vat_json_init_object (node);
15146   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15147   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15148   vat_json_object_add_ip6 (node, "prefix", ip6);
15149   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15150   vat_json_object_add_uint (node, "path_count", count);
15151   fp = mp->path;
15152   for (i = 0; i < count; i++)
15153     {
15154       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15155       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15156       vat_json_object_add_uint (node, "is_local", fp->is_local);
15157       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15158       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15159       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15160       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15161       if (fp->afi == IP46_TYPE_IP4)
15162         {
15163           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15164           vat_json_object_add_ip4 (node, "next_hop", ip4);
15165         }
15166       else if (fp->afi == IP46_TYPE_IP6)
15167         {
15168           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15169           vat_json_object_add_ip6 (node, "next_hop", ip6);
15170         }
15171     }
15172 }
15173
15174 static int
15175 api_ip6_fib_dump (vat_main_t * vam)
15176 {
15177   vl_api_ip6_fib_dump_t *mp;
15178   f64 timeout;
15179
15180   M (IP6_FIB_DUMP, ip6_fib_dump);
15181   S;
15182
15183   /* Use a control ping for synchronization */
15184   {
15185     vl_api_control_ping_t *mp;
15186     M (CONTROL_PING, control_ping);
15187     S;
15188   }
15189   W;
15190 }
15191
15192 int
15193 api_classify_table_ids (vat_main_t * vam)
15194 {
15195   vl_api_classify_table_ids_t *mp;
15196   f64 timeout;
15197
15198   /* Construct the API message */
15199   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15200   mp->context = 0;
15201
15202   S;
15203   W;
15204   /* NOTREACHED */
15205   return 0;
15206 }
15207
15208 int
15209 api_classify_table_by_interface (vat_main_t * vam)
15210 {
15211   unformat_input_t *input = vam->input;
15212   vl_api_classify_table_by_interface_t *mp;
15213   f64 timeout;
15214
15215   u32 sw_if_index = ~0;
15216   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15217     {
15218       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15219         ;
15220       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15221         ;
15222       else
15223         break;
15224     }
15225   if (sw_if_index == ~0)
15226     {
15227       errmsg ("missing interface name or sw_if_index\n");
15228       return -99;
15229     }
15230
15231   /* Construct the API message */
15232   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15233   mp->context = 0;
15234   mp->sw_if_index = ntohl (sw_if_index);
15235
15236   S;
15237   W;
15238   /* NOTREACHED */
15239   return 0;
15240 }
15241
15242 int
15243 api_classify_table_info (vat_main_t * vam)
15244 {
15245   unformat_input_t *input = vam->input;
15246   vl_api_classify_table_info_t *mp;
15247   f64 timeout;
15248
15249   u32 table_id = ~0;
15250   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15251     {
15252       if (unformat (input, "table_id %d", &table_id))
15253         ;
15254       else
15255         break;
15256     }
15257   if (table_id == ~0)
15258     {
15259       errmsg ("missing table id\n");
15260       return -99;
15261     }
15262
15263   /* Construct the API message */
15264   M (CLASSIFY_TABLE_INFO, classify_table_info);
15265   mp->context = 0;
15266   mp->table_id = ntohl (table_id);
15267
15268   S;
15269   W;
15270   /* NOTREACHED */
15271   return 0;
15272 }
15273
15274 int
15275 api_classify_session_dump (vat_main_t * vam)
15276 {
15277   unformat_input_t *input = vam->input;
15278   vl_api_classify_session_dump_t *mp;
15279   f64 timeout;
15280
15281   u32 table_id = ~0;
15282   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15283     {
15284       if (unformat (input, "table_id %d", &table_id))
15285         ;
15286       else
15287         break;
15288     }
15289   if (table_id == ~0)
15290     {
15291       errmsg ("missing table id\n");
15292       return -99;
15293     }
15294
15295   /* Construct the API message */
15296   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15297   mp->context = 0;
15298   mp->table_id = ntohl (table_id);
15299   S;
15300
15301   /* Use a control ping for synchronization */
15302   {
15303     vl_api_control_ping_t *mp;
15304     M (CONTROL_PING, control_ping);
15305     S;
15306   }
15307   W;
15308   /* NOTREACHED */
15309   return 0;
15310 }
15311
15312 static void
15313 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15314 {
15315   vat_main_t *vam = &vat_main;
15316
15317   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15318            "src_address %U, vrf_id %d, path_mtu %u, "
15319            "template_interval %u, udp_checksum %d\n",
15320            format_ip4_address, mp->collector_address,
15321            ntohs (mp->collector_port),
15322            format_ip4_address, mp->src_address,
15323            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15324            ntohl (mp->template_interval), mp->udp_checksum);
15325
15326   vam->retval = 0;
15327   vam->result_ready = 1;
15328 }
15329
15330 static void
15331   vl_api_ipfix_exporter_details_t_handler_json
15332   (vl_api_ipfix_exporter_details_t * mp)
15333 {
15334   vat_main_t *vam = &vat_main;
15335   vat_json_node_t node;
15336   struct in_addr collector_address;
15337   struct in_addr src_address;
15338
15339   vat_json_init_object (&node);
15340   clib_memcpy (&collector_address, &mp->collector_address,
15341                sizeof (collector_address));
15342   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15343   vat_json_object_add_uint (&node, "collector_port",
15344                             ntohs (mp->collector_port));
15345   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15346   vat_json_object_add_ip4 (&node, "src_address", src_address);
15347   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15348   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15349   vat_json_object_add_uint (&node, "template_interval",
15350                             ntohl (mp->template_interval));
15351   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15352
15353   vat_json_print (vam->ofp, &node);
15354   vat_json_free (&node);
15355   vam->retval = 0;
15356   vam->result_ready = 1;
15357 }
15358
15359 int
15360 api_ipfix_exporter_dump (vat_main_t * vam)
15361 {
15362   vl_api_ipfix_exporter_dump_t *mp;
15363   f64 timeout;
15364
15365   /* Construct the API message */
15366   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15367   mp->context = 0;
15368
15369   S;
15370   W;
15371   /* NOTREACHED */
15372   return 0;
15373 }
15374
15375 static int
15376 api_ipfix_classify_stream_dump (vat_main_t * vam)
15377 {
15378   vl_api_ipfix_classify_stream_dump_t *mp;
15379   f64 timeout;
15380
15381   /* Construct the API message */
15382   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15383   mp->context = 0;
15384
15385   S;
15386   W;
15387   /* NOTREACHED */
15388   return 0;
15389 }
15390
15391 static void
15392   vl_api_ipfix_classify_stream_details_t_handler
15393   (vl_api_ipfix_classify_stream_details_t * mp)
15394 {
15395   vat_main_t *vam = &vat_main;
15396   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15397            ntohl (mp->domain_id), ntohs (mp->src_port));
15398   vam->retval = 0;
15399   vam->result_ready = 1;
15400 }
15401
15402 static void
15403   vl_api_ipfix_classify_stream_details_t_handler_json
15404   (vl_api_ipfix_classify_stream_details_t * mp)
15405 {
15406   vat_main_t *vam = &vat_main;
15407   vat_json_node_t node;
15408
15409   vat_json_init_object (&node);
15410   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15411   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15412
15413   vat_json_print (vam->ofp, &node);
15414   vat_json_free (&node);
15415   vam->retval = 0;
15416   vam->result_ready = 1;
15417 }
15418
15419 static int
15420 api_ipfix_classify_table_dump (vat_main_t * vam)
15421 {
15422   vl_api_ipfix_classify_table_dump_t *mp;
15423   f64 timeout;
15424
15425   if (!vam->json_output)
15426     {
15427       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15428                "transport_protocol");
15429     }
15430
15431   /* Construct the API message */
15432   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15433
15434   /* send it... */
15435   S;
15436
15437   /* Use a control ping for synchronization */
15438   {
15439     vl_api_control_ping_t *mp;
15440     M (CONTROL_PING, control_ping);
15441     S;
15442   }
15443   W;
15444 }
15445
15446 static void
15447   vl_api_ipfix_classify_table_details_t_handler
15448   (vl_api_ipfix_classify_table_details_t * mp)
15449 {
15450   vat_main_t *vam = &vat_main;
15451   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15452            mp->transport_protocol);
15453 }
15454
15455 static void
15456   vl_api_ipfix_classify_table_details_t_handler_json
15457   (vl_api_ipfix_classify_table_details_t * mp)
15458 {
15459   vat_json_node_t *node = NULL;
15460   vat_main_t *vam = &vat_main;
15461
15462   if (VAT_JSON_ARRAY != vam->json_tree.type)
15463     {
15464       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15465       vat_json_init_array (&vam->json_tree);
15466     }
15467
15468   node = vat_json_array_add (&vam->json_tree);
15469   vat_json_init_object (node);
15470
15471   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15472   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15473   vat_json_object_add_uint (node, "transport_protocol",
15474                             mp->transport_protocol);
15475 }
15476
15477 static int
15478 api_sw_interface_span_enable_disable (vat_main_t * vam)
15479 {
15480   unformat_input_t *i = vam->input;
15481   vl_api_sw_interface_span_enable_disable_t *mp;
15482   f64 timeout;
15483   u32 src_sw_if_index = ~0;
15484   u32 dst_sw_if_index = ~0;
15485   u8 enable = 1;
15486
15487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15488     {
15489       if (unformat (i, "src %U", unformat_sw_if_index, vam, &src_sw_if_index))
15490         ;
15491       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15492         ;
15493       else
15494         if (unformat
15495             (i, "dst %U", unformat_sw_if_index, vam, &dst_sw_if_index))
15496         ;
15497       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15498         ;
15499       else if (unformat (i, "disable"))
15500         enable = 0;
15501       else
15502         break;
15503     }
15504
15505   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
15506
15507   mp->sw_if_index_from = htonl (src_sw_if_index);
15508   mp->sw_if_index_to = htonl (dst_sw_if_index);
15509   mp->enable = enable;
15510
15511   S;
15512   W;
15513   /* NOTREACHED */
15514   return 0;
15515 }
15516
15517 static void
15518 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
15519                                             * mp)
15520 {
15521   vat_main_t *vam = &vat_main;
15522
15523   fformat (vam->ofp, "%u => %u\n",
15524            ntohl (mp->sw_if_index_from), ntohl (mp->sw_if_index_to));
15525 }
15526
15527 static void
15528   vl_api_sw_interface_span_details_t_handler_json
15529   (vl_api_sw_interface_span_details_t * mp)
15530 {
15531   vat_main_t *vam = &vat_main;
15532   vat_json_node_t *node = NULL;
15533
15534   if (VAT_JSON_ARRAY != vam->json_tree.type)
15535     {
15536       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15537       vat_json_init_array (&vam->json_tree);
15538     }
15539   node = vat_json_array_add (&vam->json_tree);
15540
15541   vat_json_init_object (node);
15542   vat_json_object_add_uint (node, "src-if-index",
15543                             ntohl (mp->sw_if_index_from));
15544   vat_json_object_add_uint (node, "dst-if-index", ntohl (mp->sw_if_index_to));
15545 }
15546
15547 static int
15548 api_sw_interface_span_dump (vat_main_t * vam)
15549 {
15550   vl_api_sw_interface_span_dump_t *mp;
15551   f64 timeout;
15552
15553   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
15554   S;
15555
15556   /* Use a control ping for synchronization */
15557   {
15558     vl_api_control_ping_t *mp;
15559     M (CONTROL_PING, control_ping);
15560     S;
15561   }
15562   W;
15563 }
15564
15565 int
15566 api_pg_create_interface (vat_main_t * vam)
15567 {
15568   unformat_input_t *input = vam->input;
15569   vl_api_pg_create_interface_t *mp;
15570   f64 timeout;
15571
15572   u32 if_id = ~0;
15573   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15574     {
15575       if (unformat (input, "if_id %d", &if_id))
15576         ;
15577       else
15578         break;
15579     }
15580   if (if_id == ~0)
15581     {
15582       errmsg ("missing pg interface index\n");
15583       return -99;
15584     }
15585
15586   /* Construct the API message */
15587   M (PG_CREATE_INTERFACE, pg_create_interface);
15588   mp->context = 0;
15589   mp->interface_id = ntohl (if_id);
15590
15591   S;
15592   W;
15593   /* NOTREACHED */
15594   return 0;
15595 }
15596
15597 int
15598 api_pg_capture (vat_main_t * vam)
15599 {
15600   unformat_input_t *input = vam->input;
15601   vl_api_pg_capture_t *mp;
15602   f64 timeout;
15603
15604   u32 if_id = ~0;
15605   u8 enable = 1;
15606   u32 count = 1;
15607   u8 pcap_file_set = 0;
15608   u8 *pcap_file = 0;
15609   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15610     {
15611       if (unformat (input, "if_id %d", &if_id))
15612         ;
15613       else if (unformat (input, "pcap %s", &pcap_file))
15614         pcap_file_set = 1;
15615       else if (unformat (input, "count %d", &count))
15616         ;
15617       else if (unformat (input, "disable"))
15618         enable = 0;
15619       else
15620         break;
15621     }
15622   if (if_id == ~0)
15623     {
15624       errmsg ("missing pg interface index\n");
15625       return -99;
15626     }
15627   if (pcap_file_set > 0)
15628     {
15629       if (vec_len (pcap_file) > 255)
15630         {
15631           errmsg ("pcap file name is too long\n");
15632           return -99;
15633         }
15634     }
15635
15636   u32 name_len = vec_len (pcap_file);
15637   /* Construct the API message */
15638   M (PG_CAPTURE, pg_capture);
15639   mp->context = 0;
15640   mp->interface_id = ntohl (if_id);
15641   mp->is_enabled = enable;
15642   mp->count = ntohl (count);
15643   mp->pcap_name_length = ntohl (name_len);
15644   if (pcap_file_set != 0)
15645     {
15646       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15647     }
15648   vec_free (pcap_file);
15649
15650   S;
15651   W;
15652   /* NOTREACHED */
15653   return 0;
15654 }
15655
15656 int
15657 api_pg_enable_disable (vat_main_t * vam)
15658 {
15659   unformat_input_t *input = vam->input;
15660   vl_api_pg_enable_disable_t *mp;
15661   f64 timeout;
15662
15663   u8 enable = 1;
15664   u8 stream_name_set = 0;
15665   u8 *stream_name = 0;
15666   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15667     {
15668       if (unformat (input, "stream %s", &stream_name))
15669         stream_name_set = 1;
15670       else if (unformat (input, "disable"))
15671         enable = 0;
15672       else
15673         break;
15674     }
15675
15676   if (stream_name_set > 0)
15677     {
15678       if (vec_len (stream_name) > 255)
15679         {
15680           errmsg ("stream name too long\n");
15681           return -99;
15682         }
15683     }
15684
15685   u32 name_len = vec_len (stream_name);
15686   /* Construct the API message */
15687   M (PG_ENABLE_DISABLE, pg_enable_disable);
15688   mp->context = 0;
15689   mp->is_enabled = enable;
15690   if (stream_name_set != 0)
15691     {
15692       mp->stream_name_length = ntohl (name_len);
15693       clib_memcpy (mp->stream_name, stream_name, name_len);
15694     }
15695   vec_free (stream_name);
15696
15697   S;
15698   W;
15699   /* NOTREACHED */
15700   return 0;
15701 }
15702
15703 int
15704 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15705 {
15706   unformat_input_t *input = vam->input;
15707   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15708   f64 timeout;
15709
15710   u16 *low_ports = 0;
15711   u16 *high_ports = 0;
15712   u16 this_low;
15713   u16 this_hi;
15714   ip4_address_t ip4_addr;
15715   ip6_address_t ip6_addr;
15716   u32 length;
15717   u32 tmp, tmp2;
15718   u8 prefix_set = 0;
15719   u32 vrf_id = ~0;
15720   u8 is_add = 1;
15721   u8 is_ipv6 = 0;
15722
15723   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15724     {
15725       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15726         {
15727           prefix_set = 1;
15728         }
15729       else
15730         if (unformat
15731             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15732         {
15733           prefix_set = 1;
15734           is_ipv6 = 1;
15735         }
15736       else if (unformat (input, "vrf %d", &vrf_id))
15737         ;
15738       else if (unformat (input, "del"))
15739         is_add = 0;
15740       else if (unformat (input, "port %d", &tmp))
15741         {
15742           if (tmp == 0 || tmp > 65535)
15743             {
15744               errmsg ("port %d out of range", tmp);
15745               return -99;
15746             }
15747           this_low = tmp;
15748           this_hi = this_low + 1;
15749           vec_add1 (low_ports, this_low);
15750           vec_add1 (high_ports, this_hi);
15751         }
15752       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15753         {
15754           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15755             {
15756               errmsg ("incorrect range parameters\n");
15757               return -99;
15758             }
15759           this_low = tmp;
15760           /* Note: in debug CLI +1 is added to high before
15761              passing to real fn that does "the work"
15762              (ip_source_and_port_range_check_add_del).
15763              This fn is a wrapper around the binary API fn a
15764              control plane will call, which expects this increment
15765              to have occurred. Hence letting the binary API control
15766              plane fn do the increment for consistency between VAT
15767              and other control planes.
15768            */
15769           this_hi = tmp2;
15770           vec_add1 (low_ports, this_low);
15771           vec_add1 (high_ports, this_hi);
15772         }
15773       else
15774         break;
15775     }
15776
15777   if (prefix_set == 0)
15778     {
15779       errmsg ("<address>/<mask> not specified\n");
15780       return -99;
15781     }
15782
15783   if (vrf_id == ~0)
15784     {
15785       errmsg ("VRF ID required, not specified\n");
15786       return -99;
15787     }
15788
15789   if (vrf_id == 0)
15790     {
15791       errmsg
15792         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15793       return -99;
15794     }
15795
15796   if (vec_len (low_ports) == 0)
15797     {
15798       errmsg ("At least one port or port range required\n");
15799       return -99;
15800     }
15801
15802   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15803      ip_source_and_port_range_check_add_del);
15804
15805   mp->is_add = is_add;
15806
15807   if (is_ipv6)
15808     {
15809       mp->is_ipv6 = 1;
15810       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15811     }
15812   else
15813     {
15814       mp->is_ipv6 = 0;
15815       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15816     }
15817
15818   mp->mask_length = length;
15819   mp->number_of_ranges = vec_len (low_ports);
15820
15821   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15822   vec_free (low_ports);
15823
15824   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15825   vec_free (high_ports);
15826
15827   mp->vrf_id = ntohl (vrf_id);
15828
15829   S;
15830   W;
15831   /* NOTREACHED */
15832   return 0;
15833 }
15834
15835 int
15836 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15837 {
15838   unformat_input_t *input = vam->input;
15839   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15840   f64 timeout;
15841   u32 sw_if_index = ~0;
15842   int vrf_set = 0;
15843   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15844   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15845   u8 is_add = 1;
15846
15847   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15848     {
15849       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15850         ;
15851       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15852         ;
15853       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15854         vrf_set = 1;
15855       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15856         vrf_set = 1;
15857       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15858         vrf_set = 1;
15859       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15860         vrf_set = 1;
15861       else if (unformat (input, "del"))
15862         is_add = 0;
15863       else
15864         break;
15865     }
15866
15867   if (sw_if_index == ~0)
15868     {
15869       errmsg ("Interface required but not specified\n");
15870       return -99;
15871     }
15872
15873   if (vrf_set == 0)
15874     {
15875       errmsg ("VRF ID required but not specified\n");
15876       return -99;
15877     }
15878
15879   if (tcp_out_vrf_id == 0
15880       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15881     {
15882       errmsg
15883         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15884       return -99;
15885     }
15886
15887   /* Construct the API message */
15888   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15889      ip_source_and_port_range_check_interface_add_del);
15890
15891   mp->sw_if_index = ntohl (sw_if_index);
15892   mp->is_add = is_add;
15893   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15894   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15895   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15896   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15897
15898   /* send it... */
15899   S;
15900
15901   /* Wait for a reply... */
15902   W;
15903 }
15904
15905 static int
15906 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15907 {
15908   unformat_input_t *i = vam->input;
15909   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15910   f64 timeout;
15911   u32 local_sa_id = 0;
15912   u32 remote_sa_id = 0;
15913   ip4_address_t src_address;
15914   ip4_address_t dst_address;
15915   u8 is_add = 1;
15916
15917   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15918     {
15919       if (unformat (i, "local_sa %d", &local_sa_id))
15920         ;
15921       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15922         ;
15923       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15924         ;
15925       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15926         ;
15927       else if (unformat (i, "del"))
15928         is_add = 0;
15929       else
15930         {
15931           clib_warning ("parse error '%U'", format_unformat_error, i);
15932           return -99;
15933         }
15934     }
15935
15936   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15937
15938   mp->local_sa_id = ntohl (local_sa_id);
15939   mp->remote_sa_id = ntohl (remote_sa_id);
15940   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15941   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15942   mp->is_add = is_add;
15943
15944   S;
15945   W;
15946   /* NOTREACHED */
15947   return 0;
15948 }
15949
15950 static int
15951 api_punt (vat_main_t * vam)
15952 {
15953   unformat_input_t *i = vam->input;
15954   vl_api_punt_t *mp;
15955   f64 timeout;
15956   u32 ipv = ~0;
15957   u32 protocol = ~0;
15958   u32 port = ~0;
15959   int is_add = 1;
15960
15961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15962     {
15963       if (unformat (i, "ip %d", &ipv))
15964         ;
15965       else if (unformat (i, "protocol %d", &protocol))
15966         ;
15967       else if (unformat (i, "port %d", &port))
15968         ;
15969       else if (unformat (i, "del"))
15970         is_add = 0;
15971       else
15972         {
15973           clib_warning ("parse error '%U'", format_unformat_error, i);
15974           return -99;
15975         }
15976     }
15977
15978   M (PUNT, punt);
15979
15980   mp->is_add = (u8) is_add;
15981   mp->ipv = (u8) ipv;
15982   mp->l4_protocol = (u8) protocol;
15983   mp->l4_port = htons ((u16) port);
15984
15985   S;
15986   W;
15987   /* NOTREACHED */
15988   return 0;
15989 }
15990
15991 static void vl_api_ipsec_gre_tunnel_details_t_handler
15992   (vl_api_ipsec_gre_tunnel_details_t * mp)
15993 {
15994   vat_main_t *vam = &vat_main;
15995
15996   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15997            ntohl (mp->sw_if_index),
15998            format_ip4_address, &mp->src_address,
15999            format_ip4_address, &mp->dst_address,
16000            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16001 }
16002
16003 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16004   (vl_api_ipsec_gre_tunnel_details_t * mp)
16005 {
16006   vat_main_t *vam = &vat_main;
16007   vat_json_node_t *node = NULL;
16008   struct in_addr ip4;
16009
16010   if (VAT_JSON_ARRAY != vam->json_tree.type)
16011     {
16012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16013       vat_json_init_array (&vam->json_tree);
16014     }
16015   node = vat_json_array_add (&vam->json_tree);
16016
16017   vat_json_init_object (node);
16018   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16019   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16020   vat_json_object_add_ip4 (node, "src_address", ip4);
16021   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16022   vat_json_object_add_ip4 (node, "dst_address", ip4);
16023   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16024   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16025 }
16026
16027 static int
16028 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16029 {
16030   unformat_input_t *i = vam->input;
16031   vl_api_ipsec_gre_tunnel_dump_t *mp;
16032   f64 timeout;
16033   u32 sw_if_index;
16034   u8 sw_if_index_set = 0;
16035
16036   /* Parse args required to build the message */
16037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16038     {
16039       if (unformat (i, "sw_if_index %d", &sw_if_index))
16040         sw_if_index_set = 1;
16041       else
16042         break;
16043     }
16044
16045   if (sw_if_index_set == 0)
16046     {
16047       sw_if_index = ~0;
16048     }
16049
16050   if (!vam->json_output)
16051     {
16052       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
16053                "sw_if_index", "src_address", "dst_address",
16054                "local_sa_id", "remote_sa_id");
16055     }
16056
16057   /* Get list of gre-tunnel interfaces */
16058   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16059
16060   mp->sw_if_index = htonl (sw_if_index);
16061
16062   S;
16063
16064   /* Use a control ping for synchronization */
16065   {
16066     vl_api_control_ping_t *mp;
16067     M (CONTROL_PING, control_ping);
16068     S;
16069   }
16070   W;
16071 }
16072
16073 static int
16074 api_delete_subif (vat_main_t * vam)
16075 {
16076   unformat_input_t *i = vam->input;
16077   vl_api_delete_subif_t *mp;
16078   f64 timeout;
16079   u32 sw_if_index = ~0;
16080
16081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16082     {
16083       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16084         ;
16085       if (unformat (i, "sw_if_index %d", &sw_if_index))
16086         ;
16087       else
16088         break;
16089     }
16090
16091   if (sw_if_index == ~0)
16092     {
16093       errmsg ("missing sw_if_index\n");
16094       return -99;
16095     }
16096
16097   /* Construct the API message */
16098   M (DELETE_SUBIF, delete_subif);
16099   mp->sw_if_index = ntohl (sw_if_index);
16100
16101   S;
16102   W;
16103 }
16104
16105 #define foreach_pbb_vtr_op      \
16106 _("disable",  L2_VTR_DISABLED)  \
16107 _("pop",  L2_VTR_POP_2)         \
16108 _("push",  L2_VTR_PUSH_2)
16109
16110 static int
16111 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16112 {
16113   unformat_input_t *i = vam->input;
16114   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16115   f64 timeout;
16116   u32 sw_if_index = ~0, vtr_op = ~0;
16117   u16 outer_tag = ~0;
16118   u8 dmac[6], smac[6];
16119   u8 dmac_set = 0, smac_set = 0;
16120   u16 vlanid = 0;
16121   u32 sid = ~0;
16122   u32 tmp;
16123
16124   /* Shut up coverity */
16125   memset (dmac, 0, sizeof (dmac));
16126   memset (smac, 0, sizeof (smac));
16127
16128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16129     {
16130       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16131         ;
16132       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16133         ;
16134       else if (unformat (i, "vtr_op %d", &vtr_op))
16135         ;
16136 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16137       foreach_pbb_vtr_op
16138 #undef _
16139         else if (unformat (i, "translate_pbb_stag"))
16140         {
16141           if (unformat (i, "%d", &tmp))
16142             {
16143               vtr_op = L2_VTR_TRANSLATE_2_1;
16144               outer_tag = tmp;
16145             }
16146           else
16147             {
16148               errmsg
16149                 ("translate_pbb_stag operation requires outer tag definition\n");
16150               return -99;
16151             }
16152         }
16153       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16154         dmac_set++;
16155       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16156         smac_set++;
16157       else if (unformat (i, "sid %d", &sid))
16158         ;
16159       else if (unformat (i, "vlanid %d", &tmp))
16160         vlanid = tmp;
16161       else
16162         {
16163           clib_warning ("parse error '%U'", format_unformat_error, i);
16164           return -99;
16165         }
16166     }
16167
16168   if ((sw_if_index == ~0) || (vtr_op == ~0))
16169     {
16170       errmsg ("missing sw_if_index or vtr operation\n");
16171       return -99;
16172     }
16173   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16174       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16175     {
16176       errmsg
16177         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
16178       return -99;
16179     }
16180
16181   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16182   mp->sw_if_index = ntohl (sw_if_index);
16183   mp->vtr_op = ntohl (vtr_op);
16184   mp->outer_tag = ntohs (outer_tag);
16185   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16186   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16187   mp->b_vlanid = ntohs (vlanid);
16188   mp->i_sid = ntohl (sid);
16189
16190   S;
16191   W;
16192   /* NOTREACHED */
16193   return 0;
16194 }
16195
16196 static int
16197 api_flow_classify_set_interface (vat_main_t * vam)
16198 {
16199   unformat_input_t *i = vam->input;
16200   vl_api_flow_classify_set_interface_t *mp;
16201   f64 timeout;
16202   u32 sw_if_index;
16203   int sw_if_index_set;
16204   u32 ip4_table_index = ~0;
16205   u32 ip6_table_index = ~0;
16206   u8 is_add = 1;
16207
16208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16209     {
16210       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16211         sw_if_index_set = 1;
16212       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16213         sw_if_index_set = 1;
16214       else if (unformat (i, "del"))
16215         is_add = 0;
16216       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16217         ;
16218       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16219         ;
16220       else
16221         {
16222           clib_warning ("parse error '%U'", format_unformat_error, i);
16223           return -99;
16224         }
16225     }
16226
16227   if (sw_if_index_set == 0)
16228     {
16229       errmsg ("missing interface name or sw_if_index\n");
16230       return -99;
16231     }
16232
16233   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16234
16235   mp->sw_if_index = ntohl (sw_if_index);
16236   mp->ip4_table_index = ntohl (ip4_table_index);
16237   mp->ip6_table_index = ntohl (ip6_table_index);
16238   mp->is_add = is_add;
16239
16240   S;
16241   W;
16242   /* NOTREACHED */
16243   return 0;
16244 }
16245
16246 static int
16247 api_flow_classify_dump (vat_main_t * vam)
16248 {
16249   unformat_input_t *i = vam->input;
16250   vl_api_flow_classify_dump_t *mp;
16251   f64 timeout = ~0;
16252   u8 type = FLOW_CLASSIFY_N_TABLES;
16253
16254   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16255     ;
16256   else
16257     {
16258       errmsg ("classify table type must be specified\n");
16259       return -99;
16260     }
16261
16262   if (!vam->json_output)
16263     {
16264       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
16265     }
16266
16267   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16268   mp->type = type;
16269   /* send it... */
16270   S;
16271
16272   /* Use a control ping for synchronization */
16273   {
16274     vl_api_control_ping_t *mp;
16275     M (CONTROL_PING, control_ping);
16276     S;
16277   }
16278   /* Wait for a reply... */
16279   W;
16280
16281   /* NOTREACHED */
16282   return 0;
16283 }
16284
16285 static int
16286 api_feature_enable_disable (vat_main_t * vam)
16287 {
16288   unformat_input_t *i = vam->input;
16289   vl_api_feature_enable_disable_t *mp;
16290   f64 timeout;
16291   u8 *arc_name = 0;
16292   u8 *feature_name = 0;
16293   u32 sw_if_index = ~0;
16294   u8 enable = 1;
16295
16296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16297     {
16298       if (unformat (i, "arc_name %s", &arc_name))
16299         ;
16300       else if (unformat (i, "feature_name %s", &feature_name))
16301         ;
16302       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16303         ;
16304       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16305         ;
16306       else if (unformat (i, "disable"))
16307         enable = 0;
16308       else
16309         break;
16310     }
16311
16312   if (arc_name == 0)
16313     {
16314       errmsg ("missing arc name\n");
16315       return -99;
16316     }
16317   if (vec_len (arc_name) > 63)
16318     {
16319       errmsg ("arc name too long\n");
16320     }
16321
16322   if (feature_name == 0)
16323     {
16324       errmsg ("missing feature name\n");
16325       return -99;
16326     }
16327   if (vec_len (feature_name) > 63)
16328     {
16329       errmsg ("feature name too long\n");
16330     }
16331
16332   if (sw_if_index == ~0)
16333     {
16334       errmsg ("missing interface name or sw_if_index\n");
16335       return -99;
16336     }
16337
16338   /* Construct the API message */
16339   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16340   mp->sw_if_index = ntohl (sw_if_index);
16341   mp->enable = enable;
16342   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16343   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16344   vec_free (arc_name);
16345   vec_free (feature_name);
16346
16347   S;
16348   W;
16349 }
16350
16351 static int
16352 q_or_quit (vat_main_t * vam)
16353 {
16354   longjmp (vam->jump_buf, 1);
16355   return 0;                     /* not so much */
16356 }
16357
16358 static int
16359 q (vat_main_t * vam)
16360 {
16361   return q_or_quit (vam);
16362 }
16363
16364 static int
16365 quit (vat_main_t * vam)
16366 {
16367   return q_or_quit (vam);
16368 }
16369
16370 static int
16371 comment (vat_main_t * vam)
16372 {
16373   return 0;
16374 }
16375
16376 static int
16377 cmd_cmp (void *a1, void *a2)
16378 {
16379   u8 **c1 = a1;
16380   u8 **c2 = a2;
16381
16382   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
16383 }
16384
16385 static int
16386 help (vat_main_t * vam)
16387 {
16388   u8 **cmds = 0;
16389   u8 *name = 0;
16390   hash_pair_t *p;
16391   unformat_input_t *i = vam->input;
16392   int j;
16393
16394   if (unformat (i, "%s", &name))
16395     {
16396       uword *hs;
16397
16398       vec_add1 (name, 0);
16399
16400       hs = hash_get_mem (vam->help_by_name, name);
16401       if (hs)
16402         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
16403       else
16404         fformat (vam->ofp, "No such msg / command '%s'\n", name);
16405       vec_free (name);
16406       return 0;
16407     }
16408
16409   fformat (vam->ofp, "Help is available for the following:\n");
16410
16411     /* *INDENT-OFF* */
16412     hash_foreach_pair (p, vam->function_by_name,
16413     ({
16414       vec_add1 (cmds, (u8 *)(p->key));
16415     }));
16416     /* *INDENT-ON* */
16417
16418   vec_sort_with_function (cmds, cmd_cmp);
16419
16420   for (j = 0; j < vec_len (cmds); j++)
16421     fformat (vam->ofp, "%s\n", cmds[j]);
16422
16423   vec_free (cmds);
16424   return 0;
16425 }
16426
16427 static int
16428 set (vat_main_t * vam)
16429 {
16430   u8 *name = 0, *value = 0;
16431   unformat_input_t *i = vam->input;
16432
16433   if (unformat (i, "%s", &name))
16434     {
16435       /* The input buffer is a vector, not a string. */
16436       value = vec_dup (i->buffer);
16437       vec_delete (value, i->index, 0);
16438       /* Almost certainly has a trailing newline */
16439       if (value[vec_len (value) - 1] == '\n')
16440         value[vec_len (value) - 1] = 0;
16441       /* Make sure it's a proper string, one way or the other */
16442       vec_add1 (value, 0);
16443       (void) clib_macro_set_value (&vam->macro_main,
16444                                    (char *) name, (char *) value);
16445     }
16446   else
16447     errmsg ("usage: set <name> <value>\n");
16448
16449   vec_free (name);
16450   vec_free (value);
16451   return 0;
16452 }
16453
16454 static int
16455 unset (vat_main_t * vam)
16456 {
16457   u8 *name = 0;
16458
16459   if (unformat (vam->input, "%s", &name))
16460     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
16461       errmsg ("unset: %s wasn't set\n", name);
16462   vec_free (name);
16463   return 0;
16464 }
16465
16466 typedef struct
16467 {
16468   u8 *name;
16469   u8 *value;
16470 } macro_sort_t;
16471
16472
16473 static int
16474 macro_sort_cmp (void *a1, void *a2)
16475 {
16476   macro_sort_t *s1 = a1;
16477   macro_sort_t *s2 = a2;
16478
16479   return strcmp ((char *) (s1->name), (char *) (s2->name));
16480 }
16481
16482 static int
16483 dump_macro_table (vat_main_t * vam)
16484 {
16485   macro_sort_t *sort_me = 0, *sm;
16486   int i;
16487   hash_pair_t *p;
16488
16489     /* *INDENT-OFF* */
16490     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
16491     ({
16492       vec_add2 (sort_me, sm, 1);
16493       sm->name = (u8 *)(p->key);
16494       sm->value = (u8 *) (p->value[0]);
16495     }));
16496     /* *INDENT-ON* */
16497
16498   vec_sort_with_function (sort_me, macro_sort_cmp);
16499
16500   if (vec_len (sort_me))
16501     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
16502   else
16503     fformat (vam->ofp, "The macro table is empty...\n");
16504
16505   for (i = 0; i < vec_len (sort_me); i++)
16506     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
16507   return 0;
16508 }
16509
16510 static int
16511 dump_node_table (vat_main_t * vam)
16512 {
16513   int i, j;
16514   vlib_node_t *node, *next_node;
16515
16516   if (vec_len (vam->graph_nodes) == 0)
16517     {
16518       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16519       return 0;
16520     }
16521
16522   for (i = 0; i < vec_len (vam->graph_nodes); i++)
16523     {
16524       node = vam->graph_nodes[i];
16525       fformat (vam->ofp, "[%d] %s\n", i, node->name);
16526       for (j = 0; j < vec_len (node->next_nodes); j++)
16527         {
16528           if (node->next_nodes[j] != ~0)
16529             {
16530               next_node = vam->graph_nodes[node->next_nodes[j]];
16531               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16532             }
16533         }
16534     }
16535   return 0;
16536 }
16537
16538 static int
16539 value_sort_cmp (void *a1, void *a2)
16540 {
16541   name_sort_t *n1 = a1;
16542   name_sort_t *n2 = a2;
16543
16544   if (n1->value < n2->value)
16545     return -1;
16546   if (n1->value > n2->value)
16547     return 1;
16548   return 0;
16549 }
16550
16551
16552 static int
16553 dump_msg_api_table (vat_main_t * vam)
16554 {
16555   api_main_t *am = &api_main;
16556   name_sort_t *nses = 0, *ns;
16557   hash_pair_t *hp;
16558   int i;
16559
16560   /* *INDENT-OFF* */
16561   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
16562   ({
16563     vec_add2 (nses, ns, 1);
16564     ns->name = (u8 *)(hp->key);
16565     ns->value = (u32) hp->value[0];
16566   }));
16567   /* *INDENT-ON* */
16568
16569   vec_sort_with_function (nses, value_sort_cmp);
16570
16571   for (i = 0; i < vec_len (nses); i++)
16572     fformat (vam->ofp, " [%d]: %s\n", nses[i].value, nses[i].name);
16573   vec_free (nses);
16574   return 0;
16575 }
16576
16577 static int
16578 get_msg_id (vat_main_t * vam)
16579 {
16580   u8 *name_and_crc;
16581   u32 message_index;
16582
16583   if (unformat (vam->input, "%s", &name_and_crc))
16584     {
16585       message_index = vl_api_get_msg_index (name_and_crc);
16586       if (message_index == ~0)
16587         {
16588           fformat (vam->ofp, " '%s' not found\n", name_and_crc);
16589           return 0;
16590         }
16591       fformat (vam->ofp, " '%s' has message index %d\n",
16592                name_and_crc, message_index);
16593       return 0;
16594     }
16595   errmsg ("name_and_crc required...\n");
16596   return 0;
16597 }
16598
16599 static int
16600 search_node_table (vat_main_t * vam)
16601 {
16602   unformat_input_t *line_input = vam->input;
16603   u8 *node_to_find;
16604   int j;
16605   vlib_node_t *node, *next_node;
16606   uword *p;
16607
16608   if (vam->graph_node_index_by_name == 0)
16609     {
16610       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16611       return 0;
16612     }
16613
16614   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16615     {
16616       if (unformat (line_input, "%s", &node_to_find))
16617         {
16618           vec_add1 (node_to_find, 0);
16619           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
16620           if (p == 0)
16621             {
16622               fformat (vam->ofp, "%s not found...\n", node_to_find);
16623               goto out;
16624             }
16625           node = vam->graph_nodes[p[0]];
16626           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
16627           for (j = 0; j < vec_len (node->next_nodes); j++)
16628             {
16629               if (node->next_nodes[j] != ~0)
16630                 {
16631                   next_node = vam->graph_nodes[node->next_nodes[j]];
16632                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16633                 }
16634             }
16635         }
16636
16637       else
16638         {
16639           clib_warning ("parse error '%U'", format_unformat_error,
16640                         line_input);
16641           return -99;
16642         }
16643
16644     out:
16645       vec_free (node_to_find);
16646
16647     }
16648
16649   return 0;
16650 }
16651
16652
16653 static int
16654 script (vat_main_t * vam)
16655 {
16656   u8 *s = 0;
16657   char *save_current_file;
16658   unformat_input_t save_input;
16659   jmp_buf save_jump_buf;
16660   u32 save_line_number;
16661
16662   FILE *new_fp, *save_ifp;
16663
16664   if (unformat (vam->input, "%s", &s))
16665     {
16666       new_fp = fopen ((char *) s, "r");
16667       if (new_fp == 0)
16668         {
16669           errmsg ("Couldn't open script file %s\n", s);
16670           vec_free (s);
16671           return -99;
16672         }
16673     }
16674   else
16675     {
16676       errmsg ("Missing script name\n");
16677       return -99;
16678     }
16679
16680   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
16681   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
16682   save_ifp = vam->ifp;
16683   save_line_number = vam->input_line_number;
16684   save_current_file = (char *) vam->current_file;
16685
16686   vam->input_line_number = 0;
16687   vam->ifp = new_fp;
16688   vam->current_file = s;
16689   do_one_file (vam);
16690
16691   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
16692   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
16693   vam->ifp = save_ifp;
16694   vam->input_line_number = save_line_number;
16695   vam->current_file = (u8 *) save_current_file;
16696   vec_free (s);
16697
16698   return 0;
16699 }
16700
16701 static int
16702 echo (vat_main_t * vam)
16703 {
16704   fformat (vam->ofp, "%v", vam->input->buffer);
16705   return 0;
16706 }
16707
16708 /* List of API message constructors, CLI names map to api_xxx */
16709 #define foreach_vpe_api_msg                                             \
16710 _(create_loopback,"[mac <mac-addr>]")                                   \
16711 _(sw_interface_dump,"")                                                 \
16712 _(sw_interface_set_flags,                                               \
16713   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
16714 _(sw_interface_add_del_address,                                         \
16715   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
16716 _(sw_interface_set_table,                                               \
16717   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
16718 _(sw_interface_set_mpls_enable,                                                \
16719   "<intfc> | sw_if_index [disable | dis]")                                \
16720 _(sw_interface_set_vpath,                                               \
16721   "<intfc> | sw_if_index <id> enable | disable")                        \
16722 _(sw_interface_set_l2_xconnect,                                         \
16723   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16724   "enable | disable")                                                   \
16725 _(sw_interface_set_l2_bridge,                                           \
16726   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
16727   "[shg <split-horizon-group>] [bvi]\n"                                 \
16728   "enable | disable")                                                   \
16729 _(sw_interface_set_dpdk_hqos_pipe,                                      \
16730   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
16731   "profile <profile-id>\n")                                             \
16732 _(sw_interface_set_dpdk_hqos_subport,                                   \
16733   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
16734   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
16735 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
16736   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
16737 _(bridge_domain_add_del,                                                \
16738   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
16739 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
16740 _(l2fib_add_del,                                                        \
16741   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
16742 _(l2_flags,                                                             \
16743   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
16744 _(bridge_flags,                                                         \
16745   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
16746 _(tap_connect,                                                          \
16747   "tapname <name> mac <mac-addr> | random-mac")                         \
16748 _(tap_modify,                                                           \
16749   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
16750 _(tap_delete,                                                           \
16751   "<vpp-if-name> | sw_if_index <id>")                                   \
16752 _(sw_interface_tap_dump, "")                                            \
16753 _(ip_add_del_route,                                                     \
16754   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
16755   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16756   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16757   "[multipath] [count <n>]")                                            \
16758 _(mpls_route_add_del,                                                   \
16759   "<label> <eos> via <addr> [table-id <n>]\n"                           \
16760   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16761   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16762   "[multipath] [count <n>]")                                            \
16763 _(mpls_ip_bind_unbind,                                                  \
16764   "<label> <addr/len>")                                                 \
16765 _(proxy_arp_add_del,                                                    \
16766   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
16767 _(proxy_arp_intfc_enable_disable,                                       \
16768   "<intfc> | sw_if_index <id> enable | disable")                        \
16769 _(mpls_add_del_encap,                                                   \
16770   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
16771 _(sw_interface_set_unnumbered,                                          \
16772   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
16773 _(ip_neighbor_add_del,                                                  \
16774   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
16775   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
16776 _(reset_vrf, "vrf <id> [ipv6]")                                         \
16777 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
16778 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
16779   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
16780   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
16781   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
16782 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
16783 _(reset_fib, "vrf <n> [ipv6]")                                          \
16784 _(dhcp_proxy_config,                                                    \
16785   "svr <v46-address> src <v46-address>\n"                               \
16786    "insert-cid <n> [del]")                                              \
16787 _(dhcp_proxy_config_2,                                                  \
16788   "svr <v46-address> src <v46-address>\n"                               \
16789    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
16790 _(dhcp_proxy_set_vss,                                                   \
16791   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
16792 _(dhcp_client_config,                                                   \
16793   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
16794 _(set_ip_flow_hash,                                                     \
16795   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
16796 _(sw_interface_ip6_enable_disable,                                      \
16797   "<intfc> | sw_if_index <id> enable | disable")                        \
16798 _(sw_interface_ip6_set_link_local_address,                              \
16799   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
16800 _(sw_interface_ip6nd_ra_prefix,                                         \
16801   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
16802   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
16803   "[nolink] [isno]")                                                    \
16804 _(sw_interface_ip6nd_ra_config,                                         \
16805   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
16806   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
16807   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
16808 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
16809 _(l2_patch_add_del,                                                     \
16810   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16811   "enable | disable")                                                   \
16812 _(mpls_ethernet_add_del_tunnel,                                         \
16813   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
16814   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
16815 _(mpls_ethernet_add_del_tunnel_2,                                       \
16816   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
16817   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
16818 _(sr_tunnel_add_del,                                                    \
16819   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
16820   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
16821   "[policy <policy_name>]")                                             \
16822 _(sr_policy_add_del,                                                    \
16823   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
16824 _(sr_multicast_map_add_del,                                             \
16825   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
16826 _(classify_add_del_table,                                               \
16827   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
16828   " [del] mask <mask-value>\n"                                          \
16829   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
16830   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
16831 _(classify_add_del_session,                                             \
16832   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
16833   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
16834   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
16835   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
16836 _(classify_set_interface_ip_table,                                      \
16837   "<intfc> | sw_if_index <nn> table <nn>")                              \
16838 _(classify_set_interface_l2_tables,                                     \
16839   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16840   "  [other-table <nn>]")                                               \
16841 _(get_node_index, "node <node-name")                                    \
16842 _(add_node_next, "node <node-name> next <next-node-name>")              \
16843 _(l2tpv3_create_tunnel,                                                 \
16844   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
16845   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
16846   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
16847 _(l2tpv3_set_tunnel_cookies,                                            \
16848   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
16849   "[new_remote_cookie <nn>]\n")                                         \
16850 _(l2tpv3_interface_enable_disable,                                      \
16851   "<intfc> | sw_if_index <nn> enable | disable")                        \
16852 _(l2tpv3_set_lookup_key,                                                \
16853   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
16854 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
16855 _(vxlan_add_del_tunnel,                                                 \
16856   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
16857   " [decap-next l2|ip4|ip6] [del]")                                     \
16858 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
16859 _(gre_add_del_tunnel,                                                   \
16860   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
16861 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
16862 _(l2_fib_clear_table, "")                                               \
16863 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
16864 _(l2_interface_vlan_tag_rewrite,                                        \
16865   "<intfc> | sw_if_index <nn> \n"                                       \
16866   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
16867   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
16868 _(create_vhost_user_if,                                                 \
16869         "socket <filename> [server] [renumber <dev_instance>] "         \
16870         "[mac <mac_address>]")                                          \
16871 _(modify_vhost_user_if,                                                 \
16872         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
16873         "[server] [renumber <dev_instance>]")                           \
16874 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
16875 _(sw_interface_vhost_user_dump, "")                                     \
16876 _(show_version, "")                                                     \
16877 _(vxlan_gpe_add_del_tunnel,                                             \
16878   "local <addr> remote <addr> vni <nn>\n"                               \
16879     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
16880   "[next-ethernet] [next-nsh]\n")                                       \
16881 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
16882 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
16883 _(interface_name_renumber,                                              \
16884   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
16885 _(input_acl_set_interface,                                              \
16886   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16887   "  [l2-table <nn>] [del]")                                            \
16888 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
16889 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
16890 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
16891 _(ip_dump, "ipv4 | ipv6")                                               \
16892 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
16893 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
16894   "  spid_id <n> ")                                                     \
16895 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
16896   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
16897   "  integ_alg <alg> integ_key <hex>")                                  \
16898 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
16899   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
16900   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
16901   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
16902 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
16903 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
16904 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
16905   "(auth_data 0x<data> | auth_data <data>)")                            \
16906 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
16907   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
16908 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
16909   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
16910   "(local|remote)")                                                     \
16911 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
16912 _(delete_loopback,"sw_if_index <nn>")                                   \
16913 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
16914 _(map_add_domain,                                                       \
16915   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16916   "ip6-src <ip6addr> "                                                  \
16917   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16918 _(map_del_domain, "index <n>")                                          \
16919 _(map_add_del_rule,                                                     \
16920   "index <n> psid <n> dst <ip6addr> [del]")                             \
16921 _(map_domain_dump, "")                                                  \
16922 _(map_rule_dump, "index <map-domain>")                                  \
16923 _(want_interface_events,  "enable|disable")                             \
16924 _(want_stats,"enable|disable")                                          \
16925 _(get_first_msg_id, "client <name>")                                    \
16926 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16927 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16928   "fib-id <nn> [ip4][ip6][default]")                                    \
16929 _(get_node_graph, " ")                                                  \
16930 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16931 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16932 _(ioam_disable, "")                                                \
16933 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16934                             " sw_if_index <sw_if_index> p <priority> "  \
16935                             "w <weight>] [del]")                        \
16936 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16937                         "iface <intf> | sw_if_index <sw_if_index> "     \
16938                         "p <priority> w <weight> [del]")                \
16939 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16940                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16941                           "locator-set <locator_name> [del]")           \
16942 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16943   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16944 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16945 _(lisp_gpe_enable_disable, "enable|disable")                            \
16946 _(lisp_enable_disable, "enable|disable")                                \
16947 _(lisp_gpe_add_del_iface, "up|down")                                    \
16948 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
16949                                "[seid <seid>] "                         \
16950                                "rloc <locator> p <prio> "               \
16951                                "w <weight> [rloc <loc> ... ] "          \
16952                                "action <action> [del-all]")             \
16953 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
16954                           "<local-eid>")                                \
16955 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
16956 _(lisp_map_request_mode, "src-dst|dst-only")                            \
16957 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
16958 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
16959 _(lisp_locator_set_dump, "[local | remote]")                            \
16960 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
16961 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
16962                        "[local] | [remote]")                            \
16963 _(lisp_eid_table_vni_dump, "")                                          \
16964 _(lisp_eid_table_map_dump, "l2|l3")                                     \
16965 _(lisp_gpe_tunnel_dump, "")                                             \
16966 _(lisp_map_resolver_dump, "")                                           \
16967 _(lisp_adjacencies_get, "vni <vni>")                                    \
16968 _(show_lisp_status, "")                                                 \
16969 _(lisp_get_map_request_itr_rlocs, "")                                   \
16970 _(show_lisp_pitr, "")                                                   \
16971 _(show_lisp_map_request_mode, "")                                       \
16972 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
16973 _(af_packet_delete, "name <host interface name>")                       \
16974 _(policer_add_del, "name <policer name> <params> [del]")                \
16975 _(policer_dump, "[name <policer name>]")                                \
16976 _(policer_classify_set_interface,                                       \
16977   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16978   "  [l2-table <nn>] [del]")                                            \
16979 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
16980 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
16981     "[master|slave]")                                                   \
16982 _(netmap_delete, "name <interface name>")                               \
16983 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16984 _(mpls_fib_encap_dump, "")                                              \
16985 _(mpls_fib_dump, "")                                                    \
16986 _(classify_table_ids, "")                                               \
16987 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
16988 _(classify_table_info, "table_id <nn>")                                 \
16989 _(classify_session_dump, "table_id <nn>")                               \
16990 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
16991     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
16992     "[template_interval <nn>] [udp_checksum]")                          \
16993 _(ipfix_exporter_dump, "")                                              \
16994 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
16995 _(ipfix_classify_stream_dump, "")                                       \
16996 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
16997 _(ipfix_classify_table_dump, "")                                        \
16998 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [[dst <intfc> | dst_sw_if_index <id>] | disable]") \
16999 _(sw_interface_span_dump, "")                                           \
17000 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
17001 _(pg_create_interface, "if_id <nn>")                                    \
17002 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
17003 _(pg_enable_disable, "[stream <id>] disable")                           \
17004 _(ip_source_and_port_range_check_add_del,                               \
17005   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
17006 _(ip_source_and_port_range_check_interface_add_del,                     \
17007   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
17008   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
17009 _(ipsec_gre_add_del_tunnel,                                             \
17010   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
17011 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
17012 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
17013 _(l2_interface_pbb_tag_rewrite,                                         \
17014   "<intfc> | sw_if_index <nn> \n"                                       \
17015   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
17016   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
17017 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
17018 _(flow_classify_set_interface,                                          \
17019   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17020 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17021 _(ip_fib_dump, "")                                                      \
17022 _(ip6_fib_dump, "")                                                     \
17023 _(feature_enable_disable, "arc_name <arc_name> "                        \
17024   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")
17025
17026 /* List of command functions, CLI names map directly to functions */
17027 #define foreach_cli_function                                    \
17028 _(comment, "usage: comment <ignore-rest-of-line>")              \
17029 _(dump_interface_table, "usage: dump_interface_table")          \
17030 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17031 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17032 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17033 _(dump_stats_table, "usage: dump_stats_table")                  \
17034 _(dump_macro_table, "usage: dump_macro_table ")                 \
17035 _(dump_node_table, "usage: dump_node_table")                    \
17036 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17037 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17038 _(echo, "usage: echo <message>")                                \
17039 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17040 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17041 _(help, "usage: help")                                          \
17042 _(q, "usage: quit")                                             \
17043 _(quit, "usage: quit")                                          \
17044 _(search_node_table, "usage: search_node_table <name>...")      \
17045 _(set, "usage: set <variable-name> <value>")                    \
17046 _(script, "usage: script <file-name>")                          \
17047 _(unset, "usage: unset <variable-name>")
17048
17049 #define _(N,n)                                  \
17050     static void vl_api_##n##_t_handler_uni      \
17051     (vl_api_##n##_t * mp)                       \
17052     {                                           \
17053         vat_main_t * vam = &vat_main;           \
17054         if (vam->json_output) {                 \
17055             vl_api_##n##_t_handler_json(mp);    \
17056         } else {                                \
17057             vl_api_##n##_t_handler(mp);         \
17058         }                                       \
17059     }
17060 foreach_vpe_api_reply_msg;
17061 #undef _
17062
17063 void
17064 vat_api_hookup (vat_main_t * vam)
17065 {
17066 #define _(N,n)                                                  \
17067     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17068                            vl_api_##n##_t_handler_uni,          \
17069                            vl_noop_handler,                     \
17070                            vl_api_##n##_t_endian,               \
17071                            vl_api_##n##_t_print,                \
17072                            sizeof(vl_api_##n##_t), 1);
17073   foreach_vpe_api_reply_msg;
17074 #undef _
17075
17076   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17077
17078   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17079
17080   vam->function_by_name = hash_create_string (0, sizeof (uword));
17081
17082   vam->help_by_name = hash_create_string (0, sizeof (uword));
17083
17084   /* API messages we can send */
17085 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17086   foreach_vpe_api_msg;
17087 #undef _
17088
17089   /* Help strings */
17090 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17091   foreach_vpe_api_msg;
17092 #undef _
17093
17094   /* CLI functions */
17095 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17096   foreach_cli_function;
17097 #undef _
17098
17099   /* Help strings */
17100 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17101   foreach_cli_function;
17102 #undef _
17103 }
17104
17105 #undef vl_api_version
17106 #define vl_api_version(n,v) static u32 vpe_api_version = v;
17107 #include <vpp-api/vpe.api.h>
17108 #undef vl_api_version
17109
17110 void
17111 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
17112 {
17113   /*
17114    * Send the main API signature in slot 0. This bit of code must
17115    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
17116    */
17117   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
17118 }
17119
17120 /*
17121  * fd.io coding-style-patch-verification: ON
17122  *
17123  * Local Variables:
17124  * eval: (c-set-style "gnu")
17125  * End:
17126  */