api: missing support for dumping of neighbours (VPP-333)
[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 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248   u32 *r = va_arg (*args, u32 *);
249
250   if (0);
251 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
252   foreach_ipsec_policy_action
253 #undef _
254     else
255     return 0;
256   return 1;
257 }
258
259 uword
260 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
261 {
262   u32 *r = va_arg (*args, u32 *);
263
264   if (0);
265 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
266   foreach_ipsec_crypto_alg
267 #undef _
268     else
269     return 0;
270   return 1;
271 }
272
273 u8 *
274 format_ipsec_crypto_alg (u8 * s, va_list * args)
275 {
276   u32 i = va_arg (*args, u32);
277   u8 *t = 0;
278
279   switch (i)
280     {
281 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
282       foreach_ipsec_crypto_alg
283 #undef _
284     default:
285       return format (s, "unknown");
286     }
287   return format (s, "%s", t);
288 }
289
290 uword
291 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
292 {
293   u32 *r = va_arg (*args, u32 *);
294
295   if (0);
296 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
297   foreach_ipsec_integ_alg
298 #undef _
299     else
300     return 0;
301   return 1;
302 }
303
304 u8 *
305 format_ipsec_integ_alg (u8 * s, va_list * args)
306 {
307   u32 i = va_arg (*args, u32);
308   u8 *t = 0;
309
310   switch (i)
311     {
312 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
313       foreach_ipsec_integ_alg
314 #undef _
315     default:
316       return format (s, "unknown");
317     }
318   return format (s, "%s", t);
319 }
320
321 uword
322 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
323 {
324   u32 *r = va_arg (*args, u32 *);
325
326   if (0);
327 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
328   foreach_ikev2_auth_method
329 #undef _
330     else
331     return 0;
332   return 1;
333 }
334
335 uword
336 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
337 {
338   u32 *r = va_arg (*args, u32 *);
339
340   if (0);
341 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
342   foreach_ikev2_id_type
343 #undef _
344     else
345     return 0;
346   return 1;
347 }
348
349 uword
350 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
351 {
352   u8 *r = va_arg (*args, u8 *);
353
354   if (unformat (input, "kbps"))
355     *r = SSE2_QOS_RATE_KBPS;
356   else if (unformat (input, "pps"))
357     *r = SSE2_QOS_RATE_PPS;
358   else
359     return 0;
360   return 1;
361 }
362
363 uword
364 unformat_policer_round_type (unformat_input_t * input, va_list * args)
365 {
366   u8 *r = va_arg (*args, u8 *);
367
368   if (unformat (input, "closest"))
369     *r = SSE2_QOS_ROUND_TO_CLOSEST;
370   else if (unformat (input, "up"))
371     *r = SSE2_QOS_ROUND_TO_UP;
372   else if (unformat (input, "down"))
373     *r = SSE2_QOS_ROUND_TO_DOWN;
374   else
375     return 0;
376   return 1;
377 }
378
379 uword
380 unformat_policer_type (unformat_input_t * input, va_list * args)
381 {
382   u8 *r = va_arg (*args, u8 *);
383
384   if (unformat (input, "1r2c"))
385     *r = SSE2_QOS_POLICER_TYPE_1R2C;
386   else if (unformat (input, "1r3c"))
387     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
388   else if (unformat (input, "2r3c-2698"))
389     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
390   else if (unformat (input, "2r3c-4115"))
391     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
392   else if (unformat (input, "2r3c-mef5cf1"))
393     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
394   else
395     return 0;
396   return 1;
397 }
398
399 uword
400 unformat_dscp (unformat_input_t * input, va_list * va)
401 {
402   u8 *r = va_arg (*va, u8 *);
403
404   if (0);
405 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
406   foreach_vnet_dscp
407 #undef _
408     else
409     return 0;
410   return 1;
411 }
412
413 uword
414 unformat_policer_action_type (unformat_input_t * input, va_list * va)
415 {
416   sse2_qos_pol_action_params_st *a
417     = va_arg (*va, sse2_qos_pol_action_params_st *);
418
419   if (unformat (input, "drop"))
420     a->action_type = SSE2_QOS_ACTION_DROP;
421   else if (unformat (input, "transmit"))
422     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
423   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
424     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
425   else
426     return 0;
427   return 1;
428 }
429
430 uword
431 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
432 {
433   u32 *r = va_arg (*va, u32 *);
434   u32 tid;
435
436   if (unformat (input, "ip4"))
437     tid = POLICER_CLASSIFY_TABLE_IP4;
438   else if (unformat (input, "ip6"))
439     tid = POLICER_CLASSIFY_TABLE_IP6;
440   else if (unformat (input, "l2"))
441     tid = POLICER_CLASSIFY_TABLE_L2;
442   else
443     return 0;
444
445   *r = tid;
446   return 1;
447 }
448
449 uword
450 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
451 {
452   u32 *r = va_arg (*va, u32 *);
453   u32 tid;
454
455   if (unformat (input, "ip4"))
456     tid = FLOW_CLASSIFY_TABLE_IP4;
457   else if (unformat (input, "ip6"))
458     tid = FLOW_CLASSIFY_TABLE_IP6;
459   else
460     return 0;
461
462   *r = tid;
463   return 1;
464 }
465
466 u8 *
467 format_ip4_address (u8 * s, va_list * args)
468 {
469   u8 *a = va_arg (*args, u8 *);
470   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
471 }
472
473 u8 *
474 format_ip6_address (u8 * s, va_list * args)
475 {
476   ip6_address_t *a = va_arg (*args, ip6_address_t *);
477   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
478
479   i_max_n_zero = ARRAY_LEN (a->as_u16);
480   max_n_zeros = 0;
481   i_first_zero = i_max_n_zero;
482   n_zeros = 0;
483   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
484     {
485       u32 is_zero = a->as_u16[i] == 0;
486       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
487         {
488           i_first_zero = i;
489           n_zeros = 0;
490         }
491       n_zeros += is_zero;
492       if ((!is_zero && n_zeros > max_n_zeros)
493           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
494         {
495           i_max_n_zero = i_first_zero;
496           max_n_zeros = n_zeros;
497           i_first_zero = ARRAY_LEN (a->as_u16);
498           n_zeros = 0;
499         }
500     }
501
502   last_double_colon = 0;
503   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
504     {
505       if (i == i_max_n_zero && max_n_zeros > 1)
506         {
507           s = format (s, "::");
508           i += max_n_zeros - 1;
509           last_double_colon = 1;
510         }
511       else
512         {
513           s = format (s, "%s%x",
514                       (last_double_colon || i == 0) ? "" : ":",
515                       clib_net_to_host_u16 (a->as_u16[i]));
516           last_double_colon = 0;
517         }
518     }
519
520   return s;
521 }
522
523 /* Format an IP46 address. */
524 u8 *
525 format_ip46_address (u8 * s, va_list * args)
526 {
527   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
528   ip46_type_t type = va_arg (*args, ip46_type_t);
529   int is_ip4 = 1;
530
531   switch (type)
532     {
533     case IP46_TYPE_ANY:
534       is_ip4 = ip46_address_is_ip4 (ip46);
535       break;
536     case IP46_TYPE_IP4:
537       is_ip4 = 1;
538       break;
539     case IP46_TYPE_IP6:
540       is_ip4 = 0;
541       break;
542     }
543
544   return is_ip4 ?
545     format (s, "%U", format_ip4_address, &ip46->ip4) :
546     format (s, "%U", format_ip6_address, &ip46->ip6);
547 }
548
549 u8 *
550 format_ethernet_address (u8 * s, va_list * args)
551 {
552   u8 *a = va_arg (*args, u8 *);
553
554   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
555                  a[0], a[1], a[2], a[3], a[4], a[5]);
556 }
557
558 void
559 increment_v4_address (ip4_address_t * a)
560 {
561   u32 v;
562
563   v = ntohl (a->as_u32) + 1;
564   a->as_u32 = ntohl (v);
565 }
566
567 void
568 increment_v6_address (ip6_address_t * a)
569 {
570   u64 v0, v1;
571
572   v0 = clib_net_to_host_u64 (a->as_u64[0]);
573   v1 = clib_net_to_host_u64 (a->as_u64[1]);
574
575   v1 += 1;
576   if (v1 == 0)
577     v0 += 1;
578   a->as_u64[0] = clib_net_to_host_u64 (v0);
579   a->as_u64[1] = clib_net_to_host_u64 (v1);
580 }
581
582 void
583 increment_mac_address (u64 * mac)
584 {
585   u64 tmp = *mac;
586
587   tmp = clib_net_to_host_u64 (tmp);
588   tmp += 1 << 16;               /* skip unused (least significant) octets */
589   tmp = clib_host_to_net_u64 (tmp);
590   *mac = tmp;
591 }
592
593 static void vl_api_create_loopback_reply_t_handler
594   (vl_api_create_loopback_reply_t * mp)
595 {
596   vat_main_t *vam = &vat_main;
597   i32 retval = ntohl (mp->retval);
598
599   vam->retval = retval;
600   vam->regenerate_interface_table = 1;
601   vam->sw_if_index = ntohl (mp->sw_if_index);
602   vam->result_ready = 1;
603 }
604
605 static void vl_api_create_loopback_reply_t_handler_json
606   (vl_api_create_loopback_reply_t * mp)
607 {
608   vat_main_t *vam = &vat_main;
609   vat_json_node_t node;
610
611   vat_json_init_object (&node);
612   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
613   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
614
615   vat_json_print (vam->ofp, &node);
616   vat_json_free (&node);
617   vam->retval = ntohl (mp->retval);
618   vam->result_ready = 1;
619 }
620
621 static void vl_api_af_packet_create_reply_t_handler
622   (vl_api_af_packet_create_reply_t * mp)
623 {
624   vat_main_t *vam = &vat_main;
625   i32 retval = ntohl (mp->retval);
626
627   vam->retval = retval;
628   vam->regenerate_interface_table = 1;
629   vam->sw_if_index = ntohl (mp->sw_if_index);
630   vam->result_ready = 1;
631 }
632
633 static void vl_api_af_packet_create_reply_t_handler_json
634   (vl_api_af_packet_create_reply_t * mp)
635 {
636   vat_main_t *vam = &vat_main;
637   vat_json_node_t node;
638
639   vat_json_init_object (&node);
640   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
641   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
642
643   vat_json_print (vam->ofp, &node);
644   vat_json_free (&node);
645
646   vam->retval = ntohl (mp->retval);
647   vam->result_ready = 1;
648 }
649
650 static void vl_api_create_vlan_subif_reply_t_handler
651   (vl_api_create_vlan_subif_reply_t * mp)
652 {
653   vat_main_t *vam = &vat_main;
654   i32 retval = ntohl (mp->retval);
655
656   vam->retval = retval;
657   vam->regenerate_interface_table = 1;
658   vam->sw_if_index = ntohl (mp->sw_if_index);
659   vam->result_ready = 1;
660 }
661
662 static void vl_api_create_vlan_subif_reply_t_handler_json
663   (vl_api_create_vlan_subif_reply_t * mp)
664 {
665   vat_main_t *vam = &vat_main;
666   vat_json_node_t node;
667
668   vat_json_init_object (&node);
669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
670   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
671
672   vat_json_print (vam->ofp, &node);
673   vat_json_free (&node);
674
675   vam->retval = ntohl (mp->retval);
676   vam->result_ready = 1;
677 }
678
679 static void vl_api_create_subif_reply_t_handler
680   (vl_api_create_subif_reply_t * mp)
681 {
682   vat_main_t *vam = &vat_main;
683   i32 retval = ntohl (mp->retval);
684
685   vam->retval = retval;
686   vam->regenerate_interface_table = 1;
687   vam->sw_if_index = ntohl (mp->sw_if_index);
688   vam->result_ready = 1;
689 }
690
691 static void vl_api_create_subif_reply_t_handler_json
692   (vl_api_create_subif_reply_t * mp)
693 {
694   vat_main_t *vam = &vat_main;
695   vat_json_node_t node;
696
697   vat_json_init_object (&node);
698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
699   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
700
701   vat_json_print (vam->ofp, &node);
702   vat_json_free (&node);
703
704   vam->retval = ntohl (mp->retval);
705   vam->result_ready = 1;
706 }
707
708 static void vl_api_interface_name_renumber_reply_t_handler
709   (vl_api_interface_name_renumber_reply_t * mp)
710 {
711   vat_main_t *vam = &vat_main;
712   i32 retval = ntohl (mp->retval);
713
714   vam->retval = retval;
715   vam->regenerate_interface_table = 1;
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler_json
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   vat_json_node_t node;
724
725   vat_json_init_object (&node);
726   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
727
728   vat_json_print (vam->ofp, &node);
729   vat_json_free (&node);
730
731   vam->retval = ntohl (mp->retval);
732   vam->result_ready = 1;
733 }
734
735 /*
736  * Special-case: build the interface table, maintain
737  * the next loopback sw_if_index vbl.
738  */
739 static void vl_api_sw_interface_details_t_handler
740   (vl_api_sw_interface_details_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   u8 *s = format (0, "%s%c", mp->interface_name, 0);
744
745   hash_set_mem (vam->sw_if_index_by_interface_name, s,
746                 ntohl (mp->sw_if_index));
747
748   /* In sub interface case, fill the sub interface table entry */
749   if (mp->sw_if_index != mp->sup_sw_if_index)
750     {
751       sw_interface_subif_t *sub = NULL;
752
753       vec_add2 (vam->sw_if_subif_table, sub, 1);
754
755       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
756       strncpy ((char *) sub->interface_name, (char *) s,
757                vec_len (sub->interface_name));
758       sub->sw_if_index = ntohl (mp->sw_if_index);
759       sub->sub_id = ntohl (mp->sub_id);
760
761       sub->sub_dot1ad = mp->sub_dot1ad;
762       sub->sub_number_of_tags = mp->sub_number_of_tags;
763       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
764       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
765       sub->sub_exact_match = mp->sub_exact_match;
766       sub->sub_default = mp->sub_default;
767       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
768       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
769
770       /* vlan tag rewrite */
771       sub->vtr_op = ntohl (mp->vtr_op);
772       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
773       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
774       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
775     }
776 }
777
778 static void vl_api_sw_interface_details_t_handler_json
779   (vl_api_sw_interface_details_t * mp)
780 {
781   vat_main_t *vam = &vat_main;
782   vat_json_node_t *node = NULL;
783
784   if (VAT_JSON_ARRAY != vam->json_tree.type)
785     {
786       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
787       vat_json_init_array (&vam->json_tree);
788     }
789   node = vat_json_array_add (&vam->json_tree);
790
791   vat_json_init_object (node);
792   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
793   vat_json_object_add_uint (node, "sup_sw_if_index",
794                             ntohl (mp->sup_sw_if_index));
795   vat_json_object_add_uint (node, "l2_address_length",
796                             ntohl (mp->l2_address_length));
797   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
798                              sizeof (mp->l2_address));
799   vat_json_object_add_string_copy (node, "interface_name",
800                                    mp->interface_name);
801   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
802   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
803   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
804   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
805   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
806   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
807   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
808   vat_json_object_add_uint (node, "sub_number_of_tags",
809                             mp->sub_number_of_tags);
810   vat_json_object_add_uint (node, "sub_outer_vlan_id",
811                             ntohs (mp->sub_outer_vlan_id));
812   vat_json_object_add_uint (node, "sub_inner_vlan_id",
813                             ntohs (mp->sub_inner_vlan_id));
814   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
815   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
816   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
817                             mp->sub_outer_vlan_id_any);
818   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
819                             mp->sub_inner_vlan_id_any);
820   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
821   vat_json_object_add_uint (node, "vtr_push_dot1q",
822                             ntohl (mp->vtr_push_dot1q));
823   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
824   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
825 }
826
827 static void vl_api_sw_interface_set_flags_t_handler
828   (vl_api_sw_interface_set_flags_t * mp)
829 {
830   vat_main_t *vam = &vat_main;
831   if (vam->interface_event_display)
832     errmsg ("interface flags: sw_if_index %d %s %s\n",
833             ntohl (mp->sw_if_index),
834             mp->admin_up_down ? "admin-up" : "admin-down",
835             mp->link_up_down ? "link-up" : "link-down");
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler_json
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   /* JSON output not supported */
842 }
843
844 static void
845 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
846 {
847   vat_main_t *vam = &vat_main;
848   i32 retval = ntohl (mp->retval);
849
850   vam->retval = retval;
851   vam->shmem_result = (u8 *) mp->reply_in_shmem;
852   vam->result_ready = 1;
853 }
854
855 static void
856 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   vat_json_node_t node;
860   api_main_t *am = &api_main;
861   void *oldheap;
862   u8 *reply;
863
864   vat_json_init_object (&node);
865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
866   vat_json_object_add_uint (&node, "reply_in_shmem",
867                             ntohl (mp->reply_in_shmem));
868   /* Toss the shared-memory original... */
869   pthread_mutex_lock (&am->vlib_rp->mutex);
870   oldheap = svm_push_data_heap (am->vlib_rp);
871
872   reply = (u8 *) (mp->reply_in_shmem);
873   vec_free (reply);
874
875   svm_pop_heap (oldheap);
876   pthread_mutex_unlock (&am->vlib_rp->mutex);
877
878   vat_json_print (vam->ofp, &node);
879   vat_json_free (&node);
880
881   vam->retval = ntohl (mp->retval);
882   vam->result_ready = 1;
883 }
884
885 static void
886 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
887 {
888   vat_main_t *vam = &vat_main;
889   i32 retval = ntohl (mp->retval);
890
891   vam->retval = retval;
892   vam->cmd_reply = mp->reply;
893   vam->result_ready = 1;
894 }
895
896 static void
897 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   vat_json_node_t node;
901
902   vat_json_init_object (&node);
903   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
904   vat_json_object_add_string_copy (&node, "reply", mp->reply);
905
906   vat_json_print (vam->ofp, &node);
907   vat_json_free (&node);
908
909   vam->retval = ntohl (mp->retval);
910   vam->result_ready = 1;
911 }
912
913 static void vl_api_classify_add_del_table_reply_t_handler
914   (vl_api_classify_add_del_table_reply_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   i32 retval = ntohl (mp->retval);
918   if (vam->async_mode)
919     {
920       vam->async_errors += (retval < 0);
921     }
922   else
923     {
924       vam->retval = retval;
925       if (retval == 0 &&
926           ((mp->new_table_index != 0xFFFFFFFF) ||
927            (mp->skip_n_vectors != 0xFFFFFFFF) ||
928            (mp->match_n_vectors != 0xFFFFFFFF)))
929         /*
930          * Note: this is just barely thread-safe, depends on
931          * the main thread spinning waiting for an answer...
932          */
933         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
934                 ntohl (mp->new_table_index),
935                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
936       vam->result_ready = 1;
937     }
938 }
939
940 static void vl_api_classify_add_del_table_reply_t_handler_json
941   (vl_api_classify_add_del_table_reply_t * mp)
942 {
943   vat_main_t *vam = &vat_main;
944   vat_json_node_t node;
945
946   vat_json_init_object (&node);
947   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
948   vat_json_object_add_uint (&node, "new_table_index",
949                             ntohl (mp->new_table_index));
950   vat_json_object_add_uint (&node, "skip_n_vectors",
951                             ntohl (mp->skip_n_vectors));
952   vat_json_object_add_uint (&node, "match_n_vectors",
953                             ntohl (mp->match_n_vectors));
954
955   vat_json_print (vam->ofp, &node);
956   vat_json_free (&node);
957
958   vam->retval = ntohl (mp->retval);
959   vam->result_ready = 1;
960 }
961
962 static void vl_api_get_node_index_reply_t_handler
963   (vl_api_get_node_index_reply_t * mp)
964 {
965   vat_main_t *vam = &vat_main;
966   i32 retval = ntohl (mp->retval);
967   if (vam->async_mode)
968     {
969       vam->async_errors += (retval < 0);
970     }
971   else
972     {
973       vam->retval = retval;
974       if (retval == 0)
975         errmsg ("node index %d\n", ntohl (mp->node_index));
976       vam->result_ready = 1;
977     }
978 }
979
980 static void vl_api_get_node_index_reply_t_handler_json
981   (vl_api_get_node_index_reply_t * mp)
982 {
983   vat_main_t *vam = &vat_main;
984   vat_json_node_t node;
985
986   vat_json_init_object (&node);
987   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
988   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
989
990   vat_json_print (vam->ofp, &node);
991   vat_json_free (&node);
992
993   vam->retval = ntohl (mp->retval);
994   vam->result_ready = 1;
995 }
996
997 static void vl_api_get_next_index_reply_t_handler
998   (vl_api_get_next_index_reply_t * mp)
999 {
1000   vat_main_t *vam = &vat_main;
1001   i32 retval = ntohl (mp->retval);
1002   if (vam->async_mode)
1003     {
1004       vam->async_errors += (retval < 0);
1005     }
1006   else
1007     {
1008       vam->retval = retval;
1009       if (retval == 0)
1010         errmsg ("next node index %d\n", ntohl (mp->next_index));
1011       vam->result_ready = 1;
1012     }
1013 }
1014
1015 static void vl_api_get_next_index_reply_t_handler_json
1016   (vl_api_get_next_index_reply_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   vat_json_node_t node;
1020
1021   vat_json_init_object (&node);
1022   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1023   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1024
1025   vat_json_print (vam->ofp, &node);
1026   vat_json_free (&node);
1027
1028   vam->retval = ntohl (mp->retval);
1029   vam->result_ready = 1;
1030 }
1031
1032 static void vl_api_add_node_next_reply_t_handler
1033   (vl_api_add_node_next_reply_t * mp)
1034 {
1035   vat_main_t *vam = &vat_main;
1036   i32 retval = ntohl (mp->retval);
1037   if (vam->async_mode)
1038     {
1039       vam->async_errors += (retval < 0);
1040     }
1041   else
1042     {
1043       vam->retval = retval;
1044       if (retval == 0)
1045         errmsg ("next index %d\n", ntohl (mp->next_index));
1046       vam->result_ready = 1;
1047     }
1048 }
1049
1050 static void vl_api_add_node_next_reply_t_handler_json
1051   (vl_api_add_node_next_reply_t * mp)
1052 {
1053   vat_main_t *vam = &vat_main;
1054   vat_json_node_t node;
1055
1056   vat_json_init_object (&node);
1057   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1058   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1059
1060   vat_json_print (vam->ofp, &node);
1061   vat_json_free (&node);
1062
1063   vam->retval = ntohl (mp->retval);
1064   vam->result_ready = 1;
1065 }
1066
1067 static void vl_api_show_version_reply_t_handler
1068   (vl_api_show_version_reply_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   i32 retval = ntohl (mp->retval);
1072
1073   if (retval >= 0)
1074     {
1075       errmsg ("        program: %s\n", mp->program);
1076       errmsg ("        version: %s\n", mp->version);
1077       errmsg ("     build date: %s\n", mp->build_date);
1078       errmsg ("build directory: %s\n", mp->build_directory);
1079     }
1080   vam->retval = retval;
1081   vam->result_ready = 1;
1082 }
1083
1084 static void vl_api_show_version_reply_t_handler_json
1085   (vl_api_show_version_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   vat_json_node_t node;
1089
1090   vat_json_init_object (&node);
1091   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1092   vat_json_object_add_string_copy (&node, "program", mp->program);
1093   vat_json_object_add_string_copy (&node, "version", mp->version);
1094   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1095   vat_json_object_add_string_copy (&node, "build_directory",
1096                                    mp->build_directory);
1097
1098   vat_json_print (vam->ofp, &node);
1099   vat_json_free (&node);
1100
1101   vam->retval = ntohl (mp->retval);
1102   vam->result_ready = 1;
1103 }
1104
1105 static void
1106 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1107 {
1108   vat_main_t *vam = &vat_main;
1109   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1110           mp->mac_ip ? "mac/ip binding" : "address resolution",
1111           format_ip4_address, &mp->address,
1112           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1113 }
1114
1115 static void
1116 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1117 {
1118   /* JSON output not supported */
1119 }
1120
1121 static void
1122 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1123 {
1124   vat_main_t *vam = &vat_main;
1125   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1126           mp->mac_ip ? "mac/ip binding" : "address resolution",
1127           format_ip6_address, mp->address,
1128           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1129 }
1130
1131 static void
1132 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1133 {
1134   /* JSON output not supported */
1135 }
1136
1137 /*
1138  * Special-case: build the bridge domain table, maintain
1139  * the next bd id vbl.
1140  */
1141 static void vl_api_bridge_domain_details_t_handler
1142   (vl_api_bridge_domain_details_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1146
1147   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1148            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1149
1150   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1151            ntohl (mp->bd_id), mp->learn, mp->forward,
1152            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1153
1154   if (n_sw_ifs)
1155     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1156              "Interface Name");
1157 }
1158
1159 static void vl_api_bridge_domain_details_t_handler_json
1160   (vl_api_bridge_domain_details_t * mp)
1161 {
1162   vat_main_t *vam = &vat_main;
1163   vat_json_node_t *node, *array = NULL;
1164
1165   if (VAT_JSON_ARRAY != vam->json_tree.type)
1166     {
1167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1168       vat_json_init_array (&vam->json_tree);
1169     }
1170   node = vat_json_array_add (&vam->json_tree);
1171
1172   vat_json_init_object (node);
1173   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1174   vat_json_object_add_uint (node, "flood", mp->flood);
1175   vat_json_object_add_uint (node, "forward", mp->forward);
1176   vat_json_object_add_uint (node, "learn", mp->learn);
1177   vat_json_object_add_uint (node, "bvi_sw_if_index",
1178                             ntohl (mp->bvi_sw_if_index));
1179   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1180   array = vat_json_object_add (node, "sw_if");
1181   vat_json_init_array (array);
1182 }
1183
1184 /*
1185  * Special-case: build the bridge domain sw if table.
1186  */
1187 static void vl_api_bridge_domain_sw_if_details_t_handler
1188   (vl_api_bridge_domain_sw_if_details_t * mp)
1189 {
1190   vat_main_t *vam = &vat_main;
1191   hash_pair_t *p;
1192   u8 *sw_if_name = 0;
1193   u32 sw_if_index;
1194
1195   sw_if_index = ntohl (mp->sw_if_index);
1196   /* *INDENT-OFF* */
1197   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1198   ({
1199     if ((u32) p->value[0] == sw_if_index)
1200       {
1201         sw_if_name = (u8 *)(p->key);
1202         break;
1203       }
1204   }));
1205   /* *INDENT-ON* */
1206
1207   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1208            mp->shg, sw_if_name ? (char *) sw_if_name :
1209            "sw_if_index not found!");
1210 }
1211
1212 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1213   (vl_api_bridge_domain_sw_if_details_t * mp)
1214 {
1215   vat_main_t *vam = &vat_main;
1216   vat_json_node_t *node = NULL;
1217   uword last_index = 0;
1218
1219   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1220   ASSERT (vec_len (vam->json_tree.array) >= 1);
1221   last_index = vec_len (vam->json_tree.array) - 1;
1222   node = &vam->json_tree.array[last_index];
1223   node = vat_json_object_get_element (node, "sw_if");
1224   ASSERT (NULL != node);
1225   node = vat_json_array_add (node);
1226
1227   vat_json_init_object (node);
1228   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1229   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1230   vat_json_object_add_uint (node, "shg", mp->shg);
1231 }
1232
1233 static void vl_api_control_ping_reply_t_handler
1234   (vl_api_control_ping_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   i32 retval = ntohl (mp->retval);
1238   if (vam->async_mode)
1239     {
1240       vam->async_errors += (retval < 0);
1241     }
1242   else
1243     {
1244       vam->retval = retval;
1245       vam->result_ready = 1;
1246     }
1247 }
1248
1249 static void vl_api_control_ping_reply_t_handler_json
1250   (vl_api_control_ping_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254
1255   if (VAT_JSON_NONE != vam->json_tree.type)
1256     {
1257       vat_json_print (vam->ofp, &vam->json_tree);
1258       vat_json_free (&vam->json_tree);
1259       vam->json_tree.type = VAT_JSON_NONE;
1260     }
1261   else
1262     {
1263       /* just print [] */
1264       vat_json_init_array (&vam->json_tree);
1265       vat_json_print (vam->ofp, &vam->json_tree);
1266       vam->json_tree.type = VAT_JSON_NONE;
1267     }
1268
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void
1274 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278   if (vam->async_mode)
1279     {
1280       vam->async_errors += (retval < 0);
1281     }
1282   else
1283     {
1284       vam->retval = retval;
1285       vam->result_ready = 1;
1286     }
1287 }
1288
1289 static void vl_api_l2_flags_reply_t_handler_json
1290   (vl_api_l2_flags_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   vat_json_node_t node;
1294
1295   vat_json_init_object (&node);
1296   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1297   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1298                             ntohl (mp->resulting_feature_bitmap));
1299
1300   vat_json_print (vam->ofp, &node);
1301   vat_json_free (&node);
1302
1303   vam->retval = ntohl (mp->retval);
1304   vam->result_ready = 1;
1305 }
1306
1307 static void vl_api_bridge_flags_reply_t_handler
1308   (vl_api_bridge_flags_reply_t * mp)
1309 {
1310   vat_main_t *vam = &vat_main;
1311   i32 retval = ntohl (mp->retval);
1312   if (vam->async_mode)
1313     {
1314       vam->async_errors += (retval < 0);
1315     }
1316   else
1317     {
1318       vam->retval = retval;
1319       vam->result_ready = 1;
1320     }
1321 }
1322
1323 static void vl_api_bridge_flags_reply_t_handler_json
1324   (vl_api_bridge_flags_reply_t * mp)
1325 {
1326   vat_main_t *vam = &vat_main;
1327   vat_json_node_t node;
1328
1329   vat_json_init_object (&node);
1330   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1331   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1332                             ntohl (mp->resulting_feature_bitmap));
1333
1334   vat_json_print (vam->ofp, &node);
1335   vat_json_free (&node);
1336
1337   vam->retval = ntohl (mp->retval);
1338   vam->result_ready = 1;
1339 }
1340
1341 static void vl_api_tap_connect_reply_t_handler
1342   (vl_api_tap_connect_reply_t * mp)
1343 {
1344   vat_main_t *vam = &vat_main;
1345   i32 retval = ntohl (mp->retval);
1346   if (vam->async_mode)
1347     {
1348       vam->async_errors += (retval < 0);
1349     }
1350   else
1351     {
1352       vam->retval = retval;
1353       vam->sw_if_index = ntohl (mp->sw_if_index);
1354       vam->result_ready = 1;
1355     }
1356
1357 }
1358
1359 static void vl_api_tap_connect_reply_t_handler_json
1360   (vl_api_tap_connect_reply_t * mp)
1361 {
1362   vat_main_t *vam = &vat_main;
1363   vat_json_node_t node;
1364
1365   vat_json_init_object (&node);
1366   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1367   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1368
1369   vat_json_print (vam->ofp, &node);
1370   vat_json_free (&node);
1371
1372   vam->retval = ntohl (mp->retval);
1373   vam->result_ready = 1;
1374
1375 }
1376
1377 static void
1378 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1379 {
1380   vat_main_t *vam = &vat_main;
1381   i32 retval = ntohl (mp->retval);
1382   if (vam->async_mode)
1383     {
1384       vam->async_errors += (retval < 0);
1385     }
1386   else
1387     {
1388       vam->retval = retval;
1389       vam->sw_if_index = ntohl (mp->sw_if_index);
1390       vam->result_ready = 1;
1391     }
1392 }
1393
1394 static void vl_api_tap_modify_reply_t_handler_json
1395   (vl_api_tap_modify_reply_t * mp)
1396 {
1397   vat_main_t *vam = &vat_main;
1398   vat_json_node_t node;
1399
1400   vat_json_init_object (&node);
1401   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1402   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1403
1404   vat_json_print (vam->ofp, &node);
1405   vat_json_free (&node);
1406
1407   vam->retval = ntohl (mp->retval);
1408   vam->result_ready = 1;
1409 }
1410
1411 static void
1412 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1413 {
1414   vat_main_t *vam = &vat_main;
1415   i32 retval = ntohl (mp->retval);
1416   if (vam->async_mode)
1417     {
1418       vam->async_errors += (retval < 0);
1419     }
1420   else
1421     {
1422       vam->retval = retval;
1423       vam->result_ready = 1;
1424     }
1425 }
1426
1427 static void vl_api_tap_delete_reply_t_handler_json
1428   (vl_api_tap_delete_reply_t * mp)
1429 {
1430   vat_main_t *vam = &vat_main;
1431   vat_json_node_t node;
1432
1433   vat_json_init_object (&node);
1434   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1435
1436   vat_json_print (vam->ofp, &node);
1437   vat_json_free (&node);
1438
1439   vam->retval = ntohl (mp->retval);
1440   vam->result_ready = 1;
1441 }
1442
1443 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1444   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   i32 retval = ntohl (mp->retval);
1448   if (vam->async_mode)
1449     {
1450       vam->async_errors += (retval < 0);
1451     }
1452   else
1453     {
1454       vam->retval = retval;
1455       vam->result_ready = 1;
1456     }
1457 }
1458
1459 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1460   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1461 {
1462   vat_main_t *vam = &vat_main;
1463   vat_json_node_t node;
1464
1465   vat_json_init_object (&node);
1466   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1467   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1468                             ntohl (mp->sw_if_index));
1469
1470   vat_json_print (vam->ofp, &node);
1471   vat_json_free (&node);
1472
1473   vam->retval = ntohl (mp->retval);
1474   vam->result_ready = 1;
1475 }
1476
1477 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1478   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1479 {
1480   vat_main_t *vam = &vat_main;
1481   i32 retval = ntohl (mp->retval);
1482   if (vam->async_mode)
1483     {
1484       vam->async_errors += (retval < 0);
1485     }
1486   else
1487     {
1488       vam->retval = retval;
1489       vam->sw_if_index = ntohl (mp->sw_if_index);
1490       vam->result_ready = 1;
1491     }
1492 }
1493
1494 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1495   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   vat_json_node_t node;
1499
1500   vat_json_init_object (&node);
1501   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1502   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1503
1504   vat_json_print (vam->ofp, &node);
1505   vat_json_free (&node);
1506
1507   vam->retval = ntohl (mp->retval);
1508   vam->result_ready = 1;
1509 }
1510
1511
1512 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1513   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1514 {
1515   vat_main_t *vam = &vat_main;
1516   i32 retval = ntohl (mp->retval);
1517   if (vam->async_mode)
1518     {
1519       vam->async_errors += (retval < 0);
1520     }
1521   else
1522     {
1523       vam->retval = retval;
1524       vam->result_ready = 1;
1525     }
1526 }
1527
1528 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1529   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1530 {
1531   vat_main_t *vam = &vat_main;
1532   vat_json_node_t node;
1533
1534   vat_json_init_object (&node);
1535   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1536   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1537
1538   vat_json_print (vam->ofp, &node);
1539   vat_json_free (&node);
1540
1541   vam->retval = ntohl (mp->retval);
1542   vam->result_ready = 1;
1543 }
1544
1545 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1546   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   i32 retval = ntohl (mp->retval);
1550   if (vam->async_mode)
1551     {
1552       vam->async_errors += (retval < 0);
1553     }
1554   else
1555     {
1556       vam->retval = retval;
1557       vam->sw_if_index = ntohl (mp->sw_if_index);
1558       vam->result_ready = 1;
1559     }
1560 }
1561
1562 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1563   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1564 {
1565   vat_main_t *vam = &vat_main;
1566   vat_json_node_t node;
1567
1568   vat_json_init_object (&node);
1569   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1570   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1571
1572   vat_json_print (vam->ofp, &node);
1573   vat_json_free (&node);
1574
1575   vam->retval = ntohl (mp->retval);
1576   vam->result_ready = 1;
1577 }
1578
1579 static void vl_api_gre_add_del_tunnel_reply_t_handler
1580   (vl_api_gre_add_del_tunnel_reply_t * mp)
1581 {
1582   vat_main_t *vam = &vat_main;
1583   i32 retval = ntohl (mp->retval);
1584   if (vam->async_mode)
1585     {
1586       vam->async_errors += (retval < 0);
1587     }
1588   else
1589     {
1590       vam->retval = retval;
1591       vam->sw_if_index = ntohl (mp->sw_if_index);
1592       vam->result_ready = 1;
1593     }
1594 }
1595
1596 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1597   (vl_api_gre_add_del_tunnel_reply_t * mp)
1598 {
1599   vat_main_t *vam = &vat_main;
1600   vat_json_node_t node;
1601
1602   vat_json_init_object (&node);
1603   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1604   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1605
1606   vat_json_print (vam->ofp, &node);
1607   vat_json_free (&node);
1608
1609   vam->retval = ntohl (mp->retval);
1610   vam->result_ready = 1;
1611 }
1612
1613 static void vl_api_create_vhost_user_if_reply_t_handler
1614   (vl_api_create_vhost_user_if_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   i32 retval = ntohl (mp->retval);
1618   if (vam->async_mode)
1619     {
1620       vam->async_errors += (retval < 0);
1621     }
1622   else
1623     {
1624       vam->retval = retval;
1625       vam->sw_if_index = ntohl (mp->sw_if_index);
1626       vam->result_ready = 1;
1627     }
1628 }
1629
1630 static void vl_api_create_vhost_user_if_reply_t_handler_json
1631   (vl_api_create_vhost_user_if_reply_t * mp)
1632 {
1633   vat_main_t *vam = &vat_main;
1634   vat_json_node_t node;
1635
1636   vat_json_init_object (&node);
1637   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1638   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1639
1640   vat_json_print (vam->ofp, &node);
1641   vat_json_free (&node);
1642
1643   vam->retval = ntohl (mp->retval);
1644   vam->result_ready = 1;
1645 }
1646
1647 static void vl_api_ip_address_details_t_handler
1648   (vl_api_ip_address_details_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   static ip_address_details_t empty_ip_address_details = { {0} };
1652   ip_address_details_t *address = NULL;
1653   ip_details_t *current_ip_details = NULL;
1654   ip_details_t *details = NULL;
1655
1656   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1657
1658   if (!details || vam->current_sw_if_index >= vec_len (details)
1659       || !details[vam->current_sw_if_index].present)
1660     {
1661       errmsg ("ip address details arrived but not stored\n");
1662       errmsg ("ip_dump should be called first\n");
1663       return;
1664     }
1665
1666   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1667
1668 #define addresses (current_ip_details->addr)
1669
1670   vec_validate_init_empty (addresses, vec_len (addresses),
1671                            empty_ip_address_details);
1672
1673   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1674
1675   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1676   address->prefix_length = mp->prefix_length;
1677 #undef addresses
1678 }
1679
1680 static void vl_api_ip_address_details_t_handler_json
1681   (vl_api_ip_address_details_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t *node = NULL;
1685   struct in6_addr ip6;
1686   struct in_addr ip4;
1687
1688   if (VAT_JSON_ARRAY != vam->json_tree.type)
1689     {
1690       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1691       vat_json_init_array (&vam->json_tree);
1692     }
1693   node = vat_json_array_add (&vam->json_tree);
1694
1695   vat_json_init_object (node);
1696   if (vam->is_ipv6)
1697     {
1698       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1699       vat_json_object_add_ip6 (node, "ip", ip6);
1700     }
1701   else
1702     {
1703       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1704       vat_json_object_add_ip4 (node, "ip", ip4);
1705     }
1706   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1707 }
1708
1709 static void
1710 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   static ip_details_t empty_ip_details = { 0 };
1714   ip_details_t *ip = NULL;
1715   u32 sw_if_index = ~0;
1716
1717   sw_if_index = ntohl (mp->sw_if_index);
1718
1719   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1720                            sw_if_index, empty_ip_details);
1721
1722   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1723                          sw_if_index);
1724
1725   ip->present = 1;
1726 }
1727
1728 static void
1729 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732
1733   if (VAT_JSON_ARRAY != vam->json_tree.type)
1734     {
1735       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1736       vat_json_init_array (&vam->json_tree);
1737     }
1738   vat_json_array_add_uint (&vam->json_tree,
1739                            clib_net_to_host_u32 (mp->sw_if_index));
1740 }
1741
1742 static void vl_api_map_domain_details_t_handler_json
1743   (vl_api_map_domain_details_t * mp)
1744 {
1745   vat_json_node_t *node = NULL;
1746   vat_main_t *vam = &vat_main;
1747   struct in6_addr ip6;
1748   struct in_addr ip4;
1749
1750   if (VAT_JSON_ARRAY != vam->json_tree.type)
1751     {
1752       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1753       vat_json_init_array (&vam->json_tree);
1754     }
1755
1756   node = vat_json_array_add (&vam->json_tree);
1757   vat_json_init_object (node);
1758
1759   vat_json_object_add_uint (node, "domain_index",
1760                             clib_net_to_host_u32 (mp->domain_index));
1761   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1762   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1763   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1764   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1765   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1766   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1767   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1768   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1769   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1770   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1771   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1772   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1773   vat_json_object_add_uint (node, "flags", mp->flags);
1774   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1775   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1776 }
1777
1778 static void vl_api_map_domain_details_t_handler
1779   (vl_api_map_domain_details_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782
1783   if (mp->is_translation)
1784     {
1785       fformat (vam->ofp,
1786                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1787                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1788                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1789                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1790                clib_net_to_host_u32 (mp->domain_index));
1791     }
1792   else
1793     {
1794       fformat (vam->ofp,
1795                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1796                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1797                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1798                format_ip6_address, mp->ip6_src,
1799                clib_net_to_host_u32 (mp->domain_index));
1800     }
1801   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1802            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1803            mp->is_translation ? "map-t" : "");
1804 }
1805
1806 static void vl_api_map_rule_details_t_handler_json
1807   (vl_api_map_rule_details_t * mp)
1808 {
1809   struct in6_addr ip6;
1810   vat_json_node_t *node = NULL;
1811   vat_main_t *vam = &vat_main;
1812
1813   if (VAT_JSON_ARRAY != vam->json_tree.type)
1814     {
1815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1816       vat_json_init_array (&vam->json_tree);
1817     }
1818
1819   node = vat_json_array_add (&vam->json_tree);
1820   vat_json_init_object (node);
1821
1822   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1823   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1824   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1825 }
1826
1827 static void
1828 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1829 {
1830   vat_main_t *vam = &vat_main;
1831   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1832            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1833 }
1834
1835 static void
1836 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1837 {
1838   vat_main_t *vam = &vat_main;
1839   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1840           "router_addr %U host_mac %U\n",
1841           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1842           format_ip4_address, &mp->host_address,
1843           format_ip4_address, &mp->router_address,
1844           format_ethernet_address, mp->host_mac);
1845 }
1846
1847 static void vl_api_dhcp_compl_event_t_handler_json
1848   (vl_api_dhcp_compl_event_t * mp)
1849 {
1850   /* JSON output not supported */
1851 }
1852
1853 static void
1854 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1855                               u32 counter)
1856 {
1857   vat_main_t *vam = &vat_main;
1858   static u64 default_counter = 0;
1859
1860   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1861                            NULL);
1862   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1863                            sw_if_index, default_counter);
1864   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1865 }
1866
1867 static void
1868 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1869                                 interface_counter_t counter)
1870 {
1871   vat_main_t *vam = &vat_main;
1872   static interface_counter_t default_counter = { 0, };
1873
1874   vec_validate_init_empty (vam->combined_interface_counters,
1875                            vnet_counter_type, NULL);
1876   vec_validate_init_empty (vam->combined_interface_counters
1877                            [vnet_counter_type], sw_if_index, default_counter);
1878   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1879 }
1880
1881 static void vl_api_vnet_interface_counters_t_handler
1882   (vl_api_vnet_interface_counters_t * mp)
1883 {
1884   /* not supported */
1885 }
1886
1887 static void vl_api_vnet_interface_counters_t_handler_json
1888   (vl_api_vnet_interface_counters_t * mp)
1889 {
1890   interface_counter_t counter;
1891   vlib_counter_t *v;
1892   u64 *v_packets;
1893   u64 packets;
1894   u32 count;
1895   u32 first_sw_if_index;
1896   int i;
1897
1898   count = ntohl (mp->count);
1899   first_sw_if_index = ntohl (mp->first_sw_if_index);
1900
1901   if (!mp->is_combined)
1902     {
1903       v_packets = (u64 *) & mp->data;
1904       for (i = 0; i < count; i++)
1905         {
1906           packets =
1907             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1908           set_simple_interface_counter (mp->vnet_counter_type,
1909                                         first_sw_if_index + i, packets);
1910           v_packets++;
1911         }
1912     }
1913   else
1914     {
1915       v = (vlib_counter_t *) & mp->data;
1916       for (i = 0; i < count; i++)
1917         {
1918           counter.packets =
1919             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1920           counter.bytes =
1921             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1922           set_combined_interface_counter (mp->vnet_counter_type,
1923                                           first_sw_if_index + i, counter);
1924           v++;
1925         }
1926     }
1927 }
1928
1929 static u32
1930 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1931 {
1932   vat_main_t *vam = &vat_main;
1933   u32 i;
1934
1935   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1936     {
1937       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1938         {
1939           return i;
1940         }
1941     }
1942   return ~0;
1943 }
1944
1945 static u32
1946 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1947 {
1948   vat_main_t *vam = &vat_main;
1949   u32 i;
1950
1951   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1952     {
1953       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1954         {
1955           return i;
1956         }
1957     }
1958   return ~0;
1959 }
1960
1961 static void vl_api_vnet_ip4_fib_counters_t_handler
1962   (vl_api_vnet_ip4_fib_counters_t * mp)
1963 {
1964   /* not supported */
1965 }
1966
1967 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1968   (vl_api_vnet_ip4_fib_counters_t * mp)
1969 {
1970   vat_main_t *vam = &vat_main;
1971   vl_api_ip4_fib_counter_t *v;
1972   ip4_fib_counter_t *counter;
1973   struct in_addr ip4;
1974   u32 vrf_id;
1975   u32 vrf_index;
1976   u32 count;
1977   int i;
1978
1979   vrf_id = ntohl (mp->vrf_id);
1980   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
1981   if (~0 == vrf_index)
1982     {
1983       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
1984       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1985       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1986       vec_validate (vam->ip4_fib_counters, vrf_index);
1987       vam->ip4_fib_counters[vrf_index] = NULL;
1988     }
1989
1990   vec_free (vam->ip4_fib_counters[vrf_index]);
1991   v = (vl_api_ip4_fib_counter_t *) & mp->c;
1992   count = ntohl (mp->count);
1993   for (i = 0; i < count; i++)
1994     {
1995       vec_validate (vam->ip4_fib_counters[vrf_index], i);
1996       counter = &vam->ip4_fib_counters[vrf_index][i];
1997       clib_memcpy (&ip4, &v->address, sizeof (ip4));
1998       counter->address = ip4;
1999       counter->address_length = v->address_length;
2000       counter->packets = clib_net_to_host_u64 (v->packets);
2001       counter->bytes = clib_net_to_host_u64 (v->bytes);
2002       v++;
2003     }
2004 }
2005
2006 static void vl_api_vnet_ip6_fib_counters_t_handler
2007   (vl_api_vnet_ip6_fib_counters_t * mp)
2008 {
2009   /* not supported */
2010 }
2011
2012 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2013   (vl_api_vnet_ip6_fib_counters_t * mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016   vl_api_ip6_fib_counter_t *v;
2017   ip6_fib_counter_t *counter;
2018   struct in6_addr ip6;
2019   u32 vrf_id;
2020   u32 vrf_index;
2021   u32 count;
2022   int i;
2023
2024   vrf_id = ntohl (mp->vrf_id);
2025   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2026   if (~0 == vrf_index)
2027     {
2028       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2029       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2030       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2031       vec_validate (vam->ip6_fib_counters, vrf_index);
2032       vam->ip6_fib_counters[vrf_index] = NULL;
2033     }
2034
2035   vec_free (vam->ip6_fib_counters[vrf_index]);
2036   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2037   count = ntohl (mp->count);
2038   for (i = 0; i < count; i++)
2039     {
2040       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2041       counter = &vam->ip6_fib_counters[vrf_index][i];
2042       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2043       counter->address = ip6;
2044       counter->address_length = v->address_length;
2045       counter->packets = clib_net_to_host_u64 (v->packets);
2046       counter->bytes = clib_net_to_host_u64 (v->bytes);
2047       v++;
2048     }
2049 }
2050
2051 static void vl_api_get_first_msg_id_reply_t_handler
2052   (vl_api_get_first_msg_id_reply_t * mp)
2053 {
2054   vat_main_t *vam = &vat_main;
2055   i32 retval = ntohl (mp->retval);
2056
2057   if (vam->async_mode)
2058     {
2059       vam->async_errors += (retval < 0);
2060     }
2061   else
2062     {
2063       vam->retval = retval;
2064       vam->result_ready = 1;
2065     }
2066   if (retval >= 0)
2067     {
2068       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2069     }
2070 }
2071
2072 static void vl_api_get_first_msg_id_reply_t_handler_json
2073   (vl_api_get_first_msg_id_reply_t * mp)
2074 {
2075   vat_main_t *vam = &vat_main;
2076   vat_json_node_t node;
2077
2078   vat_json_init_object (&node);
2079   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2080   vat_json_object_add_uint (&node, "first_msg_id",
2081                             (uint) ntohs (mp->first_msg_id));
2082
2083   vat_json_print (vam->ofp, &node);
2084   vat_json_free (&node);
2085
2086   vam->retval = ntohl (mp->retval);
2087   vam->result_ready = 1;
2088 }
2089
2090 static void vl_api_get_node_graph_reply_t_handler
2091   (vl_api_get_node_graph_reply_t * mp)
2092 {
2093   vat_main_t *vam = &vat_main;
2094   api_main_t *am = &api_main;
2095   i32 retval = ntohl (mp->retval);
2096   u8 *pvt_copy, *reply;
2097   void *oldheap;
2098   vlib_node_t *node;
2099   int i;
2100
2101   if (vam->async_mode)
2102     {
2103       vam->async_errors += (retval < 0);
2104     }
2105   else
2106     {
2107       vam->retval = retval;
2108       vam->result_ready = 1;
2109     }
2110
2111   /* "Should never happen..." */
2112   if (retval != 0)
2113     return;
2114
2115   reply = (u8 *) (mp->reply_in_shmem);
2116   pvt_copy = vec_dup (reply);
2117
2118   /* Toss the shared-memory original... */
2119   pthread_mutex_lock (&am->vlib_rp->mutex);
2120   oldheap = svm_push_data_heap (am->vlib_rp);
2121
2122   vec_free (reply);
2123
2124   svm_pop_heap (oldheap);
2125   pthread_mutex_unlock (&am->vlib_rp->mutex);
2126
2127   if (vam->graph_nodes)
2128     {
2129       hash_free (vam->graph_node_index_by_name);
2130
2131       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2132         {
2133           node = vam->graph_nodes[i];
2134           vec_free (node->name);
2135           vec_free (node->next_nodes);
2136           vec_free (node);
2137         }
2138       vec_free (vam->graph_nodes);
2139     }
2140
2141   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2142   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2143   vec_free (pvt_copy);
2144
2145   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2146     {
2147       node = vam->graph_nodes[i];
2148       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2149     }
2150 }
2151
2152 static void vl_api_get_node_graph_reply_t_handler_json
2153   (vl_api_get_node_graph_reply_t * mp)
2154 {
2155   vat_main_t *vam = &vat_main;
2156   api_main_t *am = &api_main;
2157   void *oldheap;
2158   vat_json_node_t node;
2159   u8 *reply;
2160
2161   /* $$$$ make this real? */
2162   vat_json_init_object (&node);
2163   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2164   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2165
2166   reply = (u8 *) (mp->reply_in_shmem);
2167
2168   /* Toss the shared-memory original... */
2169   pthread_mutex_lock (&am->vlib_rp->mutex);
2170   oldheap = svm_push_data_heap (am->vlib_rp);
2171
2172   vec_free (reply);
2173
2174   svm_pop_heap (oldheap);
2175   pthread_mutex_unlock (&am->vlib_rp->mutex);
2176
2177   vat_json_print (vam->ofp, &node);
2178   vat_json_free (&node);
2179
2180   vam->retval = ntohl (mp->retval);
2181   vam->result_ready = 1;
2182 }
2183
2184 static void
2185 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2186 {
2187   vat_main_t *vam = &vat_main;
2188   u8 *s = 0;
2189
2190   if (mp->local)
2191     {
2192       s = format (s, "%=16d%=16d%=16d\n",
2193                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2194     }
2195   else
2196     {
2197       s = format (s, "%=16U%=16d%=16d\n",
2198                   mp->is_ipv6 ? format_ip6_address :
2199                   format_ip4_address,
2200                   mp->ip_address, mp->priority, mp->weight);
2201     }
2202
2203   fformat (vam->ofp, "%v", s);
2204   vec_free (s);
2205 }
2206
2207 static void
2208 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2209                                             mp)
2210 {
2211   vat_main_t *vam = &vat_main;
2212   vat_json_node_t *node = NULL;
2213   struct in6_addr ip6;
2214   struct in_addr ip4;
2215
2216   if (VAT_JSON_ARRAY != vam->json_tree.type)
2217     {
2218       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2219       vat_json_init_array (&vam->json_tree);
2220     }
2221   node = vat_json_array_add (&vam->json_tree);
2222   vat_json_init_object (node);
2223
2224   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2225   vat_json_object_add_uint (node, "priority", mp->priority);
2226   vat_json_object_add_uint (node, "weight", mp->weight);
2227
2228   if (mp->local)
2229     vat_json_object_add_uint (node, "sw_if_index",
2230                               clib_net_to_host_u32 (mp->sw_if_index));
2231   else
2232     {
2233       if (mp->is_ipv6)
2234         {
2235           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2236           vat_json_object_add_ip6 (node, "address", ip6);
2237         }
2238       else
2239         {
2240           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2241           vat_json_object_add_ip4 (node, "address", ip4);
2242         }
2243     }
2244 }
2245
2246 static void
2247 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2248                                            mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   u8 *ls_name = 0;
2252
2253   ls_name = format (0, "%s", mp->ls_name);
2254
2255   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2256            ls_name);
2257   vec_free (ls_name);
2258 }
2259
2260 static void
2261   vl_api_lisp_locator_set_details_t_handler_json
2262   (vl_api_lisp_locator_set_details_t * mp)
2263 {
2264   vat_main_t *vam = &vat_main;
2265   vat_json_node_t *node = 0;
2266   u8 *ls_name = 0;
2267
2268   ls_name = format (0, "%s", mp->ls_name);
2269   vec_add1 (ls_name, 0);
2270
2271   if (VAT_JSON_ARRAY != vam->json_tree.type)
2272     {
2273       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2274       vat_json_init_array (&vam->json_tree);
2275     }
2276   node = vat_json_array_add (&vam->json_tree);
2277
2278   vat_json_init_object (node);
2279   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2280   vat_json_object_add_uint (node, "ls_index",
2281                             clib_net_to_host_u32 (mp->ls_index));
2282   vec_free (ls_name);
2283 }
2284
2285 static u8 *
2286 format_lisp_flat_eid (u8 * s, va_list * args)
2287 {
2288   u32 type = va_arg (*args, u32);
2289   u8 *eid = va_arg (*args, u8 *);
2290   u32 eid_len = va_arg (*args, u32);
2291
2292   switch (type)
2293     {
2294     case 0:
2295       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2296     case 1:
2297       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2298     case 2:
2299       return format (s, "%U", format_ethernet_address, eid);
2300     }
2301   return 0;
2302 }
2303
2304 static u8 *
2305 format_lisp_eid_vat (u8 * s, va_list * args)
2306 {
2307   u32 type = va_arg (*args, u32);
2308   u8 *eid = va_arg (*args, u8 *);
2309   u32 eid_len = va_arg (*args, u32);
2310   u8 *seid = va_arg (*args, u8 *);
2311   u32 seid_len = va_arg (*args, u32);
2312   u32 is_src_dst = va_arg (*args, u32);
2313
2314   if (is_src_dst)
2315     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2316
2317   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2318
2319   return s;
2320 }
2321
2322 static void
2323 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2324 {
2325   vat_main_t *vam = &vat_main;
2326   u8 *s = 0, *eid = 0;
2327
2328   if (~0 == mp->locator_set_index)
2329     s = format (0, "action: %d", mp->action);
2330   else
2331     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2332
2333   eid = format (0, "%U", format_lisp_eid_vat,
2334                 mp->eid_type,
2335                 mp->eid,
2336                 mp->eid_prefix_len,
2337                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2338   vec_add1 (eid, 0);
2339
2340   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s\n",
2341            clib_net_to_host_u32 (mp->vni),
2342            eid,
2343            mp->is_local ? "local" : "remote",
2344            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2345            clib_net_to_host_u16 (mp->key_id), mp->key);
2346
2347   vec_free (s);
2348   vec_free (eid);
2349 }
2350
2351 static void
2352 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2353                                               * mp)
2354 {
2355   vat_main_t *vam = &vat_main;
2356   vat_json_node_t *node = 0;
2357   u8 *eid = 0;
2358
2359   if (VAT_JSON_ARRAY != vam->json_tree.type)
2360     {
2361       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2362       vat_json_init_array (&vam->json_tree);
2363     }
2364   node = vat_json_array_add (&vam->json_tree);
2365
2366   vat_json_init_object (node);
2367   if (~0 == mp->locator_set_index)
2368     vat_json_object_add_uint (node, "action", mp->action);
2369   else
2370     vat_json_object_add_uint (node, "locator_set_index",
2371                               clib_net_to_host_u32 (mp->locator_set_index));
2372
2373   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2374   eid = format (0, "%U", format_lisp_eid_vat,
2375                 mp->eid_type,
2376                 mp->eid,
2377                 mp->eid_prefix_len,
2378                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2379   vec_add1 (eid, 0);
2380   vat_json_object_add_string_copy (node, "eid", eid);
2381   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2382   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2383   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2384
2385   if (mp->key_id)
2386     {
2387       vat_json_object_add_uint (node, "key_id",
2388                                 clib_net_to_host_u16 (mp->key_id));
2389       vat_json_object_add_string_copy (node, "key", mp->key);
2390     }
2391   vec_free (eid);
2392 }
2393
2394 static void
2395   vl_api_lisp_eid_table_map_details_t_handler
2396   (vl_api_lisp_eid_table_map_details_t * mp)
2397 {
2398   vat_main_t *vam = &vat_main;
2399
2400   u8 *line = format (0, "%=10d%=10d",
2401                      clib_net_to_host_u32 (mp->vni),
2402                      clib_net_to_host_u32 (mp->dp_table));
2403   fformat (vam->ofp, "%v\n", line);
2404   vec_free (line);
2405 }
2406
2407 static void
2408   vl_api_lisp_eid_table_map_details_t_handler_json
2409   (vl_api_lisp_eid_table_map_details_t * mp)
2410 {
2411   vat_main_t *vam = &vat_main;
2412   vat_json_node_t *node = NULL;
2413
2414   if (VAT_JSON_ARRAY != vam->json_tree.type)
2415     {
2416       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2417       vat_json_init_array (&vam->json_tree);
2418     }
2419   node = vat_json_array_add (&vam->json_tree);
2420   vat_json_init_object (node);
2421   vat_json_object_add_uint (node, "dp_table",
2422                             clib_net_to_host_u32 (mp->dp_table));
2423   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2424 }
2425
2426 static void
2427   vl_api_lisp_eid_table_vni_details_t_handler
2428   (vl_api_lisp_eid_table_vni_details_t * mp)
2429 {
2430   vat_main_t *vam = &vat_main;
2431
2432   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2433   fformat (vam->ofp, "%v\n", line);
2434   vec_free (line);
2435 }
2436
2437 static void
2438   vl_api_lisp_eid_table_vni_details_t_handler_json
2439   (vl_api_lisp_eid_table_vni_details_t * mp)
2440 {
2441   vat_main_t *vam = &vat_main;
2442   vat_json_node_t *node = NULL;
2443
2444   if (VAT_JSON_ARRAY != vam->json_tree.type)
2445     {
2446       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2447       vat_json_init_array (&vam->json_tree);
2448     }
2449   node = vat_json_array_add (&vam->json_tree);
2450   vat_json_init_object (node);
2451   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2452 }
2453
2454 static u8 *
2455 format_decap_next (u8 * s, va_list * args)
2456 {
2457   u32 next_index = va_arg (*args, u32);
2458
2459   switch (next_index)
2460     {
2461     case LISP_GPE_INPUT_NEXT_DROP:
2462       return format (s, "drop");
2463     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2464       return format (s, "ip4");
2465     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2466       return format (s, "ip6");
2467     default:
2468       return format (s, "unknown %d", next_index);
2469     }
2470   return s;
2471 }
2472
2473 static void
2474 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2475                                           mp)
2476 {
2477   vat_main_t *vam = &vat_main;
2478   u8 *iid_str;
2479   u8 *flag_str = NULL;
2480
2481   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2482
2483 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2484   foreach_lisp_gpe_flag_bit;
2485 #undef _
2486
2487   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2488            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2489            mp->tunnels,
2490            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2491            mp->source_ip,
2492            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2493            mp->destination_ip,
2494            ntohl (mp->encap_fib_id),
2495            ntohl (mp->decap_fib_id),
2496            format_decap_next, ntohl (mp->dcap_next),
2497            mp->ver_res >> 6,
2498            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2499
2500   vec_free (iid_str);
2501 }
2502
2503 static void
2504   vl_api_lisp_gpe_tunnel_details_t_handler_json
2505   (vl_api_lisp_gpe_tunnel_details_t * mp)
2506 {
2507   vat_main_t *vam = &vat_main;
2508   vat_json_node_t *node = NULL;
2509   struct in6_addr ip6;
2510   struct in_addr ip4;
2511   u8 *next_decap_str;
2512
2513   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2514
2515   if (VAT_JSON_ARRAY != vam->json_tree.type)
2516     {
2517       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2518       vat_json_init_array (&vam->json_tree);
2519     }
2520   node = vat_json_array_add (&vam->json_tree);
2521
2522   vat_json_init_object (node);
2523   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2524   if (mp->is_ipv6)
2525     {
2526       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2527       vat_json_object_add_ip6 (node, "source address", ip6);
2528       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2529       vat_json_object_add_ip6 (node, "destination address", ip6);
2530     }
2531   else
2532     {
2533       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2534       vat_json_object_add_ip4 (node, "source address", ip4);
2535       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2536       vat_json_object_add_ip4 (node, "destination address", ip4);
2537     }
2538   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2539   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2540   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2541   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2542   vat_json_object_add_uint (node, "flags", mp->flags);
2543   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2544   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2545   vat_json_object_add_uint (node, "res", mp->res);
2546   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2547
2548   vec_free (next_decap_str);
2549 }
2550
2551 static void
2552   vl_api_show_lisp_map_register_state_reply_t_handler
2553   (vl_api_show_lisp_map_register_state_reply_t * mp)
2554 {
2555   vat_main_t *vam = &vat_main;
2556   int retval = clib_net_to_host_u32 (mp->retval);
2557
2558   fformat (vam->ofp, "%s\n", mp->is_enabled ? "enabled" : "disabled");
2559
2560   vam->retval = retval;
2561   vam->result_ready = 1;
2562 }
2563
2564 static void
2565   vl_api_show_lisp_map_register_state_reply_t_handler_json
2566   (vl_api_show_lisp_map_register_state_reply_t * mp)
2567 {
2568   vat_main_t *vam = &vat_main;
2569   vat_json_node_t _node, *node = &_node;
2570   int retval = clib_net_to_host_u32 (mp->retval);
2571
2572   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2573
2574   vat_json_init_object (node);
2575   vat_json_object_add_string_copy (node, "state", s);
2576
2577   vat_json_print (vam->ofp, node);
2578   vat_json_free (node);
2579
2580   vam->retval = retval;
2581   vam->result_ready = 1;
2582   vec_free (s);
2583 }
2584
2585 static void
2586   vl_api_show_lisp_rloc_probe_state_reply_t_handler
2587   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2588 {
2589   vat_main_t *vam = &vat_main;
2590   int retval = clib_net_to_host_u32 (mp->retval);
2591
2592   if (retval)
2593     goto end;
2594
2595   fformat (vam->ofp, "%s\n", mp->is_enabled ? "enabled" : "disabled");
2596 end:
2597   vam->retval = retval;
2598   vam->result_ready = 1;
2599 }
2600
2601 static void
2602   vl_api_show_lisp_rloc_probe_state_reply_t_handler_json
2603   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2604 {
2605   vat_main_t *vam = &vat_main;
2606   vat_json_node_t _node, *node = &_node;
2607   int retval = clib_net_to_host_u32 (mp->retval);
2608
2609   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2610   vat_json_init_object (node);
2611   vat_json_object_add_string_copy (node, "state", s);
2612
2613   vat_json_print (vam->ofp, node);
2614   vat_json_free (node);
2615
2616   vam->retval = retval;
2617   vam->result_ready = 1;
2618   vec_free (s);
2619 }
2620
2621 static void
2622   vl_api_lisp_adjacencies_get_reply_t_handler
2623   (vl_api_lisp_adjacencies_get_reply_t * mp)
2624 {
2625   vat_main_t *vam = &vat_main;
2626   u32 i, n;
2627   int retval = clib_net_to_host_u32 (mp->retval);
2628   vl_api_lisp_adjacency_t *a;
2629
2630   if (retval)
2631     goto end;
2632
2633   n = clib_net_to_host_u32 (mp->count);
2634
2635   for (i = 0; i < n; i++)
2636     {
2637       a = &mp->adjacencies[i];
2638       fformat (vam->ofp, "%U %40U\n",
2639                format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2640                format_lisp_flat_eid, a->eid_type, a->reid,
2641                a->reid_prefix_len);
2642     }
2643
2644 end:
2645   vam->retval = retval;
2646   vam->result_ready = 1;
2647 }
2648
2649 static void
2650   vl_api_lisp_adjacencies_get_reply_t_handler_json
2651   (vl_api_lisp_adjacencies_get_reply_t * mp)
2652 {
2653   u8 *s = 0;
2654   vat_main_t *vam = &vat_main;
2655   vat_json_node_t *e = 0, root;
2656   u32 i, n;
2657   int retval = clib_net_to_host_u32 (mp->retval);
2658   vl_api_lisp_adjacency_t *a;
2659
2660   if (retval)
2661     goto end;
2662
2663   n = clib_net_to_host_u32 (mp->count);
2664   vat_json_init_array (&root);
2665
2666   for (i = 0; i < n; i++)
2667     {
2668       e = vat_json_array_add (&root);
2669       a = &mp->adjacencies[i];
2670
2671       vat_json_init_object (e);
2672       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2673                   a->leid_prefix_len);
2674       vec_add1 (s, 0);
2675       vat_json_object_add_string_copy (e, "leid", s);
2676       vec_free (s);
2677
2678       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2679                   a->reid_prefix_len);
2680       vec_add1 (s, 0);
2681       vat_json_object_add_string_copy (e, "reid", s);
2682       vec_free (s);
2683     }
2684
2685   vat_json_print (vam->ofp, &root);
2686   vat_json_free (&root);
2687
2688 end:
2689   vam->retval = retval;
2690   vam->result_ready = 1;
2691 }
2692
2693 static void
2694 vl_api_lisp_map_server_details_t_handler (vl_api_lisp_map_server_details_t
2695                                           * mp)
2696 {
2697   vat_main_t *vam = &vat_main;
2698
2699   fformat (vam->ofp, "%=20U\n",
2700            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2701            mp->ip_address);
2702 }
2703
2704 static void
2705   vl_api_lisp_map_server_details_t_handler_json
2706   (vl_api_lisp_map_server_details_t * mp)
2707 {
2708   vat_main_t *vam = &vat_main;
2709   vat_json_node_t *node = NULL;
2710   struct in6_addr ip6;
2711   struct in_addr ip4;
2712
2713   if (VAT_JSON_ARRAY != vam->json_tree.type)
2714     {
2715       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2716       vat_json_init_array (&vam->json_tree);
2717     }
2718   node = vat_json_array_add (&vam->json_tree);
2719
2720   vat_json_init_object (node);
2721   if (mp->is_ipv6)
2722     {
2723       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2724       vat_json_object_add_ip6 (node, "map-server", ip6);
2725     }
2726   else
2727     {
2728       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2729       vat_json_object_add_ip4 (node, "map-server", ip4);
2730     }
2731 }
2732
2733 static void
2734 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2735                                             * mp)
2736 {
2737   vat_main_t *vam = &vat_main;
2738
2739   fformat (vam->ofp, "%=20U\n",
2740            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2741            mp->ip_address);
2742 }
2743
2744 static void
2745   vl_api_lisp_map_resolver_details_t_handler_json
2746   (vl_api_lisp_map_resolver_details_t * mp)
2747 {
2748   vat_main_t *vam = &vat_main;
2749   vat_json_node_t *node = NULL;
2750   struct in6_addr ip6;
2751   struct in_addr ip4;
2752
2753   if (VAT_JSON_ARRAY != vam->json_tree.type)
2754     {
2755       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2756       vat_json_init_array (&vam->json_tree);
2757     }
2758   node = vat_json_array_add (&vam->json_tree);
2759
2760   vat_json_init_object (node);
2761   if (mp->is_ipv6)
2762     {
2763       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2764       vat_json_object_add_ip6 (node, "map resolver", ip6);
2765     }
2766   else
2767     {
2768       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2769       vat_json_object_add_ip4 (node, "map resolver", ip4);
2770     }
2771 }
2772
2773 static void
2774   vl_api_show_lisp_status_reply_t_handler
2775   (vl_api_show_lisp_status_reply_t * mp)
2776 {
2777   vat_main_t *vam = &vat_main;
2778   i32 retval = ntohl (mp->retval);
2779
2780   if (0 <= retval)
2781     {
2782       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2783                mp->feature_status ? "enabled" : "disabled",
2784                mp->gpe_status ? "enabled" : "disabled");
2785     }
2786
2787   vam->retval = retval;
2788   vam->result_ready = 1;
2789 }
2790
2791 static void
2792   vl_api_show_lisp_status_reply_t_handler_json
2793   (vl_api_show_lisp_status_reply_t * mp)
2794 {
2795   vat_main_t *vam = &vat_main;
2796   vat_json_node_t node;
2797   u8 *gpe_status = NULL;
2798   u8 *feature_status = NULL;
2799
2800   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2801   feature_status = format (0, "%s",
2802                            mp->feature_status ? "enabled" : "disabled");
2803   vec_add1 (gpe_status, 0);
2804   vec_add1 (feature_status, 0);
2805
2806   vat_json_init_object (&node);
2807   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2808   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2809
2810   vec_free (gpe_status);
2811   vec_free (feature_status);
2812
2813   vat_json_print (vam->ofp, &node);
2814   vat_json_free (&node);
2815
2816   vam->retval = ntohl (mp->retval);
2817   vam->result_ready = 1;
2818 }
2819
2820 static void
2821   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2822   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2823 {
2824   vat_main_t *vam = &vat_main;
2825   i32 retval = ntohl (mp->retval);
2826
2827   if (retval >= 0)
2828     {
2829       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2830     }
2831
2832   vam->retval = retval;
2833   vam->result_ready = 1;
2834 }
2835
2836 static void
2837   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2838   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2839 {
2840   vat_main_t *vam = &vat_main;
2841   vat_json_node_t *node = NULL;
2842
2843   if (VAT_JSON_ARRAY != vam->json_tree.type)
2844     {
2845       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2846       vat_json_init_array (&vam->json_tree);
2847     }
2848   node = vat_json_array_add (&vam->json_tree);
2849
2850   vat_json_init_object (node);
2851   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2852
2853   vat_json_print (vam->ofp, node);
2854   vat_json_free (node);
2855
2856   vam->retval = ntohl (mp->retval);
2857   vam->result_ready = 1;
2858 }
2859
2860 static u8 *
2861 format_lisp_map_request_mode (u8 * s, va_list * args)
2862 {
2863   u32 mode = va_arg (*args, u32);
2864
2865   switch (mode)
2866     {
2867     case 0:
2868       return format (0, "dst-only");
2869     case 1:
2870       return format (0, "src-dst");
2871     }
2872   return 0;
2873 }
2874
2875 static void
2876   vl_api_show_lisp_map_request_mode_reply_t_handler
2877   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2878 {
2879   vat_main_t *vam = &vat_main;
2880   i32 retval = ntohl (mp->retval);
2881
2882   if (0 <= retval)
2883     {
2884       u32 mode = mp->mode;
2885       fformat (vam->ofp, "map_request_mode: %U\n",
2886                format_lisp_map_request_mode, mode);
2887     }
2888
2889   vam->retval = retval;
2890   vam->result_ready = 1;
2891 }
2892
2893 static void
2894   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2895   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2896 {
2897   vat_main_t *vam = &vat_main;
2898   vat_json_node_t node;
2899   u8 *s = 0;
2900   u32 mode;
2901
2902   mode = mp->mode;
2903   s = format (0, "%U", format_lisp_map_request_mode, mode);
2904   vec_add1 (s, 0);
2905
2906   vat_json_init_object (&node);
2907   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2908   vat_json_print (vam->ofp, &node);
2909   vat_json_free (&node);
2910
2911   vec_free (s);
2912   vam->retval = ntohl (mp->retval);
2913   vam->result_ready = 1;
2914 }
2915
2916 static void
2917 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2918 {
2919   vat_main_t *vam = &vat_main;
2920   i32 retval = ntohl (mp->retval);
2921
2922   if (0 <= retval)
2923     {
2924       fformat (vam->ofp, "%-20s%-16s\n",
2925                mp->status ? "enabled" : "disabled",
2926                mp->status ? (char *) mp->locator_set_name : "");
2927     }
2928
2929   vam->retval = retval;
2930   vam->result_ready = 1;
2931 }
2932
2933 static void
2934 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2935                                             mp)
2936 {
2937   vat_main_t *vam = &vat_main;
2938   vat_json_node_t node;
2939   u8 *status = 0;
2940
2941   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2942   vec_add1 (status, 0);
2943
2944   vat_json_init_object (&node);
2945   vat_json_object_add_string_copy (&node, "status", status);
2946   if (mp->status)
2947     {
2948       vat_json_object_add_string_copy (&node, "locator_set",
2949                                        mp->locator_set_name);
2950     }
2951
2952   vec_free (status);
2953
2954   vat_json_print (vam->ofp, &node);
2955   vat_json_free (&node);
2956
2957   vam->retval = ntohl (mp->retval);
2958   vam->result_ready = 1;
2959 }
2960
2961 static u8 *
2962 format_policer_type (u8 * s, va_list * va)
2963 {
2964   u32 i = va_arg (*va, u32);
2965
2966   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2967     s = format (s, "1r2c");
2968   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2969     s = format (s, "1r3c");
2970   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2971     s = format (s, "2r3c-2698");
2972   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2973     s = format (s, "2r3c-4115");
2974   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2975     s = format (s, "2r3c-mef5cf1");
2976   else
2977     s = format (s, "ILLEGAL");
2978   return s;
2979 }
2980
2981 static u8 *
2982 format_policer_rate_type (u8 * s, va_list * va)
2983 {
2984   u32 i = va_arg (*va, u32);
2985
2986   if (i == SSE2_QOS_RATE_KBPS)
2987     s = format (s, "kbps");
2988   else if (i == SSE2_QOS_RATE_PPS)
2989     s = format (s, "pps");
2990   else
2991     s = format (s, "ILLEGAL");
2992   return s;
2993 }
2994
2995 static u8 *
2996 format_policer_round_type (u8 * s, va_list * va)
2997 {
2998   u32 i = va_arg (*va, u32);
2999
3000   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3001     s = format (s, "closest");
3002   else if (i == SSE2_QOS_ROUND_TO_UP)
3003     s = format (s, "up");
3004   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3005     s = format (s, "down");
3006   else
3007     s = format (s, "ILLEGAL");
3008   return s;
3009 }
3010
3011 static u8 *
3012 format_policer_action_type (u8 * s, va_list * va)
3013 {
3014   u32 i = va_arg (*va, u32);
3015
3016   if (i == SSE2_QOS_ACTION_DROP)
3017     s = format (s, "drop");
3018   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3019     s = format (s, "transmit");
3020   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3021     s = format (s, "mark-and-transmit");
3022   else
3023     s = format (s, "ILLEGAL");
3024   return s;
3025 }
3026
3027 static u8 *
3028 format_dscp (u8 * s, va_list * va)
3029 {
3030   u32 i = va_arg (*va, u32);
3031   char *t = 0;
3032
3033   switch (i)
3034     {
3035 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3036       foreach_vnet_dscp
3037 #undef _
3038     default:
3039       return format (s, "ILLEGAL");
3040     }
3041   s = format (s, "%s", t);
3042   return s;
3043 }
3044
3045 static void
3046 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3047 {
3048   vat_main_t *vam = &vat_main;
3049   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3050
3051   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3052     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3053   else
3054     conform_dscp_str = format (0, "");
3055
3056   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3057     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3058   else
3059     exceed_dscp_str = format (0, "");
3060
3061   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3062     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3063   else
3064     violate_dscp_str = format (0, "");
3065
3066   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3067            "rate type %U, round type %U, %s rate, %s color-aware, "
3068            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3069            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3070            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
3071            mp->name,
3072            format_policer_type, mp->type,
3073            ntohl (mp->cir),
3074            ntohl (mp->eir),
3075            clib_net_to_host_u64 (mp->cb),
3076            clib_net_to_host_u64 (mp->eb),
3077            format_policer_rate_type, mp->rate_type,
3078            format_policer_round_type, mp->round_type,
3079            mp->single_rate ? "single" : "dual",
3080            mp->color_aware ? "is" : "not",
3081            ntohl (mp->cir_tokens_per_period),
3082            ntohl (mp->pir_tokens_per_period),
3083            ntohl (mp->scale),
3084            ntohl (mp->current_limit),
3085            ntohl (mp->current_bucket),
3086            ntohl (mp->extended_limit),
3087            ntohl (mp->extended_bucket),
3088            clib_net_to_host_u64 (mp->last_update_time),
3089            format_policer_action_type, mp->conform_action_type,
3090            conform_dscp_str,
3091            format_policer_action_type, mp->exceed_action_type,
3092            exceed_dscp_str,
3093            format_policer_action_type, mp->violate_action_type,
3094            violate_dscp_str);
3095
3096   vec_free (conform_dscp_str);
3097   vec_free (exceed_dscp_str);
3098   vec_free (violate_dscp_str);
3099 }
3100
3101 static void vl_api_policer_details_t_handler_json
3102   (vl_api_policer_details_t * mp)
3103 {
3104   vat_main_t *vam = &vat_main;
3105   vat_json_node_t *node;
3106   u8 *rate_type_str, *round_type_str, *type_str;
3107   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3108
3109   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3110   round_type_str =
3111     format (0, "%U", format_policer_round_type, mp->round_type);
3112   type_str = format (0, "%U", format_policer_type, mp->type);
3113   conform_action_str = format (0, "%U", format_policer_action_type,
3114                                mp->conform_action_type);
3115   exceed_action_str = format (0, "%U", format_policer_action_type,
3116                               mp->exceed_action_type);
3117   violate_action_str = format (0, "%U", format_policer_action_type,
3118                                mp->violate_action_type);
3119
3120   if (VAT_JSON_ARRAY != vam->json_tree.type)
3121     {
3122       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3123       vat_json_init_array (&vam->json_tree);
3124     }
3125   node = vat_json_array_add (&vam->json_tree);
3126
3127   vat_json_init_object (node);
3128   vat_json_object_add_string_copy (node, "name", mp->name);
3129   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3130   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3131   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3132   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3133   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3134   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3135   vat_json_object_add_string_copy (node, "type", type_str);
3136   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3137   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3138   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3139   vat_json_object_add_uint (node, "cir_tokens_per_period",
3140                             ntohl (mp->cir_tokens_per_period));
3141   vat_json_object_add_uint (node, "eir_tokens_per_period",
3142                             ntohl (mp->pir_tokens_per_period));
3143   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3144   vat_json_object_add_uint (node, "current_bucket",
3145                             ntohl (mp->current_bucket));
3146   vat_json_object_add_uint (node, "extended_limit",
3147                             ntohl (mp->extended_limit));
3148   vat_json_object_add_uint (node, "extended_bucket",
3149                             ntohl (mp->extended_bucket));
3150   vat_json_object_add_uint (node, "last_update_time",
3151                             ntohl (mp->last_update_time));
3152   vat_json_object_add_string_copy (node, "conform_action",
3153                                    conform_action_str);
3154   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3155     {
3156       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3157       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3158       vec_free (dscp_str);
3159     }
3160   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3161   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3162     {
3163       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3164       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3165       vec_free (dscp_str);
3166     }
3167   vat_json_object_add_string_copy (node, "violate_action",
3168                                    violate_action_str);
3169   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3170     {
3171       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3172       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3173       vec_free (dscp_str);
3174     }
3175
3176   vec_free (rate_type_str);
3177   vec_free (round_type_str);
3178   vec_free (type_str);
3179   vec_free (conform_action_str);
3180   vec_free (exceed_action_str);
3181   vec_free (violate_action_str);
3182 }
3183
3184 static void
3185 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3186                                            mp)
3187 {
3188   vat_main_t *vam = &vat_main;
3189   int i, count = ntohl (mp->count);
3190
3191   if (count > 0)
3192     fformat (vam->ofp, "classify table ids (%d) : ", count);
3193   for (i = 0; i < count; i++)
3194     {
3195       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3196       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3197     }
3198   vam->retval = ntohl (mp->retval);
3199   vam->result_ready = 1;
3200 }
3201
3202 static void
3203   vl_api_classify_table_ids_reply_t_handler_json
3204   (vl_api_classify_table_ids_reply_t * mp)
3205 {
3206   vat_main_t *vam = &vat_main;
3207   int i, count = ntohl (mp->count);
3208
3209   if (count > 0)
3210     {
3211       vat_json_node_t node;
3212
3213       vat_json_init_object (&node);
3214       for (i = 0; i < count; i++)
3215         {
3216           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3217         }
3218       vat_json_print (vam->ofp, &node);
3219       vat_json_free (&node);
3220     }
3221   vam->retval = ntohl (mp->retval);
3222   vam->result_ready = 1;
3223 }
3224
3225 static void
3226   vl_api_classify_table_by_interface_reply_t_handler
3227   (vl_api_classify_table_by_interface_reply_t * mp)
3228 {
3229   vat_main_t *vam = &vat_main;
3230   u32 table_id;
3231
3232   table_id = ntohl (mp->l2_table_id);
3233   if (table_id != ~0)
3234     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3235   else
3236     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3237   table_id = ntohl (mp->ip4_table_id);
3238   if (table_id != ~0)
3239     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3240   else
3241     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3242   table_id = ntohl (mp->ip6_table_id);
3243   if (table_id != ~0)
3244     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3245   else
3246     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3247   vam->retval = ntohl (mp->retval);
3248   vam->result_ready = 1;
3249 }
3250
3251 static void
3252   vl_api_classify_table_by_interface_reply_t_handler_json
3253   (vl_api_classify_table_by_interface_reply_t * mp)
3254 {
3255   vat_main_t *vam = &vat_main;
3256   vat_json_node_t node;
3257
3258   vat_json_init_object (&node);
3259
3260   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3261   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3262   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3263
3264   vat_json_print (vam->ofp, &node);
3265   vat_json_free (&node);
3266
3267   vam->retval = ntohl (mp->retval);
3268   vam->result_ready = 1;
3269 }
3270
3271 static void vl_api_policer_add_del_reply_t_handler
3272   (vl_api_policer_add_del_reply_t * mp)
3273 {
3274   vat_main_t *vam = &vat_main;
3275   i32 retval = ntohl (mp->retval);
3276   if (vam->async_mode)
3277     {
3278       vam->async_errors += (retval < 0);
3279     }
3280   else
3281     {
3282       vam->retval = retval;
3283       vam->result_ready = 1;
3284       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3285         /*
3286          * Note: this is just barely thread-safe, depends on
3287          * the main thread spinning waiting for an answer...
3288          */
3289         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3290     }
3291 }
3292
3293 static void vl_api_policer_add_del_reply_t_handler_json
3294   (vl_api_policer_add_del_reply_t * mp)
3295 {
3296   vat_main_t *vam = &vat_main;
3297   vat_json_node_t node;
3298
3299   vat_json_init_object (&node);
3300   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3301   vat_json_object_add_uint (&node, "policer_index",
3302                             ntohl (mp->policer_index));
3303
3304   vat_json_print (vam->ofp, &node);
3305   vat_json_free (&node);
3306
3307   vam->retval = ntohl (mp->retval);
3308   vam->result_ready = 1;
3309 }
3310
3311 /* Format hex dump. */
3312 u8 *
3313 format_hex_bytes (u8 * s, va_list * va)
3314 {
3315   u8 *bytes = va_arg (*va, u8 *);
3316   int n_bytes = va_arg (*va, int);
3317   uword i;
3318
3319   /* Print short or long form depending on byte count. */
3320   uword short_form = n_bytes <= 32;
3321   uword indent = format_get_indent (s);
3322
3323   if (n_bytes == 0)
3324     return s;
3325
3326   for (i = 0; i < n_bytes; i++)
3327     {
3328       if (!short_form && (i % 32) == 0)
3329         s = format (s, "%08x: ", i);
3330       s = format (s, "%02x", bytes[i]);
3331       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3332         s = format (s, "\n%U", format_white_space, indent);
3333     }
3334
3335   return s;
3336 }
3337
3338 static void
3339 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3340                                             * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   i32 retval = ntohl (mp->retval);
3344   if (retval == 0)
3345     {
3346       fformat (vam->ofp, "classify table info :\n");
3347       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3348                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3349                ntohl (mp->miss_next_index));
3350       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3351                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3352                ntohl (mp->match_n_vectors));
3353       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3354                ntohl (mp->mask_length));
3355     }
3356   vam->retval = retval;
3357   vam->result_ready = 1;
3358 }
3359
3360 static void
3361   vl_api_classify_table_info_reply_t_handler_json
3362   (vl_api_classify_table_info_reply_t * mp)
3363 {
3364   vat_main_t *vam = &vat_main;
3365   vat_json_node_t node;
3366
3367   i32 retval = ntohl (mp->retval);
3368   if (retval == 0)
3369     {
3370       vat_json_init_object (&node);
3371
3372       vat_json_object_add_int (&node, "sessions",
3373                                ntohl (mp->active_sessions));
3374       vat_json_object_add_int (&node, "nexttbl",
3375                                ntohl (mp->next_table_index));
3376       vat_json_object_add_int (&node, "nextnode",
3377                                ntohl (mp->miss_next_index));
3378       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3379       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3380       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3381       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3382                       ntohl (mp->mask_length), 0);
3383       vat_json_object_add_string_copy (&node, "mask", s);
3384
3385       vat_json_print (vam->ofp, &node);
3386       vat_json_free (&node);
3387     }
3388   vam->retval = ntohl (mp->retval);
3389   vam->result_ready = 1;
3390 }
3391
3392 static void
3393 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3394                                            mp)
3395 {
3396   vat_main_t *vam = &vat_main;
3397
3398   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3399            ntohl (mp->hit_next_index), ntohl (mp->advance),
3400            ntohl (mp->opaque_index));
3401   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3402            ntohl (mp->match_length));
3403 }
3404
3405 static void
3406   vl_api_classify_session_details_t_handler_json
3407   (vl_api_classify_session_details_t * mp)
3408 {
3409   vat_main_t *vam = &vat_main;
3410   vat_json_node_t *node = NULL;
3411
3412   if (VAT_JSON_ARRAY != vam->json_tree.type)
3413     {
3414       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3415       vat_json_init_array (&vam->json_tree);
3416     }
3417   node = vat_json_array_add (&vam->json_tree);
3418
3419   vat_json_init_object (node);
3420   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3421   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3422   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3423   u8 *s =
3424     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3425             0);
3426   vat_json_object_add_string_copy (node, "match", s);
3427 }
3428
3429 static void vl_api_pg_create_interface_reply_t_handler
3430   (vl_api_pg_create_interface_reply_t * mp)
3431 {
3432   vat_main_t *vam = &vat_main;
3433
3434   vam->retval = ntohl (mp->retval);
3435   vam->result_ready = 1;
3436 }
3437
3438 static void vl_api_pg_create_interface_reply_t_handler_json
3439   (vl_api_pg_create_interface_reply_t * mp)
3440 {
3441   vat_main_t *vam = &vat_main;
3442   vat_json_node_t node;
3443
3444   i32 retval = ntohl (mp->retval);
3445   if (retval == 0)
3446     {
3447       vat_json_init_object (&node);
3448
3449       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3450
3451       vat_json_print (vam->ofp, &node);
3452       vat_json_free (&node);
3453     }
3454   vam->retval = ntohl (mp->retval);
3455   vam->result_ready = 1;
3456 }
3457
3458 static void vl_api_policer_classify_details_t_handler
3459   (vl_api_policer_classify_details_t * mp)
3460 {
3461   vat_main_t *vam = &vat_main;
3462
3463   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3464            ntohl (mp->table_index));
3465 }
3466
3467 static void vl_api_policer_classify_details_t_handler_json
3468   (vl_api_policer_classify_details_t * mp)
3469 {
3470   vat_main_t *vam = &vat_main;
3471   vat_json_node_t *node;
3472
3473   if (VAT_JSON_ARRAY != vam->json_tree.type)
3474     {
3475       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3476       vat_json_init_array (&vam->json_tree);
3477     }
3478   node = vat_json_array_add (&vam->json_tree);
3479
3480   vat_json_init_object (node);
3481   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3482   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3483 }
3484
3485 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3486   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3487 {
3488   vat_main_t *vam = &vat_main;
3489   i32 retval = ntohl (mp->retval);
3490   if (vam->async_mode)
3491     {
3492       vam->async_errors += (retval < 0);
3493     }
3494   else
3495     {
3496       vam->retval = retval;
3497       vam->sw_if_index = ntohl (mp->sw_if_index);
3498       vam->result_ready = 1;
3499     }
3500 }
3501
3502 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3503   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3504 {
3505   vat_main_t *vam = &vat_main;
3506   vat_json_node_t node;
3507
3508   vat_json_init_object (&node);
3509   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3510   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3511
3512   vat_json_print (vam->ofp, &node);
3513   vat_json_free (&node);
3514
3515   vam->retval = ntohl (mp->retval);
3516   vam->result_ready = 1;
3517 }
3518
3519 static void vl_api_flow_classify_details_t_handler
3520   (vl_api_flow_classify_details_t * mp)
3521 {
3522   vat_main_t *vam = &vat_main;
3523
3524   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3525            ntohl (mp->table_index));
3526 }
3527
3528 static void vl_api_flow_classify_details_t_handler_json
3529   (vl_api_flow_classify_details_t * mp)
3530 {
3531   vat_main_t *vam = &vat_main;
3532   vat_json_node_t *node;
3533
3534   if (VAT_JSON_ARRAY != vam->json_tree.type)
3535     {
3536       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3537       vat_json_init_array (&vam->json_tree);
3538     }
3539   node = vat_json_array_add (&vam->json_tree);
3540
3541   vat_json_init_object (node);
3542   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3543   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3544 }
3545
3546
3547
3548 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3549 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3550 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3551 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3552 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3553 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3554
3555 /*
3556  * Generate boilerplate reply handlers, which
3557  * dig the return value out of the xxx_reply_t API message,
3558  * stick it into vam->retval, and set vam->result_ready
3559  *
3560  * Could also do this by pointing N message decode slots at
3561  * a single function, but that could break in subtle ways.
3562  */
3563
3564 #define foreach_standard_reply_retval_handler           \
3565 _(sw_interface_set_flags_reply)                         \
3566 _(sw_interface_add_del_address_reply)                   \
3567 _(sw_interface_set_table_reply)                         \
3568 _(sw_interface_set_mpls_enable_reply)                   \
3569 _(sw_interface_set_vpath_reply)                         \
3570 _(sw_interface_set_vxlan_bypass_reply)                  \
3571 _(sw_interface_set_l2_bridge_reply)                     \
3572 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3573 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3574 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3575 _(bridge_domain_add_del_reply)                          \
3576 _(sw_interface_set_l2_xconnect_reply)                   \
3577 _(l2fib_add_del_reply)                                  \
3578 _(ip_add_del_route_reply)                               \
3579 _(mpls_route_add_del_reply)                             \
3580 _(mpls_ip_bind_unbind_reply)                            \
3581 _(proxy_arp_add_del_reply)                              \
3582 _(proxy_arp_intfc_enable_disable_reply)                 \
3583 _(sw_interface_set_unnumbered_reply)                    \
3584 _(ip_neighbor_add_del_reply)                            \
3585 _(reset_vrf_reply)                                      \
3586 _(oam_add_del_reply)                                    \
3587 _(reset_fib_reply)                                      \
3588 _(dhcp_proxy_config_reply)                              \
3589 _(dhcp_proxy_config_2_reply)                            \
3590 _(dhcp_proxy_set_vss_reply)                             \
3591 _(dhcp_client_config_reply)                             \
3592 _(set_ip_flow_hash_reply)                               \
3593 _(sw_interface_ip6_enable_disable_reply)                \
3594 _(sw_interface_ip6_set_link_local_address_reply)        \
3595 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3596 _(sw_interface_ip6nd_ra_config_reply)                   \
3597 _(set_arp_neighbor_limit_reply)                         \
3598 _(l2_patch_add_del_reply)                               \
3599 _(sr_tunnel_add_del_reply)                              \
3600 _(sr_policy_add_del_reply)                              \
3601 _(sr_multicast_map_add_del_reply)                       \
3602 _(classify_add_del_session_reply)                       \
3603 _(classify_set_interface_ip_table_reply)                \
3604 _(classify_set_interface_l2_tables_reply)               \
3605 _(l2tpv3_set_tunnel_cookies_reply)                      \
3606 _(l2tpv3_interface_enable_disable_reply)                \
3607 _(l2tpv3_set_lookup_key_reply)                          \
3608 _(l2_fib_clear_table_reply)                             \
3609 _(l2_interface_efp_filter_reply)                        \
3610 _(l2_interface_vlan_tag_rewrite_reply)                  \
3611 _(modify_vhost_user_if_reply)                           \
3612 _(delete_vhost_user_if_reply)                           \
3613 _(want_ip4_arp_events_reply)                            \
3614 _(want_ip6_nd_events_reply)                             \
3615 _(input_acl_set_interface_reply)                        \
3616 _(ipsec_spd_add_del_reply)                              \
3617 _(ipsec_interface_add_del_spd_reply)                    \
3618 _(ipsec_spd_add_del_entry_reply)                        \
3619 _(ipsec_sad_add_del_entry_reply)                        \
3620 _(ipsec_sa_set_key_reply)                               \
3621 _(ikev2_profile_add_del_reply)                          \
3622 _(ikev2_profile_set_auth_reply)                         \
3623 _(ikev2_profile_set_id_reply)                           \
3624 _(ikev2_profile_set_ts_reply)                           \
3625 _(ikev2_set_local_key_reply)                            \
3626 _(delete_loopback_reply)                                \
3627 _(bd_ip_mac_add_del_reply)                              \
3628 _(map_del_domain_reply)                                 \
3629 _(map_add_del_rule_reply)                               \
3630 _(want_interface_events_reply)                          \
3631 _(want_stats_reply)                                     \
3632 _(cop_interface_enable_disable_reply)                   \
3633 _(cop_whitelist_enable_disable_reply)                   \
3634 _(sw_interface_clear_stats_reply)                       \
3635 _(ioam_enable_reply)                              \
3636 _(ioam_disable_reply)                              \
3637 _(lisp_add_del_locator_reply)                           \
3638 _(lisp_add_del_local_eid_reply)                         \
3639 _(lisp_add_del_remote_mapping_reply)                    \
3640 _(lisp_add_del_adjacency_reply)                         \
3641 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3642 _(lisp_add_del_map_resolver_reply)                      \
3643 _(lisp_add_del_map_server_reply)                        \
3644 _(lisp_gpe_enable_disable_reply)                        \
3645 _(lisp_gpe_add_del_iface_reply)                         \
3646 _(lisp_enable_disable_reply)                            \
3647 _(lisp_rloc_probe_enable_disable_reply)                 \
3648 _(lisp_map_register_enable_disable_reply)               \
3649 _(lisp_pitr_set_locator_set_reply)                      \
3650 _(lisp_map_request_mode_reply)                          \
3651 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3652 _(lisp_eid_table_add_del_map_reply)                     \
3653 _(vxlan_gpe_add_del_tunnel_reply)                       \
3654 _(af_packet_delete_reply)                               \
3655 _(policer_classify_set_interface_reply)                 \
3656 _(netmap_create_reply)                                  \
3657 _(netmap_delete_reply)                                  \
3658 _(set_ipfix_exporter_reply)                             \
3659 _(set_ipfix_classify_stream_reply)                      \
3660 _(ipfix_classify_table_add_del_reply)                   \
3661 _(flow_classify_set_interface_reply)                    \
3662 _(sw_interface_span_enable_disable_reply)               \
3663 _(pg_capture_reply)                                     \
3664 _(pg_enable_disable_reply)                              \
3665 _(ip_source_and_port_range_check_add_del_reply)         \
3666 _(ip_source_and_port_range_check_interface_add_del_reply)\
3667 _(delete_subif_reply)                                   \
3668 _(l2_interface_pbb_tag_rewrite_reply)                   \
3669 _(punt_reply)                                           \
3670 _(feature_enable_disable_reply)                         \
3671 _(sw_interface_tag_add_del_reply)                       \
3672 _(sw_interface_set_mtu_reply)
3673
3674 #define _(n)                                    \
3675     static void vl_api_##n##_t_handler          \
3676     (vl_api_##n##_t * mp)                       \
3677     {                                           \
3678         vat_main_t * vam = &vat_main;           \
3679         i32 retval = ntohl(mp->retval);         \
3680         if (vam->async_mode) {                  \
3681             vam->async_errors += (retval < 0);  \
3682         } else {                                \
3683             vam->retval = retval;               \
3684             vam->result_ready = 1;              \
3685         }                                       \
3686     }
3687 foreach_standard_reply_retval_handler;
3688 #undef _
3689
3690 #define _(n)                                    \
3691     static void vl_api_##n##_t_handler_json     \
3692     (vl_api_##n##_t * mp)                       \
3693     {                                           \
3694         vat_main_t * vam = &vat_main;           \
3695         vat_json_node_t node;                   \
3696         vat_json_init_object(&node);            \
3697         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3698         vat_json_print(vam->ofp, &node);        \
3699         vam->retval = ntohl(mp->retval);        \
3700         vam->result_ready = 1;                  \
3701     }
3702 foreach_standard_reply_retval_handler;
3703 #undef _
3704
3705 /*
3706  * Table of message reply handlers, must include boilerplate handlers
3707  * we just generated
3708  */
3709
3710 #define foreach_vpe_api_reply_msg                                       \
3711 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3712 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3713 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3714 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3715 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3716 _(CLI_REPLY, cli_reply)                                                 \
3717 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3718 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3719   sw_interface_add_del_address_reply)                                   \
3720 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3721 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3722 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3723 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3724 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3725   sw_interface_set_l2_xconnect_reply)                                   \
3726 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3727   sw_interface_set_l2_bridge_reply)                                     \
3728 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3729   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3730 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3731   sw_interface_set_dpdk_hqos_subport_reply)                             \
3732 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3733   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3734 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3735 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3736 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3737 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3738 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3739 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3740 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3741 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3742 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3743 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3744 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3745 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3746 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3747 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3748 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3749   proxy_arp_intfc_enable_disable_reply)                                 \
3750 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
3751 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3752   sw_interface_set_unnumbered_reply)                                    \
3753 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3754 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3755 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3756 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3757 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3758 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3759 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3760 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3761 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3762 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3763 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3764 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3765   sw_interface_ip6_enable_disable_reply)                                \
3766 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3767   sw_interface_ip6_set_link_local_address_reply)                        \
3768 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3769   sw_interface_ip6nd_ra_prefix_reply)                                   \
3770 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3771   sw_interface_ip6nd_ra_config_reply)                                   \
3772 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3773 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3774 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3775 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3776 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3777 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3778 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3779 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3780 classify_set_interface_ip_table_reply)                                  \
3781 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3782   classify_set_interface_l2_tables_reply)                               \
3783 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3784 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3785 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3786 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3787 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3788   l2tpv3_interface_enable_disable_reply)                                \
3789 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3790 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3791 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3792 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3793 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3794 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3795 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3796 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3797 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3798 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3799 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3800 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3801 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3802 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3803 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3804 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3805 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3806 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3807 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3808 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3809 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3810 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3811 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3812 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3813 _(IP_DETAILS, ip_details)                                               \
3814 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3815 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3816 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3817 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3818 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3819 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3820 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3821 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3822 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3823 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3824 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3825 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3826 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3827 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3828 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3829 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3830 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3831 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3832 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3833 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3834 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3835 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3836 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3837 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3838 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3839 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3840 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3841 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3842 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3843 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3844 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3845 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3846 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3847 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3848 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3849 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3850 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3851 _(LISP_ADD_DEL_MAP_SERVER_REPLY, lisp_add_del_map_server_reply)         \
3852 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3853 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3854 _(LISP_MAP_REGISTER_ENABLE_DISABLE_REPLY,                               \
3855   lisp_map_register_enable_disable_reply)                               \
3856 _(LISP_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                 \
3857   lisp_rloc_probe_enable_disable_reply)                                 \
3858 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3859 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3860 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3861 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3862 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3863 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3864 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3865 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3866 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3867 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3868 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3869 _(LISP_MAP_SERVER_DETAILS, lisp_map_server_details)                     \
3870 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3871 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3872 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3873   lisp_add_del_map_request_itr_rlocs_reply)                             \
3874 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3875   lisp_get_map_request_itr_rlocs_reply)                                 \
3876 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3877 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3878 _(SHOW_LISP_RLOC_PROBE_STATE_REPLY, show_lisp_rloc_probe_state_reply)   \
3879 _(SHOW_LISP_MAP_REGISTER_STATE_REPLY,                                   \
3880   show_lisp_map_register_state_reply)                                   \
3881 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3882 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3883 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3884 _(POLICER_DETAILS, policer_details)                                     \
3885 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3886 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3887 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3888 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3889 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
3890 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3891 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3892 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3893 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3894 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3895 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3896 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3897 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3898 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3899 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3900 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3901 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3902 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3903 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3904 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3905 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3906 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3907 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3908 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3909 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3910  ip_source_and_port_range_check_add_del_reply)                          \
3911 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3912  ip_source_and_port_range_check_interface_add_del_reply)                \
3913 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3914 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3915 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3916 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3917 _(PUNT_REPLY, punt_reply)                                               \
3918 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3919 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
3920 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
3921 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
3922 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
3923 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
3924 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)
3925
3926 /* M: construct, but don't yet send a message */
3927
3928 #define M(T,t)                                  \
3929 do {                                            \
3930     vam->result_ready = 0;                      \
3931     mp = vl_msg_api_alloc(sizeof(*mp));         \
3932     memset (mp, 0, sizeof (*mp));               \
3933     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3934     mp->client_index = vam->my_client_index;    \
3935 } while(0);
3936
3937 #define M2(T,t,n)                               \
3938 do {                                            \
3939     vam->result_ready = 0;                      \
3940     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3941     memset (mp, 0, sizeof (*mp));               \
3942     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3943     mp->client_index = vam->my_client_index;    \
3944 } while(0);
3945
3946
3947 /* S: send a message */
3948 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3949
3950 /* W: wait for results, with timeout */
3951 #define W                                       \
3952 do {                                            \
3953     timeout = vat_time_now (vam) + 1.0;         \
3954                                                 \
3955     while (vat_time_now (vam) < timeout) {      \
3956         if (vam->result_ready == 1) {           \
3957             return (vam->retval);               \
3958         }                                       \
3959     }                                           \
3960     return -99;                                 \
3961 } while(0);
3962
3963 /* W2: wait for results, with timeout */
3964 #define W2(body)                                \
3965 do {                                            \
3966     timeout = vat_time_now (vam) + 1.0;         \
3967                                                 \
3968     while (vat_time_now (vam) < timeout) {      \
3969         if (vam->result_ready == 1) {           \
3970           (body);                               \
3971           return (vam->retval);                 \
3972         }                                       \
3973     }                                           \
3974     return -99;                                 \
3975 } while(0);
3976
3977 typedef struct
3978 {
3979   u8 *name;
3980   u32 value;
3981 } name_sort_t;
3982
3983
3984 #define STR_VTR_OP_CASE(op)     \
3985     case L2_VTR_ ## op:         \
3986         return "" # op;
3987
3988 static const char *
3989 str_vtr_op (u32 vtr_op)
3990 {
3991   switch (vtr_op)
3992     {
3993       STR_VTR_OP_CASE (DISABLED);
3994       STR_VTR_OP_CASE (PUSH_1);
3995       STR_VTR_OP_CASE (PUSH_2);
3996       STR_VTR_OP_CASE (POP_1);
3997       STR_VTR_OP_CASE (POP_2);
3998       STR_VTR_OP_CASE (TRANSLATE_1_1);
3999       STR_VTR_OP_CASE (TRANSLATE_1_2);
4000       STR_VTR_OP_CASE (TRANSLATE_2_1);
4001       STR_VTR_OP_CASE (TRANSLATE_2_2);
4002     }
4003
4004   return "UNKNOWN";
4005 }
4006
4007 static int
4008 dump_sub_interface_table (vat_main_t * vam)
4009 {
4010   const sw_interface_subif_t *sub = NULL;
4011
4012   if (vam->json_output)
4013     {
4014       clib_warning
4015         ("JSON output supported only for VPE API calls and dump_stats_table");
4016       return -99;
4017     }
4018
4019   fformat (vam->ofp,
4020            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
4021            "Interface", "sw_if_index",
4022            "sub id", "dot1ad", "tags", "outer id",
4023            "inner id", "exact", "default", "outer any", "inner any");
4024
4025   vec_foreach (sub, vam->sw_if_subif_table)
4026   {
4027     fformat (vam->ofp,
4028              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
4029              sub->interface_name,
4030              sub->sw_if_index,
4031              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4032              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4033              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4034              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4035     if (sub->vtr_op != L2_VTR_DISABLED)
4036       {
4037         fformat (vam->ofp,
4038                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4039                  "tag1: %d tag2: %d ]\n",
4040                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4041                  sub->vtr_tag1, sub->vtr_tag2);
4042       }
4043   }
4044
4045   return 0;
4046 }
4047
4048 static int
4049 name_sort_cmp (void *a1, void *a2)
4050 {
4051   name_sort_t *n1 = a1;
4052   name_sort_t *n2 = a2;
4053
4054   return strcmp ((char *) n1->name, (char *) n2->name);
4055 }
4056
4057 static int
4058 dump_interface_table (vat_main_t * vam)
4059 {
4060   hash_pair_t *p;
4061   name_sort_t *nses = 0, *ns;
4062
4063   if (vam->json_output)
4064     {
4065       clib_warning
4066         ("JSON output supported only for VPE API calls and dump_stats_table");
4067       return -99;
4068     }
4069
4070   /* *INDENT-OFF* */
4071   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4072   ({
4073     vec_add2 (nses, ns, 1);
4074     ns->name = (u8 *)(p->key);
4075     ns->value = (u32) p->value[0];
4076   }));
4077   /* *INDENT-ON* */
4078
4079   vec_sort_with_function (nses, name_sort_cmp);
4080
4081   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
4082   vec_foreach (ns, nses)
4083   {
4084     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
4085   }
4086   vec_free (nses);
4087   return 0;
4088 }
4089
4090 static int
4091 dump_ip_table (vat_main_t * vam, int is_ipv6)
4092 {
4093   const ip_details_t *det = NULL;
4094   const ip_address_details_t *address = NULL;
4095   u32 i = ~0;
4096
4097   fformat (vam->ofp, "%-12s\n", "sw_if_index");
4098
4099   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4100   {
4101     i++;
4102     if (!det->present)
4103       {
4104         continue;
4105       }
4106     fformat (vam->ofp, "%-12d\n", i);
4107     fformat (vam->ofp,
4108              "            %-30s%-13s\n", "Address", "Prefix length");
4109     if (!det->addr)
4110       {
4111         continue;
4112       }
4113     vec_foreach (address, det->addr)
4114     {
4115       fformat (vam->ofp,
4116                "            %-30U%-13d\n",
4117                is_ipv6 ? format_ip6_address : format_ip4_address,
4118                address->ip, address->prefix_length);
4119     }
4120   }
4121
4122   return 0;
4123 }
4124
4125 static int
4126 dump_ipv4_table (vat_main_t * vam)
4127 {
4128   if (vam->json_output)
4129     {
4130       clib_warning
4131         ("JSON output supported only for VPE API calls and dump_stats_table");
4132       return -99;
4133     }
4134
4135   return dump_ip_table (vam, 0);
4136 }
4137
4138 static int
4139 dump_ipv6_table (vat_main_t * vam)
4140 {
4141   if (vam->json_output)
4142     {
4143       clib_warning
4144         ("JSON output supported only for VPE API calls and dump_stats_table");
4145       return -99;
4146     }
4147
4148   return dump_ip_table (vam, 1);
4149 }
4150
4151 static char *
4152 counter_type_to_str (u8 counter_type, u8 is_combined)
4153 {
4154   if (!is_combined)
4155     {
4156       switch (counter_type)
4157         {
4158         case VNET_INTERFACE_COUNTER_DROP:
4159           return "drop";
4160         case VNET_INTERFACE_COUNTER_PUNT:
4161           return "punt";
4162         case VNET_INTERFACE_COUNTER_IP4:
4163           return "ip4";
4164         case VNET_INTERFACE_COUNTER_IP6:
4165           return "ip6";
4166         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4167           return "rx-no-buf";
4168         case VNET_INTERFACE_COUNTER_RX_MISS:
4169           return "rx-miss";
4170         case VNET_INTERFACE_COUNTER_RX_ERROR:
4171           return "rx-error";
4172         case VNET_INTERFACE_COUNTER_TX_ERROR:
4173           return "tx-error";
4174         default:
4175           return "INVALID-COUNTER-TYPE";
4176         }
4177     }
4178   else
4179     {
4180       switch (counter_type)
4181         {
4182         case VNET_INTERFACE_COUNTER_RX:
4183           return "rx";
4184         case VNET_INTERFACE_COUNTER_TX:
4185           return "tx";
4186         default:
4187           return "INVALID-COUNTER-TYPE";
4188         }
4189     }
4190 }
4191
4192 static int
4193 dump_stats_table (vat_main_t * vam)
4194 {
4195   vat_json_node_t node;
4196   vat_json_node_t *msg_array;
4197   vat_json_node_t *msg;
4198   vat_json_node_t *counter_array;
4199   vat_json_node_t *counter;
4200   interface_counter_t c;
4201   u64 packets;
4202   ip4_fib_counter_t *c4;
4203   ip6_fib_counter_t *c6;
4204   int i, j;
4205
4206   if (!vam->json_output)
4207     {
4208       clib_warning ("dump_stats_table supported only in JSON format");
4209       return -99;
4210     }
4211
4212   vat_json_init_object (&node);
4213
4214   /* interface counters */
4215   msg_array = vat_json_object_add (&node, "interface_counters");
4216   vat_json_init_array (msg_array);
4217   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4218     {
4219       msg = vat_json_array_add (msg_array);
4220       vat_json_init_object (msg);
4221       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4222                                        (u8 *) counter_type_to_str (i, 0));
4223       vat_json_object_add_int (msg, "is_combined", 0);
4224       counter_array = vat_json_object_add (msg, "data");
4225       vat_json_init_array (counter_array);
4226       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4227         {
4228           packets = vam->simple_interface_counters[i][j];
4229           vat_json_array_add_uint (counter_array, packets);
4230         }
4231     }
4232   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4233     {
4234       msg = vat_json_array_add (msg_array);
4235       vat_json_init_object (msg);
4236       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4237                                        (u8 *) counter_type_to_str (i, 1));
4238       vat_json_object_add_int (msg, "is_combined", 1);
4239       counter_array = vat_json_object_add (msg, "data");
4240       vat_json_init_array (counter_array);
4241       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4242         {
4243           c = vam->combined_interface_counters[i][j];
4244           counter = vat_json_array_add (counter_array);
4245           vat_json_init_object (counter);
4246           vat_json_object_add_uint (counter, "packets", c.packets);
4247           vat_json_object_add_uint (counter, "bytes", c.bytes);
4248         }
4249     }
4250
4251   /* ip4 fib counters */
4252   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4253   vat_json_init_array (msg_array);
4254   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4255     {
4256       msg = vat_json_array_add (msg_array);
4257       vat_json_init_object (msg);
4258       vat_json_object_add_uint (msg, "vrf_id",
4259                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4260       counter_array = vat_json_object_add (msg, "c");
4261       vat_json_init_array (counter_array);
4262       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4263         {
4264           counter = vat_json_array_add (counter_array);
4265           vat_json_init_object (counter);
4266           c4 = &vam->ip4_fib_counters[i][j];
4267           vat_json_object_add_ip4 (counter, "address", c4->address);
4268           vat_json_object_add_uint (counter, "address_length",
4269                                     c4->address_length);
4270           vat_json_object_add_uint (counter, "packets", c4->packets);
4271           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4272         }
4273     }
4274
4275   /* ip6 fib counters */
4276   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4277   vat_json_init_array (msg_array);
4278   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4279     {
4280       msg = vat_json_array_add (msg_array);
4281       vat_json_init_object (msg);
4282       vat_json_object_add_uint (msg, "vrf_id",
4283                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4284       counter_array = vat_json_object_add (msg, "c");
4285       vat_json_init_array (counter_array);
4286       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4287         {
4288           counter = vat_json_array_add (counter_array);
4289           vat_json_init_object (counter);
4290           c6 = &vam->ip6_fib_counters[i][j];
4291           vat_json_object_add_ip6 (counter, "address", c6->address);
4292           vat_json_object_add_uint (counter, "address_length",
4293                                     c6->address_length);
4294           vat_json_object_add_uint (counter, "packets", c6->packets);
4295           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4296         }
4297     }
4298
4299   vat_json_print (vam->ofp, &node);
4300   vat_json_free (&node);
4301
4302   return 0;
4303 }
4304
4305 int
4306 exec (vat_main_t * vam)
4307 {
4308   api_main_t *am = &api_main;
4309   vl_api_cli_request_t *mp;
4310   f64 timeout;
4311   void *oldheap;
4312   u8 *cmd = 0;
4313   unformat_input_t *i = vam->input;
4314
4315   if (vec_len (i->buffer) == 0)
4316     return -1;
4317
4318   if (vam->exec_mode == 0 && unformat (i, "mode"))
4319     {
4320       vam->exec_mode = 1;
4321       return 0;
4322     }
4323   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4324     {
4325       vam->exec_mode = 0;
4326       return 0;
4327     }
4328
4329
4330   M (CLI_REQUEST, cli_request);
4331
4332   /*
4333    * Copy cmd into shared memory.
4334    * In order for the CLI command to work, it
4335    * must be a vector ending in \n, not a C-string ending
4336    * in \n\0.
4337    */
4338   pthread_mutex_lock (&am->vlib_rp->mutex);
4339   oldheap = svm_push_data_heap (am->vlib_rp);
4340
4341   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4342   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4343
4344   svm_pop_heap (oldheap);
4345   pthread_mutex_unlock (&am->vlib_rp->mutex);
4346
4347   mp->cmd_in_shmem = (u64) cmd;
4348   S;
4349   timeout = vat_time_now (vam) + 10.0;
4350
4351   while (vat_time_now (vam) < timeout)
4352     {
4353       if (vam->result_ready == 1)
4354         {
4355           u8 *free_me;
4356           if (vam->shmem_result != NULL)
4357             fformat (vam->ofp, "%s", vam->shmem_result);
4358           pthread_mutex_lock (&am->vlib_rp->mutex);
4359           oldheap = svm_push_data_heap (am->vlib_rp);
4360
4361           free_me = (u8 *) vam->shmem_result;
4362           vec_free (free_me);
4363
4364           svm_pop_heap (oldheap);
4365           pthread_mutex_unlock (&am->vlib_rp->mutex);
4366           return 0;
4367         }
4368     }
4369   return -99;
4370 }
4371
4372 /*
4373  * Future replacement of exec() that passes CLI buffers directly in
4374  * the API messages instead of an additional shared memory area.
4375  */
4376 static int
4377 exec_inband (vat_main_t * vam)
4378 {
4379   vl_api_cli_inband_t *mp;
4380   f64 timeout;
4381   unformat_input_t *i = vam->input;
4382
4383   if (vec_len (i->buffer) == 0)
4384     return -1;
4385
4386   if (vam->exec_mode == 0 && unformat (i, "mode"))
4387     {
4388       vam->exec_mode = 1;
4389       return 0;
4390     }
4391   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4392     {
4393       vam->exec_mode = 0;
4394       return 0;
4395     }
4396
4397   /*
4398    * In order for the CLI command to work, it
4399    * must be a vector ending in \n, not a C-string ending
4400    * in \n\0.
4401    */
4402   u32 len = vec_len (vam->input->buffer);
4403   M2 (CLI_INBAND, cli_inband, len);
4404   clib_memcpy (mp->cmd, vam->input->buffer, len);
4405   mp->length = htonl (len);
4406
4407   S;
4408   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4409 }
4410
4411 static int
4412 api_create_loopback (vat_main_t * vam)
4413 {
4414   unformat_input_t *i = vam->input;
4415   vl_api_create_loopback_t *mp;
4416   f64 timeout;
4417   u8 mac_address[6];
4418   u8 mac_set = 0;
4419
4420   memset (mac_address, 0, sizeof (mac_address));
4421
4422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4423     {
4424       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4425         mac_set = 1;
4426       else
4427         break;
4428     }
4429
4430   /* Construct the API message */
4431   M (CREATE_LOOPBACK, create_loopback);
4432   if (mac_set)
4433     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4434
4435   S;
4436   W;
4437 }
4438
4439 static int
4440 api_delete_loopback (vat_main_t * vam)
4441 {
4442   unformat_input_t *i = vam->input;
4443   vl_api_delete_loopback_t *mp;
4444   f64 timeout;
4445   u32 sw_if_index = ~0;
4446
4447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4448     {
4449       if (unformat (i, "sw_if_index %d", &sw_if_index))
4450         ;
4451       else
4452         break;
4453     }
4454
4455   if (sw_if_index == ~0)
4456     {
4457       errmsg ("missing sw_if_index\n");
4458       return -99;
4459     }
4460
4461   /* Construct the API message */
4462   M (DELETE_LOOPBACK, delete_loopback);
4463   mp->sw_if_index = ntohl (sw_if_index);
4464
4465   S;
4466   W;
4467 }
4468
4469 static int
4470 api_want_stats (vat_main_t * vam)
4471 {
4472   unformat_input_t *i = vam->input;
4473   vl_api_want_stats_t *mp;
4474   f64 timeout;
4475   int enable = -1;
4476
4477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4478     {
4479       if (unformat (i, "enable"))
4480         enable = 1;
4481       else if (unformat (i, "disable"))
4482         enable = 0;
4483       else
4484         break;
4485     }
4486
4487   if (enable == -1)
4488     {
4489       errmsg ("missing enable|disable\n");
4490       return -99;
4491     }
4492
4493   M (WANT_STATS, want_stats);
4494   mp->enable_disable = enable;
4495
4496   S;
4497   W;
4498 }
4499
4500 static int
4501 api_want_interface_events (vat_main_t * vam)
4502 {
4503   unformat_input_t *i = vam->input;
4504   vl_api_want_interface_events_t *mp;
4505   f64 timeout;
4506   int enable = -1;
4507
4508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4509     {
4510       if (unformat (i, "enable"))
4511         enable = 1;
4512       else if (unformat (i, "disable"))
4513         enable = 0;
4514       else
4515         break;
4516     }
4517
4518   if (enable == -1)
4519     {
4520       errmsg ("missing enable|disable\n");
4521       return -99;
4522     }
4523
4524   M (WANT_INTERFACE_EVENTS, want_interface_events);
4525   mp->enable_disable = enable;
4526
4527   vam->interface_event_display = enable;
4528
4529   S;
4530   W;
4531 }
4532
4533
4534 /* Note: non-static, called once to set up the initial intfc table */
4535 int
4536 api_sw_interface_dump (vat_main_t * vam)
4537 {
4538   vl_api_sw_interface_dump_t *mp;
4539   f64 timeout;
4540   hash_pair_t *p;
4541   name_sort_t *nses = 0, *ns;
4542   sw_interface_subif_t *sub = NULL;
4543
4544   /* Toss the old name table */
4545   /* *INDENT-OFF* */
4546   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4547   ({
4548     vec_add2 (nses, ns, 1);
4549     ns->name = (u8 *)(p->key);
4550     ns->value = (u32) p->value[0];
4551   }));
4552   /* *INDENT-ON* */
4553
4554   hash_free (vam->sw_if_index_by_interface_name);
4555
4556   vec_foreach (ns, nses) vec_free (ns->name);
4557
4558   vec_free (nses);
4559
4560   vec_foreach (sub, vam->sw_if_subif_table)
4561   {
4562     vec_free (sub->interface_name);
4563   }
4564   vec_free (vam->sw_if_subif_table);
4565
4566   /* recreate the interface name hash table */
4567   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4568
4569   /* Get list of ethernets */
4570   M (SW_INTERFACE_DUMP, sw_interface_dump);
4571   mp->name_filter_valid = 1;
4572   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4573   S;
4574
4575   /* and local / loopback interfaces */
4576   M (SW_INTERFACE_DUMP, sw_interface_dump);
4577   mp->name_filter_valid = 1;
4578   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4579   S;
4580
4581   /* and packet-generator interfaces */
4582   M (SW_INTERFACE_DUMP, sw_interface_dump);
4583   mp->name_filter_valid = 1;
4584   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4585   S;
4586
4587   /* and vxlan-gpe tunnel interfaces */
4588   M (SW_INTERFACE_DUMP, sw_interface_dump);
4589   mp->name_filter_valid = 1;
4590   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4591            sizeof (mp->name_filter) - 1);
4592   S;
4593
4594   /* and vxlan tunnel interfaces */
4595   M (SW_INTERFACE_DUMP, sw_interface_dump);
4596   mp->name_filter_valid = 1;
4597   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4598   S;
4599
4600   /* and host (af_packet) interfaces */
4601   M (SW_INTERFACE_DUMP, sw_interface_dump);
4602   mp->name_filter_valid = 1;
4603   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4604   S;
4605
4606   /* and l2tpv3 tunnel interfaces */
4607   M (SW_INTERFACE_DUMP, sw_interface_dump);
4608   mp->name_filter_valid = 1;
4609   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4610            sizeof (mp->name_filter) - 1);
4611   S;
4612
4613   /* and GRE tunnel interfaces */
4614   M (SW_INTERFACE_DUMP, sw_interface_dump);
4615   mp->name_filter_valid = 1;
4616   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4617   S;
4618
4619   /* and LISP-GPE interfaces */
4620   M (SW_INTERFACE_DUMP, sw_interface_dump);
4621   mp->name_filter_valid = 1;
4622   strncpy ((char *) mp->name_filter, "lisp_gpe",
4623            sizeof (mp->name_filter) - 1);
4624   S;
4625
4626   /* and IPSEC tunnel interfaces */
4627   M (SW_INTERFACE_DUMP, sw_interface_dump);
4628   mp->name_filter_valid = 1;
4629   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4630   S;
4631
4632   /* Use a control ping for synchronization */
4633   {
4634     vl_api_control_ping_t *mp;
4635     M (CONTROL_PING, control_ping);
4636     S;
4637   }
4638   W;
4639 }
4640
4641 static int
4642 api_sw_interface_set_flags (vat_main_t * vam)
4643 {
4644   unformat_input_t *i = vam->input;
4645   vl_api_sw_interface_set_flags_t *mp;
4646   f64 timeout;
4647   u32 sw_if_index;
4648   u8 sw_if_index_set = 0;
4649   u8 admin_up = 0, link_up = 0;
4650
4651   /* Parse args required to build the message */
4652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4653     {
4654       if (unformat (i, "admin-up"))
4655         admin_up = 1;
4656       else if (unformat (i, "admin-down"))
4657         admin_up = 0;
4658       else if (unformat (i, "link-up"))
4659         link_up = 1;
4660       else if (unformat (i, "link-down"))
4661         link_up = 0;
4662       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4663         sw_if_index_set = 1;
4664       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4665         sw_if_index_set = 1;
4666       else
4667         break;
4668     }
4669
4670   if (sw_if_index_set == 0)
4671     {
4672       errmsg ("missing interface name or sw_if_index\n");
4673       return -99;
4674     }
4675
4676   /* Construct the API message */
4677   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4678   mp->sw_if_index = ntohl (sw_if_index);
4679   mp->admin_up_down = admin_up;
4680   mp->link_up_down = link_up;
4681
4682   /* send it... */
4683   S;
4684
4685   /* Wait for a reply, return the good/bad news... */
4686   W;
4687 }
4688
4689 static int
4690 api_sw_interface_clear_stats (vat_main_t * vam)
4691 {
4692   unformat_input_t *i = vam->input;
4693   vl_api_sw_interface_clear_stats_t *mp;
4694   f64 timeout;
4695   u32 sw_if_index;
4696   u8 sw_if_index_set = 0;
4697
4698   /* Parse args required to build the message */
4699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4700     {
4701       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4702         sw_if_index_set = 1;
4703       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4704         sw_if_index_set = 1;
4705       else
4706         break;
4707     }
4708
4709   /* Construct the API message */
4710   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4711
4712   if (sw_if_index_set == 1)
4713     mp->sw_if_index = ntohl (sw_if_index);
4714   else
4715     mp->sw_if_index = ~0;
4716
4717   /* send it... */
4718   S;
4719
4720   /* Wait for a reply, return the good/bad news... */
4721   W;
4722 }
4723
4724 static int
4725 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4726 {
4727   unformat_input_t *i = vam->input;
4728   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4729   f64 timeout;
4730   u32 sw_if_index;
4731   u8 sw_if_index_set = 0;
4732   u32 subport;
4733   u8 subport_set = 0;
4734   u32 pipe;
4735   u8 pipe_set = 0;
4736   u32 profile;
4737   u8 profile_set = 0;
4738
4739   /* Parse args required to build the message */
4740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4741     {
4742       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4743         sw_if_index_set = 1;
4744       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4745         sw_if_index_set = 1;
4746       else if (unformat (i, "subport %u", &subport))
4747         subport_set = 1;
4748       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4749         sw_if_index_set = 1;
4750       else if (unformat (i, "pipe %u", &pipe))
4751         pipe_set = 1;
4752       else if (unformat (i, "profile %u", &profile))
4753         profile_set = 1;
4754       else
4755         break;
4756     }
4757
4758   if (sw_if_index_set == 0)
4759     {
4760       errmsg ("missing interface name or sw_if_index\n");
4761       return -99;
4762     }
4763
4764   if (subport_set == 0)
4765     {
4766       errmsg ("missing subport \n");
4767       return -99;
4768     }
4769
4770   if (pipe_set == 0)
4771     {
4772       errmsg ("missing pipe\n");
4773       return -99;
4774     }
4775
4776   if (profile_set == 0)
4777     {
4778       errmsg ("missing profile\n");
4779       return -99;
4780     }
4781
4782   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4783
4784   mp->sw_if_index = ntohl (sw_if_index);
4785   mp->subport = ntohl (subport);
4786   mp->pipe = ntohl (pipe);
4787   mp->profile = ntohl (profile);
4788
4789
4790   S;
4791   W;
4792   /* NOTREACHED */
4793   return 0;
4794 }
4795
4796 static int
4797 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4798 {
4799   unformat_input_t *i = vam->input;
4800   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4801   f64 timeout;
4802   u32 sw_if_index;
4803   u8 sw_if_index_set = 0;
4804   u32 subport;
4805   u8 subport_set = 0;
4806   u32 tb_rate = 1250000000;     /* 10GbE */
4807   u32 tb_size = 1000000;
4808   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4809   u32 tc_period = 10;
4810
4811   /* Parse args required to build the message */
4812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4813     {
4814       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4815         sw_if_index_set = 1;
4816       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4817         sw_if_index_set = 1;
4818       else if (unformat (i, "subport %u", &subport))
4819         subport_set = 1;
4820       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4821         sw_if_index_set = 1;
4822       else if (unformat (i, "rate %u", &tb_rate))
4823         {
4824           u32 tc_id;
4825
4826           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4827                tc_id++)
4828             tc_rate[tc_id] = tb_rate;
4829         }
4830       else if (unformat (i, "bktsize %u", &tb_size))
4831         ;
4832       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4833         ;
4834       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4835         ;
4836       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4837         ;
4838       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4839         ;
4840       else if (unformat (i, "period %u", &tc_period))
4841         ;
4842       else
4843         break;
4844     }
4845
4846   if (sw_if_index_set == 0)
4847     {
4848       errmsg ("missing interface name or sw_if_index\n");
4849       return -99;
4850     }
4851
4852   if (subport_set == 0)
4853     {
4854       errmsg ("missing subport \n");
4855       return -99;
4856     }
4857
4858   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4859
4860   mp->sw_if_index = ntohl (sw_if_index);
4861   mp->subport = ntohl (subport);
4862   mp->tb_rate = ntohl (tb_rate);
4863   mp->tb_size = ntohl (tb_size);
4864   mp->tc_rate[0] = ntohl (tc_rate[0]);
4865   mp->tc_rate[1] = ntohl (tc_rate[1]);
4866   mp->tc_rate[2] = ntohl (tc_rate[2]);
4867   mp->tc_rate[3] = ntohl (tc_rate[3]);
4868   mp->tc_period = ntohl (tc_period);
4869
4870   S;
4871   W;
4872   /* NOTREACHED */
4873   return 0;
4874 }
4875
4876 static int
4877 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4878 {
4879   unformat_input_t *i = vam->input;
4880   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4881   f64 timeout;
4882   u32 sw_if_index;
4883   u8 sw_if_index_set = 0;
4884   u8 entry_set = 0;
4885   u8 tc_set = 0;
4886   u8 queue_set = 0;
4887   u32 entry, tc, queue;
4888
4889   /* Parse args required to build the message */
4890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4891     {
4892       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4893         sw_if_index_set = 1;
4894       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4895         sw_if_index_set = 1;
4896       else if (unformat (i, "entry %d", &entry))
4897         entry_set = 1;
4898       else if (unformat (i, "tc %d", &tc))
4899         tc_set = 1;
4900       else if (unformat (i, "queue %d", &queue))
4901         queue_set = 1;
4902       else
4903         break;
4904     }
4905
4906   if (sw_if_index_set == 0)
4907     {
4908       errmsg ("missing interface name or sw_if_index\n");
4909       return -99;
4910     }
4911
4912   if (entry_set == 0)
4913     {
4914       errmsg ("missing entry \n");
4915       return -99;
4916     }
4917
4918   if (tc_set == 0)
4919     {
4920       errmsg ("missing traffic class \n");
4921       return -99;
4922     }
4923
4924   if (queue_set == 0)
4925     {
4926       errmsg ("missing queue \n");
4927       return -99;
4928     }
4929
4930   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4931
4932   mp->sw_if_index = ntohl (sw_if_index);
4933   mp->entry = ntohl (entry);
4934   mp->tc = ntohl (tc);
4935   mp->queue = ntohl (queue);
4936
4937   S;
4938   W;
4939   /* NOTREACHED */
4940   return 0;
4941 }
4942
4943 static int
4944 api_sw_interface_add_del_address (vat_main_t * vam)
4945 {
4946   unformat_input_t *i = vam->input;
4947   vl_api_sw_interface_add_del_address_t *mp;
4948   f64 timeout;
4949   u32 sw_if_index;
4950   u8 sw_if_index_set = 0;
4951   u8 is_add = 1, del_all = 0;
4952   u32 address_length = 0;
4953   u8 v4_address_set = 0;
4954   u8 v6_address_set = 0;
4955   ip4_address_t v4address;
4956   ip6_address_t v6address;
4957
4958   /* Parse args required to build the message */
4959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4960     {
4961       if (unformat (i, "del-all"))
4962         del_all = 1;
4963       else if (unformat (i, "del"))
4964         is_add = 0;
4965       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4966         sw_if_index_set = 1;
4967       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4968         sw_if_index_set = 1;
4969       else if (unformat (i, "%U/%d",
4970                          unformat_ip4_address, &v4address, &address_length))
4971         v4_address_set = 1;
4972       else if (unformat (i, "%U/%d",
4973                          unformat_ip6_address, &v6address, &address_length))
4974         v6_address_set = 1;
4975       else
4976         break;
4977     }
4978
4979   if (sw_if_index_set == 0)
4980     {
4981       errmsg ("missing interface name or sw_if_index\n");
4982       return -99;
4983     }
4984   if (v4_address_set && v6_address_set)
4985     {
4986       errmsg ("both v4 and v6 addresses set\n");
4987       return -99;
4988     }
4989   if (!v4_address_set && !v6_address_set && !del_all)
4990     {
4991       errmsg ("no addresses set\n");
4992       return -99;
4993     }
4994
4995   /* Construct the API message */
4996   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4997
4998   mp->sw_if_index = ntohl (sw_if_index);
4999   mp->is_add = is_add;
5000   mp->del_all = del_all;
5001   if (v6_address_set)
5002     {
5003       mp->is_ipv6 = 1;
5004       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5005     }
5006   else
5007     {
5008       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5009     }
5010   mp->address_length = address_length;
5011
5012   /* send it... */
5013   S;
5014
5015   /* Wait for a reply, return good/bad news  */
5016   W;
5017 }
5018
5019 static int
5020 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5021 {
5022   unformat_input_t *i = vam->input;
5023   vl_api_sw_interface_set_mpls_enable_t *mp;
5024   f64 timeout;
5025   u32 sw_if_index;
5026   u8 sw_if_index_set = 0;
5027   u8 enable = 1;
5028
5029   /* Parse args required to build the message */
5030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5031     {
5032       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5033         sw_if_index_set = 1;
5034       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5035         sw_if_index_set = 1;
5036       else if (unformat (i, "disable"))
5037         enable = 0;
5038       else if (unformat (i, "dis"))
5039         enable = 0;
5040       else
5041         break;
5042     }
5043
5044   if (sw_if_index_set == 0)
5045     {
5046       errmsg ("missing interface name or sw_if_index\n");
5047       return -99;
5048     }
5049
5050   /* Construct the API message */
5051   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
5052
5053   mp->sw_if_index = ntohl (sw_if_index);
5054   mp->enable = enable;
5055
5056   /* send it... */
5057   S;
5058
5059   /* Wait for a reply... */
5060   W;
5061 }
5062
5063 static int
5064 api_sw_interface_set_table (vat_main_t * vam)
5065 {
5066   unformat_input_t *i = vam->input;
5067   vl_api_sw_interface_set_table_t *mp;
5068   f64 timeout;
5069   u32 sw_if_index, vrf_id = 0;
5070   u8 sw_if_index_set = 0;
5071   u8 is_ipv6 = 0;
5072
5073   /* Parse args required to build the message */
5074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5075     {
5076       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5077         sw_if_index_set = 1;
5078       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5079         sw_if_index_set = 1;
5080       else if (unformat (i, "vrf %d", &vrf_id))
5081         ;
5082       else if (unformat (i, "ipv6"))
5083         is_ipv6 = 1;
5084       else
5085         break;
5086     }
5087
5088   if (sw_if_index_set == 0)
5089     {
5090       errmsg ("missing interface name or sw_if_index\n");
5091       return -99;
5092     }
5093
5094   /* Construct the API message */
5095   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
5096
5097   mp->sw_if_index = ntohl (sw_if_index);
5098   mp->is_ipv6 = is_ipv6;
5099   mp->vrf_id = ntohl (vrf_id);
5100
5101   /* send it... */
5102   S;
5103
5104   /* Wait for a reply... */
5105   W;
5106 }
5107
5108 static int
5109 api_sw_interface_set_vpath (vat_main_t * vam)
5110 {
5111   unformat_input_t *i = vam->input;
5112   vl_api_sw_interface_set_vpath_t *mp;
5113   f64 timeout;
5114   u32 sw_if_index = 0;
5115   u8 sw_if_index_set = 0;
5116   u8 is_enable = 0;
5117
5118   /* Parse args required to build the message */
5119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5120     {
5121       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5122         sw_if_index_set = 1;
5123       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5124         sw_if_index_set = 1;
5125       else if (unformat (i, "enable"))
5126         is_enable = 1;
5127       else if (unformat (i, "disable"))
5128         is_enable = 0;
5129       else
5130         break;
5131     }
5132
5133   if (sw_if_index_set == 0)
5134     {
5135       errmsg ("missing interface name or sw_if_index\n");
5136       return -99;
5137     }
5138
5139   /* Construct the API message */
5140   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5141
5142   mp->sw_if_index = ntohl (sw_if_index);
5143   mp->enable = is_enable;
5144
5145   /* send it... */
5146   S;
5147
5148   /* Wait for a reply... */
5149   W;
5150 }
5151
5152 static int
5153 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5154 {
5155   unformat_input_t *i = vam->input;
5156   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5157   f64 timeout;
5158   u32 sw_if_index = 0;
5159   u8 sw_if_index_set = 0;
5160   u8 is_enable = 0;
5161   u8 is_ipv6 = 0;
5162
5163   /* Parse args required to build the message */
5164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5165     {
5166       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5167         sw_if_index_set = 1;
5168       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5169         sw_if_index_set = 1;
5170       else if (unformat (i, "enable"))
5171         is_enable = 1;
5172       else if (unformat (i, "disable"))
5173         is_enable = 0;
5174       else if (unformat (i, "ip4"))
5175         is_ipv6 = 0;
5176       else if (unformat (i, "ip6"))
5177         is_ipv6 = 1;
5178       else
5179         break;
5180     }
5181
5182   if (sw_if_index_set == 0)
5183     {
5184       errmsg ("missing interface name or sw_if_index\n");
5185       return -99;
5186     }
5187
5188   /* Construct the API message */
5189   M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5190
5191   mp->sw_if_index = ntohl (sw_if_index);
5192   mp->enable = is_enable;
5193   mp->is_ipv6 = is_ipv6;
5194
5195   /* send it... */
5196   S;
5197
5198   /* Wait for a reply... */
5199   W;
5200 }
5201
5202 static int
5203 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5204 {
5205   unformat_input_t *i = vam->input;
5206   vl_api_sw_interface_set_l2_xconnect_t *mp;
5207   f64 timeout;
5208   u32 rx_sw_if_index;
5209   u8 rx_sw_if_index_set = 0;
5210   u32 tx_sw_if_index;
5211   u8 tx_sw_if_index_set = 0;
5212   u8 enable = 1;
5213
5214   /* Parse args required to build the message */
5215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5216     {
5217       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5218         rx_sw_if_index_set = 1;
5219       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5220         tx_sw_if_index_set = 1;
5221       else if (unformat (i, "rx"))
5222         {
5223           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5224             {
5225               if (unformat (i, "%U", unformat_sw_if_index, vam,
5226                             &rx_sw_if_index))
5227                 rx_sw_if_index_set = 1;
5228             }
5229           else
5230             break;
5231         }
5232       else if (unformat (i, "tx"))
5233         {
5234           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5235             {
5236               if (unformat (i, "%U", unformat_sw_if_index, vam,
5237                             &tx_sw_if_index))
5238                 tx_sw_if_index_set = 1;
5239             }
5240           else
5241             break;
5242         }
5243       else if (unformat (i, "enable"))
5244         enable = 1;
5245       else if (unformat (i, "disable"))
5246         enable = 0;
5247       else
5248         break;
5249     }
5250
5251   if (rx_sw_if_index_set == 0)
5252     {
5253       errmsg ("missing rx interface name or rx_sw_if_index\n");
5254       return -99;
5255     }
5256
5257   if (enable && (tx_sw_if_index_set == 0))
5258     {
5259       errmsg ("missing tx interface name or tx_sw_if_index\n");
5260       return -99;
5261     }
5262
5263   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5264
5265   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5266   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5267   mp->enable = enable;
5268
5269   S;
5270   W;
5271   /* NOTREACHED */
5272   return 0;
5273 }
5274
5275 static int
5276 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5277 {
5278   unformat_input_t *i = vam->input;
5279   vl_api_sw_interface_set_l2_bridge_t *mp;
5280   f64 timeout;
5281   u32 rx_sw_if_index;
5282   u8 rx_sw_if_index_set = 0;
5283   u32 bd_id;
5284   u8 bd_id_set = 0;
5285   u8 bvi = 0;
5286   u32 shg = 0;
5287   u8 enable = 1;
5288
5289   /* Parse args required to build the message */
5290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5291     {
5292       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5293         rx_sw_if_index_set = 1;
5294       else if (unformat (i, "bd_id %d", &bd_id))
5295         bd_id_set = 1;
5296       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5297         rx_sw_if_index_set = 1;
5298       else if (unformat (i, "shg %d", &shg))
5299         ;
5300       else if (unformat (i, "bvi"))
5301         bvi = 1;
5302       else if (unformat (i, "enable"))
5303         enable = 1;
5304       else if (unformat (i, "disable"))
5305         enable = 0;
5306       else
5307         break;
5308     }
5309
5310   if (rx_sw_if_index_set == 0)
5311     {
5312       errmsg ("missing rx interface name or sw_if_index\n");
5313       return -99;
5314     }
5315
5316   if (enable && (bd_id_set == 0))
5317     {
5318       errmsg ("missing bridge domain\n");
5319       return -99;
5320     }
5321
5322   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5323
5324   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5325   mp->bd_id = ntohl (bd_id);
5326   mp->shg = (u8) shg;
5327   mp->bvi = bvi;
5328   mp->enable = enable;
5329
5330   S;
5331   W;
5332   /* NOTREACHED */
5333   return 0;
5334 }
5335
5336 static int
5337 api_bridge_domain_dump (vat_main_t * vam)
5338 {
5339   unformat_input_t *i = vam->input;
5340   vl_api_bridge_domain_dump_t *mp;
5341   f64 timeout;
5342   u32 bd_id = ~0;
5343
5344   /* Parse args required to build the message */
5345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5346     {
5347       if (unformat (i, "bd_id %d", &bd_id))
5348         ;
5349       else
5350         break;
5351     }
5352
5353   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5354   mp->bd_id = ntohl (bd_id);
5355   S;
5356
5357   /* Use a control ping for synchronization */
5358   {
5359     vl_api_control_ping_t *mp;
5360     M (CONTROL_PING, control_ping);
5361     S;
5362   }
5363
5364   W;
5365   /* NOTREACHED */
5366   return 0;
5367 }
5368
5369 static int
5370 api_bridge_domain_add_del (vat_main_t * vam)
5371 {
5372   unformat_input_t *i = vam->input;
5373   vl_api_bridge_domain_add_del_t *mp;
5374   f64 timeout;
5375   u32 bd_id = ~0;
5376   u8 is_add = 1;
5377   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5378
5379   /* Parse args required to build the message */
5380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5381     {
5382       if (unformat (i, "bd_id %d", &bd_id))
5383         ;
5384       else if (unformat (i, "flood %d", &flood))
5385         ;
5386       else if (unformat (i, "uu-flood %d", &uu_flood))
5387         ;
5388       else if (unformat (i, "forward %d", &forward))
5389         ;
5390       else if (unformat (i, "learn %d", &learn))
5391         ;
5392       else if (unformat (i, "arp-term %d", &arp_term))
5393         ;
5394       else if (unformat (i, "del"))
5395         {
5396           is_add = 0;
5397           flood = uu_flood = forward = learn = 0;
5398         }
5399       else
5400         break;
5401     }
5402
5403   if (bd_id == ~0)
5404     {
5405       errmsg ("missing bridge domain\n");
5406       return -99;
5407     }
5408
5409   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5410
5411   mp->bd_id = ntohl (bd_id);
5412   mp->flood = flood;
5413   mp->uu_flood = uu_flood;
5414   mp->forward = forward;
5415   mp->learn = learn;
5416   mp->arp_term = arp_term;
5417   mp->is_add = is_add;
5418
5419   S;
5420   W;
5421   /* NOTREACHED */
5422   return 0;
5423 }
5424
5425 static int
5426 api_l2fib_add_del (vat_main_t * vam)
5427 {
5428   unformat_input_t *i = vam->input;
5429   vl_api_l2fib_add_del_t *mp;
5430   f64 timeout;
5431   u64 mac = 0;
5432   u8 mac_set = 0;
5433   u32 bd_id;
5434   u8 bd_id_set = 0;
5435   u32 sw_if_index = ~0;
5436   u8 sw_if_index_set = 0;
5437   u8 is_add = 1;
5438   u8 static_mac = 0;
5439   u8 filter_mac = 0;
5440   u8 bvi_mac = 0;
5441   int count = 1;
5442   f64 before = 0;
5443   int j;
5444
5445   /* Parse args required to build the message */
5446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5447     {
5448       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5449         mac_set = 1;
5450       else if (unformat (i, "bd_id %d", &bd_id))
5451         bd_id_set = 1;
5452       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5453         sw_if_index_set = 1;
5454       else if (unformat (i, "sw_if"))
5455         {
5456           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5457             {
5458               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5459                 sw_if_index_set = 1;
5460             }
5461           else
5462             break;
5463         }
5464       else if (unformat (i, "static"))
5465         static_mac = 1;
5466       else if (unformat (i, "filter"))
5467         {
5468           filter_mac = 1;
5469           static_mac = 1;
5470         }
5471       else if (unformat (i, "bvi"))
5472         {
5473           bvi_mac = 1;
5474           static_mac = 1;
5475         }
5476       else if (unformat (i, "del"))
5477         is_add = 0;
5478       else if (unformat (i, "count %d", &count))
5479         ;
5480       else
5481         break;
5482     }
5483
5484   if (mac_set == 0)
5485     {
5486       errmsg ("missing mac address\n");
5487       return -99;
5488     }
5489
5490   if (bd_id_set == 0)
5491     {
5492       errmsg ("missing bridge domain\n");
5493       return -99;
5494     }
5495
5496   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5497     {
5498       errmsg ("missing interface name or sw_if_index\n");
5499       return -99;
5500     }
5501
5502   if (count > 1)
5503     {
5504       /* Turn on async mode */
5505       vam->async_mode = 1;
5506       vam->async_errors = 0;
5507       before = vat_time_now (vam);
5508     }
5509
5510   for (j = 0; j < count; j++)
5511     {
5512       M (L2FIB_ADD_DEL, l2fib_add_del);
5513
5514       mp->mac = mac;
5515       mp->bd_id = ntohl (bd_id);
5516       mp->is_add = is_add;
5517
5518       if (is_add)
5519         {
5520           mp->sw_if_index = ntohl (sw_if_index);
5521           mp->static_mac = static_mac;
5522           mp->filter_mac = filter_mac;
5523           mp->bvi_mac = bvi_mac;
5524         }
5525       increment_mac_address (&mac);
5526       /* send it... */
5527       S;
5528     }
5529
5530   if (count > 1)
5531     {
5532       vl_api_control_ping_t *mp;
5533       f64 after;
5534
5535       /* Shut off async mode */
5536       vam->async_mode = 0;
5537
5538       M (CONTROL_PING, control_ping);
5539       S;
5540
5541       timeout = vat_time_now (vam) + 1.0;
5542       while (vat_time_now (vam) < timeout)
5543         if (vam->result_ready == 1)
5544           goto out;
5545       vam->retval = -99;
5546
5547     out:
5548       if (vam->retval == -99)
5549         errmsg ("timeout\n");
5550
5551       if (vam->async_errors > 0)
5552         {
5553           errmsg ("%d asynchronous errors\n", vam->async_errors);
5554           vam->retval = -98;
5555         }
5556       vam->async_errors = 0;
5557       after = vat_time_now (vam);
5558
5559       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5560                count, after - before, count / (after - before));
5561     }
5562   else
5563     {
5564       /* Wait for a reply... */
5565       W;
5566     }
5567   /* Return the good/bad news */
5568   return (vam->retval);
5569 }
5570
5571 static int
5572 api_l2_flags (vat_main_t * vam)
5573 {
5574   unformat_input_t *i = vam->input;
5575   vl_api_l2_flags_t *mp;
5576   f64 timeout;
5577   u32 sw_if_index;
5578   u32 feature_bitmap = 0;
5579   u8 sw_if_index_set = 0;
5580
5581   /* Parse args required to build the message */
5582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5583     {
5584       if (unformat (i, "sw_if_index %d", &sw_if_index))
5585         sw_if_index_set = 1;
5586       else if (unformat (i, "sw_if"))
5587         {
5588           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5589             {
5590               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5591                 sw_if_index_set = 1;
5592             }
5593           else
5594             break;
5595         }
5596       else if (unformat (i, "learn"))
5597         feature_bitmap |= L2INPUT_FEAT_LEARN;
5598       else if (unformat (i, "forward"))
5599         feature_bitmap |= L2INPUT_FEAT_FWD;
5600       else if (unformat (i, "flood"))
5601         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5602       else if (unformat (i, "uu-flood"))
5603         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5604       else
5605         break;
5606     }
5607
5608   if (sw_if_index_set == 0)
5609     {
5610       errmsg ("missing interface name or sw_if_index\n");
5611       return -99;
5612     }
5613
5614   M (L2_FLAGS, l2_flags);
5615
5616   mp->sw_if_index = ntohl (sw_if_index);
5617   mp->feature_bitmap = ntohl (feature_bitmap);
5618
5619   S;
5620   W;
5621   /* NOTREACHED */
5622   return 0;
5623 }
5624
5625 static int
5626 api_bridge_flags (vat_main_t * vam)
5627 {
5628   unformat_input_t *i = vam->input;
5629   vl_api_bridge_flags_t *mp;
5630   f64 timeout;
5631   u32 bd_id;
5632   u8 bd_id_set = 0;
5633   u8 is_set = 1;
5634   u32 flags = 0;
5635
5636   /* Parse args required to build the message */
5637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5638     {
5639       if (unformat (i, "bd_id %d", &bd_id))
5640         bd_id_set = 1;
5641       else if (unformat (i, "learn"))
5642         flags |= L2_LEARN;
5643       else if (unformat (i, "forward"))
5644         flags |= L2_FWD;
5645       else if (unformat (i, "flood"))
5646         flags |= L2_FLOOD;
5647       else if (unformat (i, "uu-flood"))
5648         flags |= L2_UU_FLOOD;
5649       else if (unformat (i, "arp-term"))
5650         flags |= L2_ARP_TERM;
5651       else if (unformat (i, "off"))
5652         is_set = 0;
5653       else if (unformat (i, "disable"))
5654         is_set = 0;
5655       else
5656         break;
5657     }
5658
5659   if (bd_id_set == 0)
5660     {
5661       errmsg ("missing bridge domain\n");
5662       return -99;
5663     }
5664
5665   M (BRIDGE_FLAGS, bridge_flags);
5666
5667   mp->bd_id = ntohl (bd_id);
5668   mp->feature_bitmap = ntohl (flags);
5669   mp->is_set = is_set;
5670
5671   S;
5672   W;
5673   /* NOTREACHED */
5674   return 0;
5675 }
5676
5677 static int
5678 api_bd_ip_mac_add_del (vat_main_t * vam)
5679 {
5680   unformat_input_t *i = vam->input;
5681   vl_api_bd_ip_mac_add_del_t *mp;
5682   f64 timeout;
5683   u32 bd_id;
5684   u8 is_ipv6 = 0;
5685   u8 is_add = 1;
5686   u8 bd_id_set = 0;
5687   u8 ip_set = 0;
5688   u8 mac_set = 0;
5689   ip4_address_t v4addr;
5690   ip6_address_t v6addr;
5691   u8 macaddr[6];
5692
5693
5694   /* Parse args required to build the message */
5695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5696     {
5697       if (unformat (i, "bd_id %d", &bd_id))
5698         {
5699           bd_id_set++;
5700         }
5701       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5702         {
5703           ip_set++;
5704         }
5705       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5706         {
5707           ip_set++;
5708           is_ipv6++;
5709         }
5710       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5711         {
5712           mac_set++;
5713         }
5714       else if (unformat (i, "del"))
5715         is_add = 0;
5716       else
5717         break;
5718     }
5719
5720   if (bd_id_set == 0)
5721     {
5722       errmsg ("missing bridge domain\n");
5723       return -99;
5724     }
5725   else if (ip_set == 0)
5726     {
5727       errmsg ("missing IP address\n");
5728       return -99;
5729     }
5730   else if (mac_set == 0)
5731     {
5732       errmsg ("missing MAC address\n");
5733       return -99;
5734     }
5735
5736   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5737
5738   mp->bd_id = ntohl (bd_id);
5739   mp->is_ipv6 = is_ipv6;
5740   mp->is_add = is_add;
5741   if (is_ipv6)
5742     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5743   else
5744     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5745   clib_memcpy (mp->mac_address, macaddr, 6);
5746   S;
5747   W;
5748   /* NOTREACHED */
5749   return 0;
5750 }
5751
5752 static int
5753 api_tap_connect (vat_main_t * vam)
5754 {
5755   unformat_input_t *i = vam->input;
5756   vl_api_tap_connect_t *mp;
5757   f64 timeout;
5758   u8 mac_address[6];
5759   u8 random_mac = 1;
5760   u8 name_set = 0;
5761   u8 *tap_name;
5762   u8 *tag = 0;
5763
5764   memset (mac_address, 0, sizeof (mac_address));
5765
5766   /* Parse args required to build the message */
5767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5768     {
5769       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5770         {
5771           random_mac = 0;
5772         }
5773       else if (unformat (i, "random-mac"))
5774         random_mac = 1;
5775       else if (unformat (i, "tapname %s", &tap_name))
5776         name_set = 1;
5777       else if (unformat (i, "tag %s", &tag))
5778         ;
5779       else
5780         break;
5781     }
5782
5783   if (name_set == 0)
5784     {
5785       errmsg ("missing tap name\n");
5786       return -99;
5787     }
5788   if (vec_len (tap_name) > 63)
5789     {
5790       errmsg ("tap name too long\n");
5791       return -99;
5792     }
5793   vec_add1 (tap_name, 0);
5794
5795   if (vec_len (tag) > 63)
5796     {
5797       errmsg ("tag too long\n");
5798       return -99;
5799     }
5800
5801   /* Construct the API message */
5802   M (TAP_CONNECT, tap_connect);
5803
5804   mp->use_random_mac = random_mac;
5805   clib_memcpy (mp->mac_address, mac_address, 6);
5806   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5807   if (tag)
5808     clib_memcpy (mp->tag, tag, vec_len (tag));
5809
5810   vec_free (tap_name);
5811   vec_free (tag);
5812
5813   /* send it... */
5814   S;
5815
5816   /* Wait for a reply... */
5817   W;
5818 }
5819
5820 static int
5821 api_tap_modify (vat_main_t * vam)
5822 {
5823   unformat_input_t *i = vam->input;
5824   vl_api_tap_modify_t *mp;
5825   f64 timeout;
5826   u8 mac_address[6];
5827   u8 random_mac = 1;
5828   u8 name_set = 0;
5829   u8 *tap_name;
5830   u32 sw_if_index = ~0;
5831   u8 sw_if_index_set = 0;
5832
5833   memset (mac_address, 0, sizeof (mac_address));
5834
5835   /* Parse args required to build the message */
5836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5837     {
5838       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5839         sw_if_index_set = 1;
5840       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5841         sw_if_index_set = 1;
5842       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5843         {
5844           random_mac = 0;
5845         }
5846       else if (unformat (i, "random-mac"))
5847         random_mac = 1;
5848       else if (unformat (i, "tapname %s", &tap_name))
5849         name_set = 1;
5850       else
5851         break;
5852     }
5853
5854   if (sw_if_index_set == 0)
5855     {
5856       errmsg ("missing vpp interface name");
5857       return -99;
5858     }
5859   if (name_set == 0)
5860     {
5861       errmsg ("missing tap name\n");
5862       return -99;
5863     }
5864   if (vec_len (tap_name) > 63)
5865     {
5866       errmsg ("tap name too long\n");
5867     }
5868   vec_add1 (tap_name, 0);
5869
5870   /* Construct the API message */
5871   M (TAP_MODIFY, tap_modify);
5872
5873   mp->use_random_mac = random_mac;
5874   mp->sw_if_index = ntohl (sw_if_index);
5875   clib_memcpy (mp->mac_address, mac_address, 6);
5876   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5877   vec_free (tap_name);
5878
5879   /* send it... */
5880   S;
5881
5882   /* Wait for a reply... */
5883   W;
5884 }
5885
5886 static int
5887 api_tap_delete (vat_main_t * vam)
5888 {
5889   unformat_input_t *i = vam->input;
5890   vl_api_tap_delete_t *mp;
5891   f64 timeout;
5892   u32 sw_if_index = ~0;
5893   u8 sw_if_index_set = 0;
5894
5895   /* Parse args required to build the message */
5896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5897     {
5898       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5899         sw_if_index_set = 1;
5900       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5901         sw_if_index_set = 1;
5902       else
5903         break;
5904     }
5905
5906   if (sw_if_index_set == 0)
5907     {
5908       errmsg ("missing vpp interface name");
5909       return -99;
5910     }
5911
5912   /* Construct the API message */
5913   M (TAP_DELETE, tap_delete);
5914
5915   mp->sw_if_index = ntohl (sw_if_index);
5916
5917   /* send it... */
5918   S;
5919
5920   /* Wait for a reply... */
5921   W;
5922 }
5923
5924 static int
5925 api_ip_add_del_route (vat_main_t * vam)
5926 {
5927   unformat_input_t *i = vam->input;
5928   vl_api_ip_add_del_route_t *mp;
5929   f64 timeout;
5930   u32 sw_if_index = ~0, vrf_id = 0;
5931   u8 is_ipv6 = 0;
5932   u8 is_local = 0, is_drop = 0;
5933   u8 is_unreach = 0, is_prohibit = 0;
5934   u8 create_vrf_if_needed = 0;
5935   u8 is_add = 1;
5936   u32 next_hop_weight = 1;
5937   u8 not_last = 0;
5938   u8 is_multipath = 0;
5939   u8 address_set = 0;
5940   u8 address_length_set = 0;
5941   u32 next_hop_table_id = 0;
5942   u32 resolve_attempts = 0;
5943   u32 dst_address_length = 0;
5944   u8 next_hop_set = 0;
5945   ip4_address_t v4_dst_address, v4_next_hop_address;
5946   ip6_address_t v6_dst_address, v6_next_hop_address;
5947   int count = 1;
5948   int j;
5949   f64 before = 0;
5950   u32 random_add_del = 0;
5951   u32 *random_vector = 0;
5952   uword *random_hash;
5953   u32 random_seed = 0xdeaddabe;
5954   u32 classify_table_index = ~0;
5955   u8 is_classify = 0;
5956   u8 resolve_host = 0, resolve_attached = 0;
5957   mpls_label_t *next_hop_out_label_stack = NULL;
5958   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5959   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
5960
5961   /* Parse args required to build the message */
5962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5963     {
5964       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5965         ;
5966       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5967         ;
5968       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5969         {
5970           address_set = 1;
5971           is_ipv6 = 0;
5972         }
5973       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5974         {
5975           address_set = 1;
5976           is_ipv6 = 1;
5977         }
5978       else if (unformat (i, "/%d", &dst_address_length))
5979         {
5980           address_length_set = 1;
5981         }
5982
5983       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5984                                          &v4_next_hop_address))
5985         {
5986           next_hop_set = 1;
5987         }
5988       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5989                                          &v6_next_hop_address))
5990         {
5991           next_hop_set = 1;
5992         }
5993       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5994         ;
5995       else if (unformat (i, "weight %d", &next_hop_weight))
5996         ;
5997       else if (unformat (i, "drop"))
5998         {
5999           is_drop = 1;
6000         }
6001       else if (unformat (i, "null-send-unreach"))
6002         {
6003           is_unreach = 1;
6004         }
6005       else if (unformat (i, "null-send-prohibit"))
6006         {
6007           is_prohibit = 1;
6008         }
6009       else if (unformat (i, "local"))
6010         {
6011           is_local = 1;
6012         }
6013       else if (unformat (i, "classify %d", &classify_table_index))
6014         {
6015           is_classify = 1;
6016         }
6017       else if (unformat (i, "del"))
6018         is_add = 0;
6019       else if (unformat (i, "add"))
6020         is_add = 1;
6021       else if (unformat (i, "not-last"))
6022         not_last = 1;
6023       else if (unformat (i, "resolve-via-host"))
6024         resolve_host = 1;
6025       else if (unformat (i, "resolve-via-attached"))
6026         resolve_attached = 1;
6027       else if (unformat (i, "multipath"))
6028         is_multipath = 1;
6029       else if (unformat (i, "vrf %d", &vrf_id))
6030         ;
6031       else if (unformat (i, "create-vrf"))
6032         create_vrf_if_needed = 1;
6033       else if (unformat (i, "count %d", &count))
6034         ;
6035       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6036         ;
6037       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6038         ;
6039       else if (unformat (i, "out-label %d", &next_hop_out_label))
6040         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6041       else if (unformat (i, "via-label %d", &next_hop_via_label))
6042         ;
6043       else if (unformat (i, "random"))
6044         random_add_del = 1;
6045       else if (unformat (i, "seed %d", &random_seed))
6046         ;
6047       else
6048         {
6049           clib_warning ("parse error '%U'", format_unformat_error, i);
6050           return -99;
6051         }
6052     }
6053
6054   if (!next_hop_set && !is_drop && !is_local &&
6055       !is_classify && !is_unreach && !is_prohibit &&
6056       MPLS_LABEL_INVALID == next_hop_via_label)
6057     {
6058       errmsg
6059         ("next hop / local / drop / unreach / prohibit / classify not set\n");
6060       return -99;
6061     }
6062
6063   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6064     {
6065       errmsg ("next hop and next-hop via label set\n");
6066       return -99;
6067     }
6068   if (address_set == 0)
6069     {
6070       errmsg ("missing addresses\n");
6071       return -99;
6072     }
6073
6074   if (address_length_set == 0)
6075     {
6076       errmsg ("missing address length\n");
6077       return -99;
6078     }
6079
6080   /* Generate a pile of unique, random routes */
6081   if (random_add_del)
6082     {
6083       u32 this_random_address;
6084       random_hash = hash_create (count, sizeof (uword));
6085
6086       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6087       for (j = 0; j <= count; j++)
6088         {
6089           do
6090             {
6091               this_random_address = random_u32 (&random_seed);
6092               this_random_address =
6093                 clib_host_to_net_u32 (this_random_address);
6094             }
6095           while (hash_get (random_hash, this_random_address));
6096           vec_add1 (random_vector, this_random_address);
6097           hash_set (random_hash, this_random_address, 1);
6098         }
6099       hash_free (random_hash);
6100       v4_dst_address.as_u32 = random_vector[0];
6101     }
6102
6103   if (count > 1)
6104     {
6105       /* Turn on async mode */
6106       vam->async_mode = 1;
6107       vam->async_errors = 0;
6108       before = vat_time_now (vam);
6109     }
6110
6111   for (j = 0; j < count; j++)
6112     {
6113       /* Construct the API message */
6114       M2 (IP_ADD_DEL_ROUTE, ip_add_del_route,
6115           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6116
6117       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6118       mp->table_id = ntohl (vrf_id);
6119       mp->create_vrf_if_needed = create_vrf_if_needed;
6120
6121       mp->is_add = is_add;
6122       mp->is_drop = is_drop;
6123       mp->is_unreach = is_unreach;
6124       mp->is_prohibit = is_prohibit;
6125       mp->is_ipv6 = is_ipv6;
6126       mp->is_local = is_local;
6127       mp->is_classify = is_classify;
6128       mp->is_multipath = is_multipath;
6129       mp->is_resolve_host = resolve_host;
6130       mp->is_resolve_attached = resolve_attached;
6131       mp->not_last = not_last;
6132       mp->next_hop_weight = next_hop_weight;
6133       mp->dst_address_length = dst_address_length;
6134       mp->next_hop_table_id = ntohl (next_hop_table_id);
6135       mp->classify_table_index = ntohl (classify_table_index);
6136       mp->next_hop_via_label = ntohl (next_hop_via_label);
6137       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6138       if (0 != mp->next_hop_n_out_labels)
6139         {
6140           memcpy (mp->next_hop_out_label_stack,
6141                   next_hop_out_label_stack,
6142                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6143           vec_free (next_hop_out_label_stack);
6144         }
6145
6146       if (is_ipv6)
6147         {
6148           clib_memcpy (mp->dst_address, &v6_dst_address,
6149                        sizeof (v6_dst_address));
6150           if (next_hop_set)
6151             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6152                          sizeof (v6_next_hop_address));
6153           increment_v6_address (&v6_dst_address);
6154         }
6155       else
6156         {
6157           clib_memcpy (mp->dst_address, &v4_dst_address,
6158                        sizeof (v4_dst_address));
6159           if (next_hop_set)
6160             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6161                          sizeof (v4_next_hop_address));
6162           if (random_add_del)
6163             v4_dst_address.as_u32 = random_vector[j + 1];
6164           else
6165             increment_v4_address (&v4_dst_address);
6166         }
6167       /* send it... */
6168       S;
6169       /* If we receive SIGTERM, stop now... */
6170       if (vam->do_exit)
6171         break;
6172     }
6173
6174   /* When testing multiple add/del ops, use a control-ping to sync */
6175   if (count > 1)
6176     {
6177       vl_api_control_ping_t *mp;
6178       f64 after;
6179
6180       /* Shut off async mode */
6181       vam->async_mode = 0;
6182
6183       M (CONTROL_PING, control_ping);
6184       S;
6185
6186       timeout = vat_time_now (vam) + 1.0;
6187       while (vat_time_now (vam) < timeout)
6188         if (vam->result_ready == 1)
6189           goto out;
6190       vam->retval = -99;
6191
6192     out:
6193       if (vam->retval == -99)
6194         errmsg ("timeout\n");
6195
6196       if (vam->async_errors > 0)
6197         {
6198           errmsg ("%d asynchronous errors\n", vam->async_errors);
6199           vam->retval = -98;
6200         }
6201       vam->async_errors = 0;
6202       after = vat_time_now (vam);
6203
6204       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6205       if (j > 0)
6206         count = j;
6207
6208       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6209                count, after - before, count / (after - before));
6210     }
6211   else
6212     {
6213       /* Wait for a reply... */
6214       W;
6215     }
6216
6217   /* Return the good/bad news */
6218   return (vam->retval);
6219 }
6220
6221 static int
6222 api_mpls_route_add_del (vat_main_t * vam)
6223 {
6224   unformat_input_t *i = vam->input;
6225   vl_api_mpls_route_add_del_t *mp;
6226   f64 timeout;
6227   u32 sw_if_index = ~0, table_id = 0;
6228   u8 create_table_if_needed = 0;
6229   u8 is_add = 1;
6230   u32 next_hop_weight = 1;
6231   u8 is_multipath = 0;
6232   u32 next_hop_table_id = 0;
6233   u8 next_hop_set = 0;
6234   ip4_address_t v4_next_hop_address = {
6235     .as_u32 = 0,
6236   };
6237   ip6_address_t v6_next_hop_address = { {0} };
6238   int count = 1;
6239   int j;
6240   f64 before = 0;
6241   u32 classify_table_index = ~0;
6242   u8 is_classify = 0;
6243   u8 resolve_host = 0, resolve_attached = 0;
6244   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6245   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6246   mpls_label_t *next_hop_out_label_stack = NULL;
6247   mpls_label_t local_label = MPLS_LABEL_INVALID;
6248   u8 is_eos = 0;
6249   u8 next_hop_proto_is_ip4 = 1;
6250
6251   /* Parse args required to build the message */
6252   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6253     {
6254       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6255         ;
6256       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6257         ;
6258       else if (unformat (i, "%d", &local_label))
6259         ;
6260       else if (unformat (i, "eos"))
6261         is_eos = 1;
6262       else if (unformat (i, "non-eos"))
6263         is_eos = 0;
6264       else if (unformat (i, "via %U", unformat_ip4_address,
6265                          &v4_next_hop_address))
6266         {
6267           next_hop_set = 1;
6268           next_hop_proto_is_ip4 = 1;
6269         }
6270       else if (unformat (i, "via %U", unformat_ip6_address,
6271                          &v6_next_hop_address))
6272         {
6273           next_hop_set = 1;
6274           next_hop_proto_is_ip4 = 0;
6275         }
6276       else if (unformat (i, "weight %d", &next_hop_weight))
6277         ;
6278       else if (unformat (i, "create-table"))
6279         create_table_if_needed = 1;
6280       else if (unformat (i, "classify %d", &classify_table_index))
6281         {
6282           is_classify = 1;
6283         }
6284       else if (unformat (i, "del"))
6285         is_add = 0;
6286       else if (unformat (i, "add"))
6287         is_add = 1;
6288       else if (unformat (i, "resolve-via-host"))
6289         resolve_host = 1;
6290       else if (unformat (i, "resolve-via-attached"))
6291         resolve_attached = 1;
6292       else if (unformat (i, "multipath"))
6293         is_multipath = 1;
6294       else if (unformat (i, "count %d", &count))
6295         ;
6296       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6297         {
6298           next_hop_set = 1;
6299           next_hop_proto_is_ip4 = 1;
6300         }
6301       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6302         {
6303           next_hop_set = 1;
6304           next_hop_proto_is_ip4 = 0;
6305         }
6306       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6307         ;
6308       else if (unformat (i, "via-label %d", &next_hop_via_label))
6309         ;
6310       else if (unformat (i, "out-label %d", &next_hop_out_label))
6311         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6312       else
6313         {
6314           clib_warning ("parse error '%U'", format_unformat_error, i);
6315           return -99;
6316         }
6317     }
6318
6319   if (!next_hop_set && !is_classify)
6320     {
6321       errmsg ("next hop / classify not set\n");
6322       return -99;
6323     }
6324
6325   if (MPLS_LABEL_INVALID == local_label)
6326     {
6327       errmsg ("missing label\n");
6328       return -99;
6329     }
6330
6331   if (count > 1)
6332     {
6333       /* Turn on async mode */
6334       vam->async_mode = 1;
6335       vam->async_errors = 0;
6336       before = vat_time_now (vam);
6337     }
6338
6339   for (j = 0; j < count; j++)
6340     {
6341       /* Construct the API message */
6342       M2 (MPLS_ROUTE_ADD_DEL, mpls_route_add_del,
6343           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6344
6345       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6346       mp->mr_table_id = ntohl (table_id);
6347       mp->mr_create_table_if_needed = create_table_if_needed;
6348
6349       mp->mr_is_add = is_add;
6350       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6351       mp->mr_is_classify = is_classify;
6352       mp->mr_is_multipath = is_multipath;
6353       mp->mr_is_resolve_host = resolve_host;
6354       mp->mr_is_resolve_attached = resolve_attached;
6355       mp->mr_next_hop_weight = next_hop_weight;
6356       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6357       mp->mr_classify_table_index = ntohl (classify_table_index);
6358       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6359       mp->mr_label = ntohl (local_label);
6360       mp->mr_eos = is_eos;
6361
6362       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6363       if (0 != mp->mr_next_hop_n_out_labels)
6364         {
6365           memcpy (mp->mr_next_hop_out_label_stack,
6366                   next_hop_out_label_stack,
6367                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6368           vec_free (next_hop_out_label_stack);
6369         }
6370
6371       if (next_hop_set)
6372         {
6373           if (next_hop_proto_is_ip4)
6374             {
6375               clib_memcpy (mp->mr_next_hop,
6376                            &v4_next_hop_address,
6377                            sizeof (v4_next_hop_address));
6378             }
6379           else
6380             {
6381               clib_memcpy (mp->mr_next_hop,
6382                            &v6_next_hop_address,
6383                            sizeof (v6_next_hop_address));
6384             }
6385         }
6386       local_label++;
6387
6388       /* send it... */
6389       S;
6390       /* If we receive SIGTERM, stop now... */
6391       if (vam->do_exit)
6392         break;
6393     }
6394
6395   /* When testing multiple add/del ops, use a control-ping to sync */
6396   if (count > 1)
6397     {
6398       vl_api_control_ping_t *mp;
6399       f64 after;
6400
6401       /* Shut off async mode */
6402       vam->async_mode = 0;
6403
6404       M (CONTROL_PING, control_ping);
6405       S;
6406
6407       timeout = vat_time_now (vam) + 1.0;
6408       while (vat_time_now (vam) < timeout)
6409         if (vam->result_ready == 1)
6410           goto out;
6411       vam->retval = -99;
6412
6413     out:
6414       if (vam->retval == -99)
6415         errmsg ("timeout\n");
6416
6417       if (vam->async_errors > 0)
6418         {
6419           errmsg ("%d asynchronous errors\n", vam->async_errors);
6420           vam->retval = -98;
6421         }
6422       vam->async_errors = 0;
6423       after = vat_time_now (vam);
6424
6425       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6426       if (j > 0)
6427         count = j;
6428
6429       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6430                count, after - before, count / (after - before));
6431     }
6432   else
6433     {
6434       /* Wait for a reply... */
6435       W;
6436     }
6437
6438   /* Return the good/bad news */
6439   return (vam->retval);
6440 }
6441
6442 static int
6443 api_mpls_ip_bind_unbind (vat_main_t * vam)
6444 {
6445   unformat_input_t *i = vam->input;
6446   vl_api_mpls_ip_bind_unbind_t *mp;
6447   f64 timeout;
6448   u32 ip_table_id = 0;
6449   u8 create_table_if_needed = 0;
6450   u8 is_bind = 1;
6451   u8 is_ip4 = 1;
6452   ip4_address_t v4_address;
6453   ip6_address_t v6_address;
6454   u32 address_length;
6455   u8 address_set = 0;
6456   mpls_label_t local_label = MPLS_LABEL_INVALID;
6457
6458   /* Parse args required to build the message */
6459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6460     {
6461       if (unformat (i, "%U/%d", unformat_ip4_address,
6462                     &v4_address, &address_length))
6463         {
6464           is_ip4 = 1;
6465           address_set = 1;
6466         }
6467       else if (unformat (i, "%U/%d", unformat_ip6_address,
6468                          &v6_address, &address_length))
6469         {
6470           is_ip4 = 0;
6471           address_set = 1;
6472         }
6473       else if (unformat (i, "%d", &local_label))
6474         ;
6475       else if (unformat (i, "create-table"))
6476         create_table_if_needed = 1;
6477       else if (unformat (i, "table-id %d", &ip_table_id))
6478         ;
6479       else if (unformat (i, "unbind"))
6480         is_bind = 0;
6481       else if (unformat (i, "bind"))
6482         is_bind = 1;
6483       else
6484         {
6485           clib_warning ("parse error '%U'", format_unformat_error, i);
6486           return -99;
6487         }
6488     }
6489
6490   if (!address_set)
6491     {
6492       errmsg ("IP addres not set\n");
6493       return -99;
6494     }
6495
6496   if (MPLS_LABEL_INVALID == local_label)
6497     {
6498       errmsg ("missing label\n");
6499       return -99;
6500     }
6501
6502   /* Construct the API message */
6503   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6504
6505   mp->mb_create_table_if_needed = create_table_if_needed;
6506   mp->mb_is_bind = is_bind;
6507   mp->mb_is_ip4 = is_ip4;
6508   mp->mb_ip_table_id = ntohl (ip_table_id);
6509   mp->mb_mpls_table_id = 0;
6510   mp->mb_label = ntohl (local_label);
6511   mp->mb_address_length = address_length;
6512
6513   if (is_ip4)
6514     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6515   else
6516     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6517
6518   /* send it... */
6519   S;
6520
6521   /* Wait for a reply... */
6522   W;
6523 }
6524
6525 static int
6526 api_proxy_arp_add_del (vat_main_t * vam)
6527 {
6528   unformat_input_t *i = vam->input;
6529   vl_api_proxy_arp_add_del_t *mp;
6530   f64 timeout;
6531   u32 vrf_id = 0;
6532   u8 is_add = 1;
6533   ip4_address_t lo, hi;
6534   u8 range_set = 0;
6535
6536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6537     {
6538       if (unformat (i, "vrf %d", &vrf_id))
6539         ;
6540       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6541                          unformat_ip4_address, &hi))
6542         range_set = 1;
6543       else if (unformat (i, "del"))
6544         is_add = 0;
6545       else
6546         {
6547           clib_warning ("parse error '%U'", format_unformat_error, i);
6548           return -99;
6549         }
6550     }
6551
6552   if (range_set == 0)
6553     {
6554       errmsg ("address range not set\n");
6555       return -99;
6556     }
6557
6558   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6559
6560   mp->vrf_id = ntohl (vrf_id);
6561   mp->is_add = is_add;
6562   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6563   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6564
6565   S;
6566   W;
6567   /* NOTREACHED */
6568   return 0;
6569 }
6570
6571 static int
6572 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6573 {
6574   unformat_input_t *i = vam->input;
6575   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6576   f64 timeout;
6577   u32 sw_if_index;
6578   u8 enable = 1;
6579   u8 sw_if_index_set = 0;
6580
6581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6582     {
6583       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6584         sw_if_index_set = 1;
6585       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6586         sw_if_index_set = 1;
6587       else if (unformat (i, "enable"))
6588         enable = 1;
6589       else if (unformat (i, "disable"))
6590         enable = 0;
6591       else
6592         {
6593           clib_warning ("parse error '%U'", format_unformat_error, i);
6594           return -99;
6595         }
6596     }
6597
6598   if (sw_if_index_set == 0)
6599     {
6600       errmsg ("missing interface name or sw_if_index\n");
6601       return -99;
6602     }
6603
6604   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6605
6606   mp->sw_if_index = ntohl (sw_if_index);
6607   mp->enable_disable = enable;
6608
6609   S;
6610   W;
6611   /* NOTREACHED */
6612   return 0;
6613 }
6614
6615 static int
6616 api_mpls_tunnel_add_del (vat_main_t * vam)
6617 {
6618   unformat_input_t *i = vam->input;
6619   vl_api_mpls_tunnel_add_del_t *mp;
6620   f64 timeout;
6621
6622   u8 is_add = 1;
6623   u8 l2_only = 0;
6624   u32 sw_if_index = ~0;
6625   u32 next_hop_sw_if_index = ~0;
6626   u32 next_hop_proto_is_ip4 = 1;
6627
6628   u32 next_hop_table_id = 0;
6629   ip4_address_t v4_next_hop_address = {
6630     .as_u32 = 0,
6631   };
6632   ip6_address_t v6_next_hop_address = { {0} };
6633   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
6634
6635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6636     {
6637       if (unformat (i, "add"))
6638         is_add = 1;
6639       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6640         is_add = 0;
6641       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
6642         ;
6643       else if (unformat (i, "via %U",
6644                          unformat_ip4_address, &v4_next_hop_address))
6645         {
6646           next_hop_proto_is_ip4 = 1;
6647         }
6648       else if (unformat (i, "via %U",
6649                          unformat_ip6_address, &v6_next_hop_address))
6650         {
6651           next_hop_proto_is_ip4 = 0;
6652         }
6653       else if (unformat (i, "l2-only"))
6654         l2_only = 1;
6655       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6656         ;
6657       else if (unformat (i, "out-label %d", &next_hop_out_label))
6658         vec_add1 (labels, ntohl (next_hop_out_label));
6659       else
6660         {
6661           clib_warning ("parse error '%U'", format_unformat_error, i);
6662           return -99;
6663         }
6664     }
6665
6666   M2 (MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del,
6667       sizeof (mpls_label_t) * vec_len (labels));
6668
6669   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
6670   mp->mt_sw_if_index = ntohl (sw_if_index);
6671   mp->mt_is_add = is_add;
6672   mp->mt_l2_only = l2_only;
6673   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
6674   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6675
6676   mp->mt_next_hop_n_out_labels = vec_len (labels);
6677
6678   if (0 != mp->mt_next_hop_n_out_labels)
6679     {
6680       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
6681                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
6682       vec_free (labels);
6683     }
6684
6685   if (next_hop_proto_is_ip4)
6686     {
6687       clib_memcpy (mp->mt_next_hop,
6688                    &v4_next_hop_address, sizeof (v4_next_hop_address));
6689     }
6690   else
6691     {
6692       clib_memcpy (mp->mt_next_hop,
6693                    &v6_next_hop_address, sizeof (v6_next_hop_address));
6694     }
6695
6696   S;
6697   W;
6698   /* NOTREACHED */
6699   return 0;
6700 }
6701
6702 static int
6703 api_sw_interface_set_unnumbered (vat_main_t * vam)
6704 {
6705   unformat_input_t *i = vam->input;
6706   vl_api_sw_interface_set_unnumbered_t *mp;
6707   f64 timeout;
6708   u32 sw_if_index;
6709   u32 unnum_sw_index = ~0;
6710   u8 is_add = 1;
6711   u8 sw_if_index_set = 0;
6712
6713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6714     {
6715       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6716         sw_if_index_set = 1;
6717       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6718         sw_if_index_set = 1;
6719       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6720         ;
6721       else if (unformat (i, "del"))
6722         is_add = 0;
6723       else
6724         {
6725           clib_warning ("parse error '%U'", format_unformat_error, i);
6726           return -99;
6727         }
6728     }
6729
6730   if (sw_if_index_set == 0)
6731     {
6732       errmsg ("missing interface name or sw_if_index\n");
6733       return -99;
6734     }
6735
6736   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6737
6738   mp->sw_if_index = ntohl (sw_if_index);
6739   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6740   mp->is_add = is_add;
6741
6742   S;
6743   W;
6744   /* NOTREACHED */
6745   return 0;
6746 }
6747
6748 static int
6749 api_ip_neighbor_add_del (vat_main_t * vam)
6750 {
6751   unformat_input_t *i = vam->input;
6752   vl_api_ip_neighbor_add_del_t *mp;
6753   f64 timeout;
6754   u32 sw_if_index;
6755   u8 sw_if_index_set = 0;
6756   u32 vrf_id = 0;
6757   u8 is_add = 1;
6758   u8 is_static = 0;
6759   u8 mac_address[6];
6760   u8 mac_set = 0;
6761   u8 v4_address_set = 0;
6762   u8 v6_address_set = 0;
6763   ip4_address_t v4address;
6764   ip6_address_t v6address;
6765
6766   memset (mac_address, 0, sizeof (mac_address));
6767
6768   /* Parse args required to build the message */
6769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6770     {
6771       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6772         {
6773           mac_set = 1;
6774         }
6775       else if (unformat (i, "del"))
6776         is_add = 0;
6777       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6778         sw_if_index_set = 1;
6779       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6780         sw_if_index_set = 1;
6781       else if (unformat (i, "is_static"))
6782         is_static = 1;
6783       else if (unformat (i, "vrf %d", &vrf_id))
6784         ;
6785       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6786         v4_address_set = 1;
6787       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6788         v6_address_set = 1;
6789       else
6790         {
6791           clib_warning ("parse error '%U'", format_unformat_error, i);
6792           return -99;
6793         }
6794     }
6795
6796   if (sw_if_index_set == 0)
6797     {
6798       errmsg ("missing interface name or sw_if_index\n");
6799       return -99;
6800     }
6801   if (v4_address_set && v6_address_set)
6802     {
6803       errmsg ("both v4 and v6 addresses set\n");
6804       return -99;
6805     }
6806   if (!v4_address_set && !v6_address_set)
6807     {
6808       errmsg ("no address set\n");
6809       return -99;
6810     }
6811
6812   /* Construct the API message */
6813   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6814
6815   mp->sw_if_index = ntohl (sw_if_index);
6816   mp->is_add = is_add;
6817   mp->vrf_id = ntohl (vrf_id);
6818   mp->is_static = is_static;
6819   if (mac_set)
6820     clib_memcpy (mp->mac_address, mac_address, 6);
6821   if (v6_address_set)
6822     {
6823       mp->is_ipv6 = 1;
6824       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6825     }
6826   else
6827     {
6828       /* mp->is_ipv6 = 0; via memset in M macro above */
6829       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6830     }
6831
6832   /* send it... */
6833   S;
6834
6835   /* Wait for a reply, return good/bad news  */
6836   W;
6837
6838   /* NOTREACHED */
6839   return 0;
6840 }
6841
6842 static int
6843 api_reset_vrf (vat_main_t * vam)
6844 {
6845   unformat_input_t *i = vam->input;
6846   vl_api_reset_vrf_t *mp;
6847   f64 timeout;
6848   u32 vrf_id = 0;
6849   u8 is_ipv6 = 0;
6850   u8 vrf_id_set = 0;
6851
6852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6853     {
6854       if (unformat (i, "vrf %d", &vrf_id))
6855         vrf_id_set = 1;
6856       else if (unformat (i, "ipv6"))
6857         is_ipv6 = 1;
6858       else
6859         {
6860           clib_warning ("parse error '%U'", format_unformat_error, i);
6861           return -99;
6862         }
6863     }
6864
6865   if (vrf_id_set == 0)
6866     {
6867       errmsg ("missing vrf id\n");
6868       return -99;
6869     }
6870
6871   M (RESET_VRF, reset_vrf);
6872
6873   mp->vrf_id = ntohl (vrf_id);
6874   mp->is_ipv6 = is_ipv6;
6875
6876   S;
6877   W;
6878   /* NOTREACHED */
6879   return 0;
6880 }
6881
6882 static int
6883 api_create_vlan_subif (vat_main_t * vam)
6884 {
6885   unformat_input_t *i = vam->input;
6886   vl_api_create_vlan_subif_t *mp;
6887   f64 timeout;
6888   u32 sw_if_index;
6889   u8 sw_if_index_set = 0;
6890   u32 vlan_id;
6891   u8 vlan_id_set = 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, "vlan %d", &vlan_id))
6900         vlan_id_set = 1;
6901       else
6902         {
6903           clib_warning ("parse error '%U'", format_unformat_error, i);
6904           return -99;
6905         }
6906     }
6907
6908   if (sw_if_index_set == 0)
6909     {
6910       errmsg ("missing interface name or sw_if_index\n");
6911       return -99;
6912     }
6913
6914   if (vlan_id_set == 0)
6915     {
6916       errmsg ("missing vlan_id\n");
6917       return -99;
6918     }
6919   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6920
6921   mp->sw_if_index = ntohl (sw_if_index);
6922   mp->vlan_id = ntohl (vlan_id);
6923
6924   S;
6925   W;
6926   /* NOTREACHED */
6927   return 0;
6928 }
6929
6930 #define foreach_create_subif_bit                \
6931 _(no_tags)                                      \
6932 _(one_tag)                                      \
6933 _(two_tags)                                     \
6934 _(dot1ad)                                       \
6935 _(exact_match)                                  \
6936 _(default_sub)                                  \
6937 _(outer_vlan_id_any)                            \
6938 _(inner_vlan_id_any)
6939
6940 static int
6941 api_create_subif (vat_main_t * vam)
6942 {
6943   unformat_input_t *i = vam->input;
6944   vl_api_create_subif_t *mp;
6945   f64 timeout;
6946   u32 sw_if_index;
6947   u8 sw_if_index_set = 0;
6948   u32 sub_id;
6949   u8 sub_id_set = 0;
6950   u32 no_tags = 0;
6951   u32 one_tag = 0;
6952   u32 two_tags = 0;
6953   u32 dot1ad = 0;
6954   u32 exact_match = 0;
6955   u32 default_sub = 0;
6956   u32 outer_vlan_id_any = 0;
6957   u32 inner_vlan_id_any = 0;
6958   u32 tmp;
6959   u16 outer_vlan_id = 0;
6960   u16 inner_vlan_id = 0;
6961
6962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6963     {
6964       if (unformat (i, "sw_if_index %d", &sw_if_index))
6965         sw_if_index_set = 1;
6966       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6967         sw_if_index_set = 1;
6968       else if (unformat (i, "sub_id %d", &sub_id))
6969         sub_id_set = 1;
6970       else if (unformat (i, "outer_vlan_id %d", &tmp))
6971         outer_vlan_id = tmp;
6972       else if (unformat (i, "inner_vlan_id %d", &tmp))
6973         inner_vlan_id = tmp;
6974
6975 #define _(a) else if (unformat (i, #a)) a = 1 ;
6976       foreach_create_subif_bit
6977 #undef _
6978         else
6979         {
6980           clib_warning ("parse error '%U'", format_unformat_error, i);
6981           return -99;
6982         }
6983     }
6984
6985   if (sw_if_index_set == 0)
6986     {
6987       errmsg ("missing interface name or sw_if_index\n");
6988       return -99;
6989     }
6990
6991   if (sub_id_set == 0)
6992     {
6993       errmsg ("missing sub_id\n");
6994       return -99;
6995     }
6996   M (CREATE_SUBIF, create_subif);
6997
6998   mp->sw_if_index = ntohl (sw_if_index);
6999   mp->sub_id = ntohl (sub_id);
7000
7001 #define _(a) mp->a = a;
7002   foreach_create_subif_bit;
7003 #undef _
7004
7005   mp->outer_vlan_id = ntohs (outer_vlan_id);
7006   mp->inner_vlan_id = ntohs (inner_vlan_id);
7007
7008   S;
7009   W;
7010   /* NOTREACHED */
7011   return 0;
7012 }
7013
7014 static int
7015 api_oam_add_del (vat_main_t * vam)
7016 {
7017   unformat_input_t *i = vam->input;
7018   vl_api_oam_add_del_t *mp;
7019   f64 timeout;
7020   u32 vrf_id = 0;
7021   u8 is_add = 1;
7022   ip4_address_t src, dst;
7023   u8 src_set = 0;
7024   u8 dst_set = 0;
7025
7026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7027     {
7028       if (unformat (i, "vrf %d", &vrf_id))
7029         ;
7030       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7031         src_set = 1;
7032       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7033         dst_set = 1;
7034       else if (unformat (i, "del"))
7035         is_add = 0;
7036       else
7037         {
7038           clib_warning ("parse error '%U'", format_unformat_error, i);
7039           return -99;
7040         }
7041     }
7042
7043   if (src_set == 0)
7044     {
7045       errmsg ("missing src addr\n");
7046       return -99;
7047     }
7048
7049   if (dst_set == 0)
7050     {
7051       errmsg ("missing dst addr\n");
7052       return -99;
7053     }
7054
7055   M (OAM_ADD_DEL, oam_add_del);
7056
7057   mp->vrf_id = ntohl (vrf_id);
7058   mp->is_add = is_add;
7059   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7060   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7061
7062   S;
7063   W;
7064   /* NOTREACHED */
7065   return 0;
7066 }
7067
7068 static int
7069 api_reset_fib (vat_main_t * vam)
7070 {
7071   unformat_input_t *i = vam->input;
7072   vl_api_reset_fib_t *mp;
7073   f64 timeout;
7074   u32 vrf_id = 0;
7075   u8 is_ipv6 = 0;
7076   u8 vrf_id_set = 0;
7077
7078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7079     {
7080       if (unformat (i, "vrf %d", &vrf_id))
7081         vrf_id_set = 1;
7082       else if (unformat (i, "ipv6"))
7083         is_ipv6 = 1;
7084       else
7085         {
7086           clib_warning ("parse error '%U'", format_unformat_error, i);
7087           return -99;
7088         }
7089     }
7090
7091   if (vrf_id_set == 0)
7092     {
7093       errmsg ("missing vrf id\n");
7094       return -99;
7095     }
7096
7097   M (RESET_FIB, reset_fib);
7098
7099   mp->vrf_id = ntohl (vrf_id);
7100   mp->is_ipv6 = is_ipv6;
7101
7102   S;
7103   W;
7104   /* NOTREACHED */
7105   return 0;
7106 }
7107
7108 static int
7109 api_dhcp_proxy_config (vat_main_t * vam)
7110 {
7111   unformat_input_t *i = vam->input;
7112   vl_api_dhcp_proxy_config_t *mp;
7113   f64 timeout;
7114   u32 vrf_id = 0;
7115   u8 is_add = 1;
7116   u8 insert_cid = 1;
7117   u8 v4_address_set = 0;
7118   u8 v6_address_set = 0;
7119   ip4_address_t v4address;
7120   ip6_address_t v6address;
7121   u8 v4_src_address_set = 0;
7122   u8 v6_src_address_set = 0;
7123   ip4_address_t v4srcaddress;
7124   ip6_address_t v6srcaddress;
7125
7126   /* Parse args required to build the message */
7127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7128     {
7129       if (unformat (i, "del"))
7130         is_add = 0;
7131       else if (unformat (i, "vrf %d", &vrf_id))
7132         ;
7133       else if (unformat (i, "insert-cid %d", &insert_cid))
7134         ;
7135       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7136         v4_address_set = 1;
7137       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7138         v6_address_set = 1;
7139       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7140         v4_src_address_set = 1;
7141       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7142         v6_src_address_set = 1;
7143       else
7144         break;
7145     }
7146
7147   if (v4_address_set && v6_address_set)
7148     {
7149       errmsg ("both v4 and v6 server addresses set\n");
7150       return -99;
7151     }
7152   if (!v4_address_set && !v6_address_set)
7153     {
7154       errmsg ("no server addresses set\n");
7155       return -99;
7156     }
7157
7158   if (v4_src_address_set && v6_src_address_set)
7159     {
7160       errmsg ("both v4 and v6  src addresses set\n");
7161       return -99;
7162     }
7163   if (!v4_src_address_set && !v6_src_address_set)
7164     {
7165       errmsg ("no src addresses set\n");
7166       return -99;
7167     }
7168
7169   if (!(v4_src_address_set && v4_address_set) &&
7170       !(v6_src_address_set && v6_address_set))
7171     {
7172       errmsg ("no matching server and src addresses set\n");
7173       return -99;
7174     }
7175
7176   /* Construct the API message */
7177   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7178
7179   mp->insert_circuit_id = insert_cid;
7180   mp->is_add = is_add;
7181   mp->vrf_id = ntohl (vrf_id);
7182   if (v6_address_set)
7183     {
7184       mp->is_ipv6 = 1;
7185       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7186       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7187     }
7188   else
7189     {
7190       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7191       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7192     }
7193
7194   /* send it... */
7195   S;
7196
7197   /* Wait for a reply, return good/bad news  */
7198   W;
7199   /* NOTREACHED */
7200   return 0;
7201 }
7202
7203 static int
7204 api_dhcp_proxy_config_2 (vat_main_t * vam)
7205 {
7206   unformat_input_t *i = vam->input;
7207   vl_api_dhcp_proxy_config_2_t *mp;
7208   f64 timeout;
7209   u32 rx_vrf_id = 0;
7210   u32 server_vrf_id = 0;
7211   u8 is_add = 1;
7212   u8 insert_cid = 1;
7213   u8 v4_address_set = 0;
7214   u8 v6_address_set = 0;
7215   ip4_address_t v4address;
7216   ip6_address_t v6address;
7217   u8 v4_src_address_set = 0;
7218   u8 v6_src_address_set = 0;
7219   ip4_address_t v4srcaddress;
7220   ip6_address_t v6srcaddress;
7221
7222   /* Parse args required to build the message */
7223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7224     {
7225       if (unformat (i, "del"))
7226         is_add = 0;
7227       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7228         ;
7229       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7230         ;
7231       else if (unformat (i, "insert-cid %d", &insert_cid))
7232         ;
7233       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7234         v4_address_set = 1;
7235       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7236         v6_address_set = 1;
7237       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7238         v4_src_address_set = 1;
7239       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7240         v6_src_address_set = 1;
7241       else
7242         break;
7243     }
7244
7245   if (v4_address_set && v6_address_set)
7246     {
7247       errmsg ("both v4 and v6 server addresses set\n");
7248       return -99;
7249     }
7250   if (!v4_address_set && !v6_address_set)
7251     {
7252       errmsg ("no server addresses set\n");
7253       return -99;
7254     }
7255
7256   if (v4_src_address_set && v6_src_address_set)
7257     {
7258       errmsg ("both v4 and v6  src addresses set\n");
7259       return -99;
7260     }
7261   if (!v4_src_address_set && !v6_src_address_set)
7262     {
7263       errmsg ("no src addresses set\n");
7264       return -99;
7265     }
7266
7267   if (!(v4_src_address_set && v4_address_set) &&
7268       !(v6_src_address_set && v6_address_set))
7269     {
7270       errmsg ("no matching server and src addresses set\n");
7271       return -99;
7272     }
7273
7274   /* Construct the API message */
7275   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7276
7277   mp->insert_circuit_id = insert_cid;
7278   mp->is_add = is_add;
7279   mp->rx_vrf_id = ntohl (rx_vrf_id);
7280   mp->server_vrf_id = ntohl (server_vrf_id);
7281   if (v6_address_set)
7282     {
7283       mp->is_ipv6 = 1;
7284       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7285       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7286     }
7287   else
7288     {
7289       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7290       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7291     }
7292
7293   /* send it... */
7294   S;
7295
7296   /* Wait for a reply, return good/bad news  */
7297   W;
7298   /* NOTREACHED */
7299   return 0;
7300 }
7301
7302 static int
7303 api_dhcp_proxy_set_vss (vat_main_t * vam)
7304 {
7305   unformat_input_t *i = vam->input;
7306   vl_api_dhcp_proxy_set_vss_t *mp;
7307   f64 timeout;
7308   u8 is_ipv6 = 0;
7309   u8 is_add = 1;
7310   u32 tbl_id;
7311   u8 tbl_id_set = 0;
7312   u32 oui;
7313   u8 oui_set = 0;
7314   u32 fib_id;
7315   u8 fib_id_set = 0;
7316
7317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7318     {
7319       if (unformat (i, "tbl_id %d", &tbl_id))
7320         tbl_id_set = 1;
7321       if (unformat (i, "fib_id %d", &fib_id))
7322         fib_id_set = 1;
7323       if (unformat (i, "oui %d", &oui))
7324         oui_set = 1;
7325       else if (unformat (i, "ipv6"))
7326         is_ipv6 = 1;
7327       else if (unformat (i, "del"))
7328         is_add = 0;
7329       else
7330         {
7331           clib_warning ("parse error '%U'", format_unformat_error, i);
7332           return -99;
7333         }
7334     }
7335
7336   if (tbl_id_set == 0)
7337     {
7338       errmsg ("missing tbl id\n");
7339       return -99;
7340     }
7341
7342   if (fib_id_set == 0)
7343     {
7344       errmsg ("missing fib id\n");
7345       return -99;
7346     }
7347   if (oui_set == 0)
7348     {
7349       errmsg ("missing oui\n");
7350       return -99;
7351     }
7352
7353   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7354   mp->tbl_id = ntohl (tbl_id);
7355   mp->fib_id = ntohl (fib_id);
7356   mp->oui = ntohl (oui);
7357   mp->is_ipv6 = is_ipv6;
7358   mp->is_add = is_add;
7359
7360   S;
7361   W;
7362   /* NOTREACHED */
7363   return 0;
7364 }
7365
7366 static int
7367 api_dhcp_client_config (vat_main_t * vam)
7368 {
7369   unformat_input_t *i = vam->input;
7370   vl_api_dhcp_client_config_t *mp;
7371   f64 timeout;
7372   u32 sw_if_index;
7373   u8 sw_if_index_set = 0;
7374   u8 is_add = 1;
7375   u8 *hostname = 0;
7376   u8 disable_event = 0;
7377
7378   /* Parse args required to build the message */
7379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7380     {
7381       if (unformat (i, "del"))
7382         is_add = 0;
7383       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7384         sw_if_index_set = 1;
7385       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7386         sw_if_index_set = 1;
7387       else if (unformat (i, "hostname %s", &hostname))
7388         ;
7389       else if (unformat (i, "disable_event"))
7390         disable_event = 1;
7391       else
7392         break;
7393     }
7394
7395   if (sw_if_index_set == 0)
7396     {
7397       errmsg ("missing interface name or sw_if_index\n");
7398       return -99;
7399     }
7400
7401   if (vec_len (hostname) > 63)
7402     {
7403       errmsg ("hostname too long\n");
7404     }
7405   vec_add1 (hostname, 0);
7406
7407   /* Construct the API message */
7408   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7409
7410   mp->sw_if_index = ntohl (sw_if_index);
7411   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7412   vec_free (hostname);
7413   mp->is_add = is_add;
7414   mp->want_dhcp_event = disable_event ? 0 : 1;
7415   mp->pid = getpid ();
7416
7417   /* send it... */
7418   S;
7419
7420   /* Wait for a reply, return good/bad news  */
7421   W;
7422   /* NOTREACHED */
7423   return 0;
7424 }
7425
7426 static int
7427 api_set_ip_flow_hash (vat_main_t * vam)
7428 {
7429   unformat_input_t *i = vam->input;
7430   vl_api_set_ip_flow_hash_t *mp;
7431   f64 timeout;
7432   u32 vrf_id = 0;
7433   u8 is_ipv6 = 0;
7434   u8 vrf_id_set = 0;
7435   u8 src = 0;
7436   u8 dst = 0;
7437   u8 sport = 0;
7438   u8 dport = 0;
7439   u8 proto = 0;
7440   u8 reverse = 0;
7441
7442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7443     {
7444       if (unformat (i, "vrf %d", &vrf_id))
7445         vrf_id_set = 1;
7446       else if (unformat (i, "ipv6"))
7447         is_ipv6 = 1;
7448       else if (unformat (i, "src"))
7449         src = 1;
7450       else if (unformat (i, "dst"))
7451         dst = 1;
7452       else if (unformat (i, "sport"))
7453         sport = 1;
7454       else if (unformat (i, "dport"))
7455         dport = 1;
7456       else if (unformat (i, "proto"))
7457         proto = 1;
7458       else if (unformat (i, "reverse"))
7459         reverse = 1;
7460
7461       else
7462         {
7463           clib_warning ("parse error '%U'", format_unformat_error, i);
7464           return -99;
7465         }
7466     }
7467
7468   if (vrf_id_set == 0)
7469     {
7470       errmsg ("missing vrf id\n");
7471       return -99;
7472     }
7473
7474   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7475   mp->src = src;
7476   mp->dst = dst;
7477   mp->sport = sport;
7478   mp->dport = dport;
7479   mp->proto = proto;
7480   mp->reverse = reverse;
7481   mp->vrf_id = ntohl (vrf_id);
7482   mp->is_ipv6 = is_ipv6;
7483
7484   S;
7485   W;
7486   /* NOTREACHED */
7487   return 0;
7488 }
7489
7490 static int
7491 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7492 {
7493   unformat_input_t *i = vam->input;
7494   vl_api_sw_interface_ip6_enable_disable_t *mp;
7495   f64 timeout;
7496   u32 sw_if_index;
7497   u8 sw_if_index_set = 0;
7498   u8 enable = 0;
7499
7500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7501     {
7502       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7503         sw_if_index_set = 1;
7504       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7505         sw_if_index_set = 1;
7506       else if (unformat (i, "enable"))
7507         enable = 1;
7508       else if (unformat (i, "disable"))
7509         enable = 0;
7510       else
7511         {
7512           clib_warning ("parse error '%U'", format_unformat_error, i);
7513           return -99;
7514         }
7515     }
7516
7517   if (sw_if_index_set == 0)
7518     {
7519       errmsg ("missing interface name or sw_if_index\n");
7520       return -99;
7521     }
7522
7523   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7524
7525   mp->sw_if_index = ntohl (sw_if_index);
7526   mp->enable = enable;
7527
7528   S;
7529   W;
7530   /* NOTREACHED */
7531   return 0;
7532 }
7533
7534 static int
7535 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7536 {
7537   unformat_input_t *i = vam->input;
7538   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7539   f64 timeout;
7540   u32 sw_if_index;
7541   u8 sw_if_index_set = 0;
7542   u32 address_length = 0;
7543   u8 v6_address_set = 0;
7544   ip6_address_t v6address;
7545
7546   /* Parse args required to build the message */
7547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7548     {
7549       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7550         sw_if_index_set = 1;
7551       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7552         sw_if_index_set = 1;
7553       else if (unformat (i, "%U/%d",
7554                          unformat_ip6_address, &v6address, &address_length))
7555         v6_address_set = 1;
7556       else
7557         break;
7558     }
7559
7560   if (sw_if_index_set == 0)
7561     {
7562       errmsg ("missing interface name or sw_if_index\n");
7563       return -99;
7564     }
7565   if (!v6_address_set)
7566     {
7567       errmsg ("no address set\n");
7568       return -99;
7569     }
7570
7571   /* Construct the API message */
7572   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7573      sw_interface_ip6_set_link_local_address);
7574
7575   mp->sw_if_index = ntohl (sw_if_index);
7576   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7577   mp->address_length = address_length;
7578
7579   /* send it... */
7580   S;
7581
7582   /* Wait for a reply, return good/bad news  */
7583   W;
7584
7585   /* NOTREACHED */
7586   return 0;
7587 }
7588
7589
7590 static int
7591 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7592 {
7593   unformat_input_t *i = vam->input;
7594   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7595   f64 timeout;
7596   u32 sw_if_index;
7597   u8 sw_if_index_set = 0;
7598   u32 address_length = 0;
7599   u8 v6_address_set = 0;
7600   ip6_address_t v6address;
7601   u8 use_default = 0;
7602   u8 no_advertise = 0;
7603   u8 off_link = 0;
7604   u8 no_autoconfig = 0;
7605   u8 no_onlink = 0;
7606   u8 is_no = 0;
7607   u32 val_lifetime = 0;
7608   u32 pref_lifetime = 0;
7609
7610   /* Parse args required to build the message */
7611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7612     {
7613       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7614         sw_if_index_set = 1;
7615       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7616         sw_if_index_set = 1;
7617       else if (unformat (i, "%U/%d",
7618                          unformat_ip6_address, &v6address, &address_length))
7619         v6_address_set = 1;
7620       else if (unformat (i, "val_life %d", &val_lifetime))
7621         ;
7622       else if (unformat (i, "pref_life %d", &pref_lifetime))
7623         ;
7624       else if (unformat (i, "def"))
7625         use_default = 1;
7626       else if (unformat (i, "noadv"))
7627         no_advertise = 1;
7628       else if (unformat (i, "offl"))
7629         off_link = 1;
7630       else if (unformat (i, "noauto"))
7631         no_autoconfig = 1;
7632       else if (unformat (i, "nolink"))
7633         no_onlink = 1;
7634       else if (unformat (i, "isno"))
7635         is_no = 1;
7636       else
7637         {
7638           clib_warning ("parse error '%U'", format_unformat_error, i);
7639           return -99;
7640         }
7641     }
7642
7643   if (sw_if_index_set == 0)
7644     {
7645       errmsg ("missing interface name or sw_if_index\n");
7646       return -99;
7647     }
7648   if (!v6_address_set)
7649     {
7650       errmsg ("no address set\n");
7651       return -99;
7652     }
7653
7654   /* Construct the API message */
7655   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7656
7657   mp->sw_if_index = ntohl (sw_if_index);
7658   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7659   mp->address_length = address_length;
7660   mp->use_default = use_default;
7661   mp->no_advertise = no_advertise;
7662   mp->off_link = off_link;
7663   mp->no_autoconfig = no_autoconfig;
7664   mp->no_onlink = no_onlink;
7665   mp->is_no = is_no;
7666   mp->val_lifetime = ntohl (val_lifetime);
7667   mp->pref_lifetime = ntohl (pref_lifetime);
7668
7669   /* send it... */
7670   S;
7671
7672   /* Wait for a reply, return good/bad news  */
7673   W;
7674
7675   /* NOTREACHED */
7676   return 0;
7677 }
7678
7679 static int
7680 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7681 {
7682   unformat_input_t *i = vam->input;
7683   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7684   f64 timeout;
7685   u32 sw_if_index;
7686   u8 sw_if_index_set = 0;
7687   u8 suppress = 0;
7688   u8 managed = 0;
7689   u8 other = 0;
7690   u8 ll_option = 0;
7691   u8 send_unicast = 0;
7692   u8 cease = 0;
7693   u8 is_no = 0;
7694   u8 default_router = 0;
7695   u32 max_interval = 0;
7696   u32 min_interval = 0;
7697   u32 lifetime = 0;
7698   u32 initial_count = 0;
7699   u32 initial_interval = 0;
7700
7701
7702   /* Parse args required to build the message */
7703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7704     {
7705       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7706         sw_if_index_set = 1;
7707       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7708         sw_if_index_set = 1;
7709       else if (unformat (i, "maxint %d", &max_interval))
7710         ;
7711       else if (unformat (i, "minint %d", &min_interval))
7712         ;
7713       else if (unformat (i, "life %d", &lifetime))
7714         ;
7715       else if (unformat (i, "count %d", &initial_count))
7716         ;
7717       else if (unformat (i, "interval %d", &initial_interval))
7718         ;
7719       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7720         suppress = 1;
7721       else if (unformat (i, "managed"))
7722         managed = 1;
7723       else if (unformat (i, "other"))
7724         other = 1;
7725       else if (unformat (i, "ll"))
7726         ll_option = 1;
7727       else if (unformat (i, "send"))
7728         send_unicast = 1;
7729       else if (unformat (i, "cease"))
7730         cease = 1;
7731       else if (unformat (i, "isno"))
7732         is_no = 1;
7733       else if (unformat (i, "def"))
7734         default_router = 1;
7735       else
7736         {
7737           clib_warning ("parse error '%U'", format_unformat_error, i);
7738           return -99;
7739         }
7740     }
7741
7742   if (sw_if_index_set == 0)
7743     {
7744       errmsg ("missing interface name or sw_if_index\n");
7745       return -99;
7746     }
7747
7748   /* Construct the API message */
7749   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7750
7751   mp->sw_if_index = ntohl (sw_if_index);
7752   mp->max_interval = ntohl (max_interval);
7753   mp->min_interval = ntohl (min_interval);
7754   mp->lifetime = ntohl (lifetime);
7755   mp->initial_count = ntohl (initial_count);
7756   mp->initial_interval = ntohl (initial_interval);
7757   mp->suppress = suppress;
7758   mp->managed = managed;
7759   mp->other = other;
7760   mp->ll_option = ll_option;
7761   mp->send_unicast = send_unicast;
7762   mp->cease = cease;
7763   mp->is_no = is_no;
7764   mp->default_router = default_router;
7765
7766   /* send it... */
7767   S;
7768
7769   /* Wait for a reply, return good/bad news  */
7770   W;
7771
7772   /* NOTREACHED */
7773   return 0;
7774 }
7775
7776 static int
7777 api_set_arp_neighbor_limit (vat_main_t * vam)
7778 {
7779   unformat_input_t *i = vam->input;
7780   vl_api_set_arp_neighbor_limit_t *mp;
7781   f64 timeout;
7782   u32 arp_nbr_limit;
7783   u8 limit_set = 0;
7784   u8 is_ipv6 = 0;
7785
7786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7787     {
7788       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7789         limit_set = 1;
7790       else if (unformat (i, "ipv6"))
7791         is_ipv6 = 1;
7792       else
7793         {
7794           clib_warning ("parse error '%U'", format_unformat_error, i);
7795           return -99;
7796         }
7797     }
7798
7799   if (limit_set == 0)
7800     {
7801       errmsg ("missing limit value\n");
7802       return -99;
7803     }
7804
7805   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7806
7807   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7808   mp->is_ipv6 = is_ipv6;
7809
7810   S;
7811   W;
7812   /* NOTREACHED */
7813   return 0;
7814 }
7815
7816 static int
7817 api_l2_patch_add_del (vat_main_t * vam)
7818 {
7819   unformat_input_t *i = vam->input;
7820   vl_api_l2_patch_add_del_t *mp;
7821   f64 timeout;
7822   u32 rx_sw_if_index;
7823   u8 rx_sw_if_index_set = 0;
7824   u32 tx_sw_if_index;
7825   u8 tx_sw_if_index_set = 0;
7826   u8 is_add = 1;
7827
7828   /* Parse args required to build the message */
7829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7830     {
7831       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7832         rx_sw_if_index_set = 1;
7833       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7834         tx_sw_if_index_set = 1;
7835       else if (unformat (i, "rx"))
7836         {
7837           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7838             {
7839               if (unformat (i, "%U", unformat_sw_if_index, vam,
7840                             &rx_sw_if_index))
7841                 rx_sw_if_index_set = 1;
7842             }
7843           else
7844             break;
7845         }
7846       else if (unformat (i, "tx"))
7847         {
7848           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7849             {
7850               if (unformat (i, "%U", unformat_sw_if_index, vam,
7851                             &tx_sw_if_index))
7852                 tx_sw_if_index_set = 1;
7853             }
7854           else
7855             break;
7856         }
7857       else if (unformat (i, "del"))
7858         is_add = 0;
7859       else
7860         break;
7861     }
7862
7863   if (rx_sw_if_index_set == 0)
7864     {
7865       errmsg ("missing rx interface name or rx_sw_if_index\n");
7866       return -99;
7867     }
7868
7869   if (tx_sw_if_index_set == 0)
7870     {
7871       errmsg ("missing tx interface name or tx_sw_if_index\n");
7872       return -99;
7873     }
7874
7875   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7876
7877   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7878   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7879   mp->is_add = is_add;
7880
7881   S;
7882   W;
7883   /* NOTREACHED */
7884   return 0;
7885 }
7886
7887 static int
7888 api_ioam_enable (vat_main_t * vam)
7889 {
7890   unformat_input_t *input = vam->input;
7891   vl_api_ioam_enable_t *mp;
7892   f64 timeout;
7893   u32 id = 0;
7894   int has_trace_option = 0;
7895   int has_pot_option = 0;
7896   int has_seqno_option = 0;
7897   int has_analyse_option = 0;
7898
7899   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7900     {
7901       if (unformat (input, "trace"))
7902         has_trace_option = 1;
7903       else if (unformat (input, "pot"))
7904         has_pot_option = 1;
7905       else if (unformat (input, "seqno"))
7906         has_seqno_option = 1;
7907       else if (unformat (input, "analyse"))
7908         has_analyse_option = 1;
7909       else
7910         break;
7911     }
7912   M (IOAM_ENABLE, ioam_enable);
7913   mp->id = htons (id);
7914   mp->seqno = has_seqno_option;
7915   mp->analyse = has_analyse_option;
7916   mp->pot_enable = has_pot_option;
7917   mp->trace_enable = has_trace_option;
7918
7919   S;
7920   W;
7921
7922   return (0);
7923
7924 }
7925
7926
7927 static int
7928 api_ioam_disable (vat_main_t * vam)
7929 {
7930   vl_api_ioam_disable_t *mp;
7931   f64 timeout;
7932
7933   M (IOAM_DISABLE, ioam_disable);
7934   S;
7935   W;
7936   return 0;
7937 }
7938
7939 static int
7940 api_sr_tunnel_add_del (vat_main_t * vam)
7941 {
7942   unformat_input_t *i = vam->input;
7943   vl_api_sr_tunnel_add_del_t *mp;
7944   f64 timeout;
7945   int is_del = 0;
7946   int pl_index;
7947   ip6_address_t src_address;
7948   int src_address_set = 0;
7949   ip6_address_t dst_address;
7950   u32 dst_mask_width;
7951   int dst_address_set = 0;
7952   u16 flags = 0;
7953   u32 rx_table_id = 0;
7954   u32 tx_table_id = 0;
7955   ip6_address_t *segments = 0;
7956   ip6_address_t *this_seg;
7957   ip6_address_t *tags = 0;
7958   ip6_address_t *this_tag;
7959   ip6_address_t next_address, tag;
7960   u8 *name = 0;
7961   u8 *policy_name = 0;
7962
7963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7964     {
7965       if (unformat (i, "del"))
7966         is_del = 1;
7967       else if (unformat (i, "name %s", &name))
7968         ;
7969       else if (unformat (i, "policy %s", &policy_name))
7970         ;
7971       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7972         ;
7973       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7974         ;
7975       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7976         src_address_set = 1;
7977       else if (unformat (i, "dst %U/%d",
7978                          unformat_ip6_address, &dst_address, &dst_mask_width))
7979         dst_address_set = 1;
7980       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7981         {
7982           vec_add2 (segments, this_seg, 1);
7983           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7984                        sizeof (*this_seg));
7985         }
7986       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7987         {
7988           vec_add2 (tags, this_tag, 1);
7989           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7990         }
7991       else if (unformat (i, "clean"))
7992         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7993       else if (unformat (i, "protected"))
7994         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7995       else if (unformat (i, "InPE %d", &pl_index))
7996         {
7997           if (pl_index <= 0 || pl_index > 4)
7998             {
7999             pl_index_range_error:
8000               errmsg ("pl index %d out of range\n", pl_index);
8001               return -99;
8002             }
8003           flags |=
8004             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8005         }
8006       else if (unformat (i, "EgPE %d", &pl_index))
8007         {
8008           if (pl_index <= 0 || pl_index > 4)
8009             goto pl_index_range_error;
8010           flags |=
8011             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8012         }
8013       else if (unformat (i, "OrgSrc %d", &pl_index))
8014         {
8015           if (pl_index <= 0 || pl_index > 4)
8016             goto pl_index_range_error;
8017           flags |=
8018             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8019         }
8020       else
8021         break;
8022     }
8023
8024   if (!src_address_set)
8025     {
8026       errmsg ("src address required\n");
8027       return -99;
8028     }
8029
8030   if (!dst_address_set)
8031     {
8032       errmsg ("dst address required\n");
8033       return -99;
8034     }
8035
8036   if (!segments)
8037     {
8038       errmsg ("at least one sr segment required\n");
8039       return -99;
8040     }
8041
8042   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
8043       vec_len (segments) * sizeof (ip6_address_t)
8044       + vec_len (tags) * sizeof (ip6_address_t));
8045
8046   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8047   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8048   mp->dst_mask_width = dst_mask_width;
8049   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8050   mp->n_segments = vec_len (segments);
8051   mp->n_tags = vec_len (tags);
8052   mp->is_add = is_del == 0;
8053   clib_memcpy (mp->segs_and_tags, segments,
8054                vec_len (segments) * sizeof (ip6_address_t));
8055   clib_memcpy (mp->segs_and_tags +
8056                vec_len (segments) * sizeof (ip6_address_t), tags,
8057                vec_len (tags) * sizeof (ip6_address_t));
8058
8059   mp->outer_vrf_id = ntohl (rx_table_id);
8060   mp->inner_vrf_id = ntohl (tx_table_id);
8061   memcpy (mp->name, name, vec_len (name));
8062   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8063
8064   vec_free (segments);
8065   vec_free (tags);
8066
8067   S;
8068   W;
8069   /* NOTREACHED */
8070 }
8071
8072 static int
8073 api_sr_policy_add_del (vat_main_t * vam)
8074 {
8075   unformat_input_t *input = vam->input;
8076   vl_api_sr_policy_add_del_t *mp;
8077   f64 timeout;
8078   int is_del = 0;
8079   u8 *name = 0;
8080   u8 *tunnel_name = 0;
8081   u8 **tunnel_names = 0;
8082
8083   int name_set = 0;
8084   int tunnel_set = 0;
8085   int j = 0;
8086   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8087   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8088
8089   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8090     {
8091       if (unformat (input, "del"))
8092         is_del = 1;
8093       else if (unformat (input, "name %s", &name))
8094         name_set = 1;
8095       else if (unformat (input, "tunnel %s", &tunnel_name))
8096         {
8097           if (tunnel_name)
8098             {
8099               vec_add1 (tunnel_names, tunnel_name);
8100               /* For serializer:
8101                  - length = #bytes to store in serial vector
8102                  - +1 = byte to store that length
8103                */
8104               tunnel_names_length += (vec_len (tunnel_name) + 1);
8105               tunnel_set = 1;
8106               tunnel_name = 0;
8107             }
8108         }
8109       else
8110         break;
8111     }
8112
8113   if (!name_set)
8114     {
8115       errmsg ("policy name required\n");
8116       return -99;
8117     }
8118
8119   if ((!tunnel_set) && (!is_del))
8120     {
8121       errmsg ("tunnel name required\n");
8122       return -99;
8123     }
8124
8125   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8126
8127
8128
8129   mp->is_add = !is_del;
8130
8131   memcpy (mp->name, name, vec_len (name));
8132   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8133   u8 *serial_orig = 0;
8134   vec_validate (serial_orig, tunnel_names_length);
8135   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8136   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8137
8138   for (j = 0; j < vec_len (tunnel_names); j++)
8139     {
8140       tun_name_len = vec_len (tunnel_names[j]);
8141       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8142       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8143       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8144       serial_orig += tun_name_len;      // Advance past the copy
8145     }
8146   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8147
8148   vec_free (tunnel_names);
8149   vec_free (tunnel_name);
8150
8151   S;
8152   W;
8153   /* NOTREACHED */
8154 }
8155
8156 static int
8157 api_sr_multicast_map_add_del (vat_main_t * vam)
8158 {
8159   unformat_input_t *input = vam->input;
8160   vl_api_sr_multicast_map_add_del_t *mp;
8161   f64 timeout;
8162   int is_del = 0;
8163   ip6_address_t multicast_address;
8164   u8 *policy_name = 0;
8165   int multicast_address_set = 0;
8166
8167   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8168     {
8169       if (unformat (input, "del"))
8170         is_del = 1;
8171       else
8172         if (unformat
8173             (input, "address %U", unformat_ip6_address, &multicast_address))
8174         multicast_address_set = 1;
8175       else if (unformat (input, "sr-policy %s", &policy_name))
8176         ;
8177       else
8178         break;
8179     }
8180
8181   if (!is_del && !policy_name)
8182     {
8183       errmsg ("sr-policy name required\n");
8184       return -99;
8185     }
8186
8187
8188   if (!multicast_address_set)
8189     {
8190       errmsg ("address required\n");
8191       return -99;
8192     }
8193
8194   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8195
8196   mp->is_add = !is_del;
8197   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8198   clib_memcpy (mp->multicast_address, &multicast_address,
8199                sizeof (mp->multicast_address));
8200
8201
8202   vec_free (policy_name);
8203
8204   S;
8205   W;
8206   /* NOTREACHED */
8207 }
8208
8209
8210 #define foreach_tcp_proto_field                 \
8211 _(src_port)                                     \
8212 _(dst_port)
8213
8214 #define foreach_udp_proto_field                 \
8215 _(src_port)                                     \
8216 _(dst_port)
8217
8218 #define foreach_ip4_proto_field                 \
8219 _(src_address)                                  \
8220 _(dst_address)                                  \
8221 _(tos)                                          \
8222 _(length)                                       \
8223 _(fragment_id)                                  \
8224 _(ttl)                                          \
8225 _(protocol)                                     \
8226 _(checksum)
8227
8228 uword
8229 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8230 {
8231   u8 **maskp = va_arg (*args, u8 **);
8232   u8 *mask = 0;
8233   u8 found_something = 0;
8234   tcp_header_t *tcp;
8235
8236 #define _(a) u8 a=0;
8237   foreach_tcp_proto_field;
8238 #undef _
8239
8240   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8241     {
8242       if (0);
8243 #define _(a) else if (unformat (input, #a)) a=1;
8244       foreach_tcp_proto_field
8245 #undef _
8246         else
8247         break;
8248     }
8249
8250 #define _(a) found_something += a;
8251   foreach_tcp_proto_field;
8252 #undef _
8253
8254   if (found_something == 0)
8255     return 0;
8256
8257   vec_validate (mask, sizeof (*tcp) - 1);
8258
8259   tcp = (tcp_header_t *) mask;
8260
8261 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8262   foreach_tcp_proto_field;
8263 #undef _
8264
8265   *maskp = mask;
8266   return 1;
8267 }
8268
8269 uword
8270 unformat_udp_mask (unformat_input_t * input, va_list * args)
8271 {
8272   u8 **maskp = va_arg (*args, u8 **);
8273   u8 *mask = 0;
8274   u8 found_something = 0;
8275   udp_header_t *udp;
8276
8277 #define _(a) u8 a=0;
8278   foreach_udp_proto_field;
8279 #undef _
8280
8281   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8282     {
8283       if (0);
8284 #define _(a) else if (unformat (input, #a)) a=1;
8285       foreach_udp_proto_field
8286 #undef _
8287         else
8288         break;
8289     }
8290
8291 #define _(a) found_something += a;
8292   foreach_udp_proto_field;
8293 #undef _
8294
8295   if (found_something == 0)
8296     return 0;
8297
8298   vec_validate (mask, sizeof (*udp) - 1);
8299
8300   udp = (udp_header_t *) mask;
8301
8302 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8303   foreach_udp_proto_field;
8304 #undef _
8305
8306   *maskp = mask;
8307   return 1;
8308 }
8309
8310 typedef struct
8311 {
8312   u16 src_port, dst_port;
8313 } tcpudp_header_t;
8314
8315 uword
8316 unformat_l4_mask (unformat_input_t * input, va_list * args)
8317 {
8318   u8 **maskp = va_arg (*args, u8 **);
8319   u16 src_port = 0, dst_port = 0;
8320   tcpudp_header_t *tcpudp;
8321
8322   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8323     {
8324       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8325         return 1;
8326       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8327         return 1;
8328       else if (unformat (input, "src_port"))
8329         src_port = 0xFFFF;
8330       else if (unformat (input, "dst_port"))
8331         dst_port = 0xFFFF;
8332       else
8333         return 0;
8334     }
8335
8336   if (!src_port && !dst_port)
8337     return 0;
8338
8339   u8 *mask = 0;
8340   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8341
8342   tcpudp = (tcpudp_header_t *) mask;
8343   tcpudp->src_port = src_port;
8344   tcpudp->dst_port = dst_port;
8345
8346   *maskp = mask;
8347
8348   return 1;
8349 }
8350
8351 uword
8352 unformat_ip4_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   ip4_header_t *ip;
8358
8359 #define _(a) u8 a=0;
8360   foreach_ip4_proto_field;
8361 #undef _
8362   u8 version = 0;
8363   u8 hdr_length = 0;
8364
8365
8366   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8367     {
8368       if (unformat (input, "version"))
8369         version = 1;
8370       else if (unformat (input, "hdr_length"))
8371         hdr_length = 1;
8372       else if (unformat (input, "src"))
8373         src_address = 1;
8374       else if (unformat (input, "dst"))
8375         dst_address = 1;
8376       else if (unformat (input, "proto"))
8377         protocol = 1;
8378
8379 #define _(a) else if (unformat (input, #a)) a=1;
8380       foreach_ip4_proto_field
8381 #undef _
8382         else
8383         break;
8384     }
8385
8386 #define _(a) found_something += a;
8387   foreach_ip4_proto_field;
8388 #undef _
8389
8390   if (found_something == 0)
8391     return 0;
8392
8393   vec_validate (mask, sizeof (*ip) - 1);
8394
8395   ip = (ip4_header_t *) mask;
8396
8397 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8398   foreach_ip4_proto_field;
8399 #undef _
8400
8401   ip->ip_version_and_header_length = 0;
8402
8403   if (version)
8404     ip->ip_version_and_header_length |= 0xF0;
8405
8406   if (hdr_length)
8407     ip->ip_version_and_header_length |= 0x0F;
8408
8409   *maskp = mask;
8410   return 1;
8411 }
8412
8413 #define foreach_ip6_proto_field                 \
8414 _(src_address)                                  \
8415 _(dst_address)                                  \
8416 _(payload_length)                               \
8417 _(hop_limit)                                    \
8418 _(protocol)
8419
8420 uword
8421 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8422 {
8423   u8 **maskp = va_arg (*args, u8 **);
8424   u8 *mask = 0;
8425   u8 found_something = 0;
8426   ip6_header_t *ip;
8427   u32 ip_version_traffic_class_and_flow_label;
8428
8429 #define _(a) u8 a=0;
8430   foreach_ip6_proto_field;
8431 #undef _
8432   u8 version = 0;
8433   u8 traffic_class = 0;
8434   u8 flow_label = 0;
8435
8436   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8437     {
8438       if (unformat (input, "version"))
8439         version = 1;
8440       else if (unformat (input, "traffic-class"))
8441         traffic_class = 1;
8442       else if (unformat (input, "flow-label"))
8443         flow_label = 1;
8444       else if (unformat (input, "src"))
8445         src_address = 1;
8446       else if (unformat (input, "dst"))
8447         dst_address = 1;
8448       else if (unformat (input, "proto"))
8449         protocol = 1;
8450
8451 #define _(a) else if (unformat (input, #a)) a=1;
8452       foreach_ip6_proto_field
8453 #undef _
8454         else
8455         break;
8456     }
8457
8458 #define _(a) found_something += a;
8459   foreach_ip6_proto_field;
8460 #undef _
8461
8462   if (found_something == 0)
8463     return 0;
8464
8465   vec_validate (mask, sizeof (*ip) - 1);
8466
8467   ip = (ip6_header_t *) mask;
8468
8469 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8470   foreach_ip6_proto_field;
8471 #undef _
8472
8473   ip_version_traffic_class_and_flow_label = 0;
8474
8475   if (version)
8476     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8477
8478   if (traffic_class)
8479     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8480
8481   if (flow_label)
8482     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8483
8484   ip->ip_version_traffic_class_and_flow_label =
8485     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8486
8487   *maskp = mask;
8488   return 1;
8489 }
8490
8491 uword
8492 unformat_l3_mask (unformat_input_t * input, va_list * args)
8493 {
8494   u8 **maskp = va_arg (*args, u8 **);
8495
8496   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8497     {
8498       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8499         return 1;
8500       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8501         return 1;
8502       else
8503         break;
8504     }
8505   return 0;
8506 }
8507
8508 uword
8509 unformat_l2_mask (unformat_input_t * input, va_list * args)
8510 {
8511   u8 **maskp = va_arg (*args, u8 **);
8512   u8 *mask = 0;
8513   u8 src = 0;
8514   u8 dst = 0;
8515   u8 proto = 0;
8516   u8 tag1 = 0;
8517   u8 tag2 = 0;
8518   u8 ignore_tag1 = 0;
8519   u8 ignore_tag2 = 0;
8520   u8 cos1 = 0;
8521   u8 cos2 = 0;
8522   u8 dot1q = 0;
8523   u8 dot1ad = 0;
8524   int len = 14;
8525
8526   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8527     {
8528       if (unformat (input, "src"))
8529         src = 1;
8530       else if (unformat (input, "dst"))
8531         dst = 1;
8532       else if (unformat (input, "proto"))
8533         proto = 1;
8534       else if (unformat (input, "tag1"))
8535         tag1 = 1;
8536       else if (unformat (input, "tag2"))
8537         tag2 = 1;
8538       else if (unformat (input, "ignore-tag1"))
8539         ignore_tag1 = 1;
8540       else if (unformat (input, "ignore-tag2"))
8541         ignore_tag2 = 1;
8542       else if (unformat (input, "cos1"))
8543         cos1 = 1;
8544       else if (unformat (input, "cos2"))
8545         cos2 = 1;
8546       else if (unformat (input, "dot1q"))
8547         dot1q = 1;
8548       else if (unformat (input, "dot1ad"))
8549         dot1ad = 1;
8550       else
8551         break;
8552     }
8553   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8554        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8555     return 0;
8556
8557   if (tag1 || ignore_tag1 || cos1 || dot1q)
8558     len = 18;
8559   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8560     len = 22;
8561
8562   vec_validate (mask, len - 1);
8563
8564   if (dst)
8565     memset (mask, 0xff, 6);
8566
8567   if (src)
8568     memset (mask + 6, 0xff, 6);
8569
8570   if (tag2 || dot1ad)
8571     {
8572       /* inner vlan tag */
8573       if (tag2)
8574         {
8575           mask[19] = 0xff;
8576           mask[18] = 0x0f;
8577         }
8578       if (cos2)
8579         mask[18] |= 0xe0;
8580       if (proto)
8581         mask[21] = mask[20] = 0xff;
8582       if (tag1)
8583         {
8584           mask[15] = 0xff;
8585           mask[14] = 0x0f;
8586         }
8587       if (cos1)
8588         mask[14] |= 0xe0;
8589       *maskp = mask;
8590       return 1;
8591     }
8592   if (tag1 | dot1q)
8593     {
8594       if (tag1)
8595         {
8596           mask[15] = 0xff;
8597           mask[14] = 0x0f;
8598         }
8599       if (cos1)
8600         mask[14] |= 0xe0;
8601       if (proto)
8602         mask[16] = mask[17] = 0xff;
8603
8604       *maskp = mask;
8605       return 1;
8606     }
8607   if (cos2)
8608     mask[18] |= 0xe0;
8609   if (cos1)
8610     mask[14] |= 0xe0;
8611   if (proto)
8612     mask[12] = mask[13] = 0xff;
8613
8614   *maskp = mask;
8615   return 1;
8616 }
8617
8618 uword
8619 unformat_classify_mask (unformat_input_t * input, va_list * args)
8620 {
8621   u8 **maskp = va_arg (*args, u8 **);
8622   u32 *skipp = va_arg (*args, u32 *);
8623   u32 *matchp = va_arg (*args, u32 *);
8624   u32 match;
8625   u8 *mask = 0;
8626   u8 *l2 = 0;
8627   u8 *l3 = 0;
8628   u8 *l4 = 0;
8629   int i;
8630
8631   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8632     {
8633       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8634         ;
8635       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8636         ;
8637       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8638         ;
8639       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8640         ;
8641       else
8642         break;
8643     }
8644
8645   if (l4 && !l3)
8646     {
8647       vec_free (mask);
8648       vec_free (l2);
8649       vec_free (l4);
8650       return 0;
8651     }
8652
8653   if (mask || l2 || l3 || l4)
8654     {
8655       if (l2 || l3 || l4)
8656         {
8657           /* "With a free Ethernet header in every package" */
8658           if (l2 == 0)
8659             vec_validate (l2, 13);
8660           mask = l2;
8661           if (vec_len (l3))
8662             {
8663               vec_append (mask, l3);
8664               vec_free (l3);
8665             }
8666           if (vec_len (l4))
8667             {
8668               vec_append (mask, l4);
8669               vec_free (l4);
8670             }
8671         }
8672
8673       /* Scan forward looking for the first significant mask octet */
8674       for (i = 0; i < vec_len (mask); i++)
8675         if (mask[i])
8676           break;
8677
8678       /* compute (skip, match) params */
8679       *skipp = i / sizeof (u32x4);
8680       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8681
8682       /* Pad mask to an even multiple of the vector size */
8683       while (vec_len (mask) % sizeof (u32x4))
8684         vec_add1 (mask, 0);
8685
8686       match = vec_len (mask) / sizeof (u32x4);
8687
8688       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8689         {
8690           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8691           if (*tmp || *(tmp + 1))
8692             break;
8693           match--;
8694         }
8695       if (match == 0)
8696         clib_warning ("BUG: match 0");
8697
8698       _vec_len (mask) = match * sizeof (u32x4);
8699
8700       *matchp = match;
8701       *maskp = mask;
8702
8703       return 1;
8704     }
8705
8706   return 0;
8707 }
8708
8709 #define foreach_l2_next                         \
8710 _(drop, DROP)                                   \
8711 _(ethernet, ETHERNET_INPUT)                     \
8712 _(ip4, IP4_INPUT)                               \
8713 _(ip6, IP6_INPUT)
8714
8715 uword
8716 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8717 {
8718   u32 *miss_next_indexp = va_arg (*args, u32 *);
8719   u32 next_index = 0;
8720   u32 tmp;
8721
8722 #define _(n,N) \
8723   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8724   foreach_l2_next;
8725 #undef _
8726
8727   if (unformat (input, "%d", &tmp))
8728     {
8729       next_index = tmp;
8730       goto out;
8731     }
8732
8733   return 0;
8734
8735 out:
8736   *miss_next_indexp = next_index;
8737   return 1;
8738 }
8739
8740 #define foreach_ip_next                         \
8741 _(drop, DROP)                                   \
8742 _(local, LOCAL)                                 \
8743 _(rewrite, REWRITE)
8744
8745 uword
8746 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8747 {
8748   u32 *miss_next_indexp = va_arg (*args, u32 *);
8749   u32 next_index = 0;
8750   u32 tmp;
8751
8752 #define _(n,N) \
8753   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8754   foreach_ip_next;
8755 #undef _
8756
8757   if (unformat (input, "%d", &tmp))
8758     {
8759       next_index = tmp;
8760       goto out;
8761     }
8762
8763   return 0;
8764
8765 out:
8766   *miss_next_indexp = next_index;
8767   return 1;
8768 }
8769
8770 #define foreach_acl_next                        \
8771 _(deny, DENY)
8772
8773 uword
8774 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8775 {
8776   u32 *miss_next_indexp = va_arg (*args, u32 *);
8777   u32 next_index = 0;
8778   u32 tmp;
8779
8780 #define _(n,N) \
8781   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8782   foreach_acl_next;
8783 #undef _
8784
8785   if (unformat (input, "permit"))
8786     {
8787       next_index = ~0;
8788       goto out;
8789     }
8790   else if (unformat (input, "%d", &tmp))
8791     {
8792       next_index = tmp;
8793       goto out;
8794     }
8795
8796   return 0;
8797
8798 out:
8799   *miss_next_indexp = next_index;
8800   return 1;
8801 }
8802
8803 uword
8804 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8805 {
8806   u32 *r = va_arg (*args, u32 *);
8807
8808   if (unformat (input, "conform-color"))
8809     *r = POLICE_CONFORM;
8810   else if (unformat (input, "exceed-color"))
8811     *r = POLICE_EXCEED;
8812   else
8813     return 0;
8814
8815   return 1;
8816 }
8817
8818 static int
8819 api_classify_add_del_table (vat_main_t * vam)
8820 {
8821   unformat_input_t *i = vam->input;
8822   vl_api_classify_add_del_table_t *mp;
8823
8824   u32 nbuckets = 2;
8825   u32 skip = ~0;
8826   u32 match = ~0;
8827   int is_add = 1;
8828   u32 table_index = ~0;
8829   u32 next_table_index = ~0;
8830   u32 miss_next_index = ~0;
8831   u32 memory_size = 32 << 20;
8832   u8 *mask = 0;
8833   f64 timeout;
8834   u32 current_data_flag = 0;
8835   int current_data_offset = 0;
8836
8837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8838     {
8839       if (unformat (i, "del"))
8840         is_add = 0;
8841       else if (unformat (i, "buckets %d", &nbuckets))
8842         ;
8843       else if (unformat (i, "memory_size %d", &memory_size))
8844         ;
8845       else if (unformat (i, "skip %d", &skip))
8846         ;
8847       else if (unformat (i, "match %d", &match))
8848         ;
8849       else if (unformat (i, "table %d", &table_index))
8850         ;
8851       else if (unformat (i, "mask %U", unformat_classify_mask,
8852                          &mask, &skip, &match))
8853         ;
8854       else if (unformat (i, "next-table %d", &next_table_index))
8855         ;
8856       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8857                          &miss_next_index))
8858         ;
8859       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8860                          &miss_next_index))
8861         ;
8862       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8863                          &miss_next_index))
8864         ;
8865       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8866         ;
8867       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8868         ;
8869       else
8870         break;
8871     }
8872
8873   if (is_add && mask == 0)
8874     {
8875       errmsg ("Mask required\n");
8876       return -99;
8877     }
8878
8879   if (is_add && skip == ~0)
8880     {
8881       errmsg ("skip count required\n");
8882       return -99;
8883     }
8884
8885   if (is_add && match == ~0)
8886     {
8887       errmsg ("match count required\n");
8888       return -99;
8889     }
8890
8891   if (!is_add && table_index == ~0)
8892     {
8893       errmsg ("table index required for delete\n");
8894       return -99;
8895     }
8896
8897   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8898
8899   mp->is_add = is_add;
8900   mp->table_index = ntohl (table_index);
8901   mp->nbuckets = ntohl (nbuckets);
8902   mp->memory_size = ntohl (memory_size);
8903   mp->skip_n_vectors = ntohl (skip);
8904   mp->match_n_vectors = ntohl (match);
8905   mp->next_table_index = ntohl (next_table_index);
8906   mp->miss_next_index = ntohl (miss_next_index);
8907   mp->current_data_flag = ntohl (current_data_flag);
8908   mp->current_data_offset = ntohl (current_data_offset);
8909   clib_memcpy (mp->mask, mask, vec_len (mask));
8910
8911   vec_free (mask);
8912
8913   S;
8914   W;
8915   /* NOTREACHED */
8916 }
8917
8918 uword
8919 unformat_l4_match (unformat_input_t * input, va_list * args)
8920 {
8921   u8 **matchp = va_arg (*args, u8 **);
8922
8923   u8 *proto_header = 0;
8924   int src_port = 0;
8925   int dst_port = 0;
8926
8927   tcpudp_header_t h;
8928
8929   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8930     {
8931       if (unformat (input, "src_port %d", &src_port))
8932         ;
8933       else if (unformat (input, "dst_port %d", &dst_port))
8934         ;
8935       else
8936         return 0;
8937     }
8938
8939   h.src_port = clib_host_to_net_u16 (src_port);
8940   h.dst_port = clib_host_to_net_u16 (dst_port);
8941   vec_validate (proto_header, sizeof (h) - 1);
8942   memcpy (proto_header, &h, sizeof (h));
8943
8944   *matchp = proto_header;
8945
8946   return 1;
8947 }
8948
8949 uword
8950 unformat_ip4_match (unformat_input_t * input, va_list * args)
8951 {
8952   u8 **matchp = va_arg (*args, u8 **);
8953   u8 *match = 0;
8954   ip4_header_t *ip;
8955   int version = 0;
8956   u32 version_val;
8957   int hdr_length = 0;
8958   u32 hdr_length_val;
8959   int src = 0, dst = 0;
8960   ip4_address_t src_val, dst_val;
8961   int proto = 0;
8962   u32 proto_val;
8963   int tos = 0;
8964   u32 tos_val;
8965   int length = 0;
8966   u32 length_val;
8967   int fragment_id = 0;
8968   u32 fragment_id_val;
8969   int ttl = 0;
8970   int ttl_val;
8971   int checksum = 0;
8972   u32 checksum_val;
8973
8974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8975     {
8976       if (unformat (input, "version %d", &version_val))
8977         version = 1;
8978       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8979         hdr_length = 1;
8980       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8981         src = 1;
8982       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8983         dst = 1;
8984       else if (unformat (input, "proto %d", &proto_val))
8985         proto = 1;
8986       else if (unformat (input, "tos %d", &tos_val))
8987         tos = 1;
8988       else if (unformat (input, "length %d", &length_val))
8989         length = 1;
8990       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8991         fragment_id = 1;
8992       else if (unformat (input, "ttl %d", &ttl_val))
8993         ttl = 1;
8994       else if (unformat (input, "checksum %d", &checksum_val))
8995         checksum = 1;
8996       else
8997         break;
8998     }
8999
9000   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9001       + ttl + checksum == 0)
9002     return 0;
9003
9004   /*
9005    * Aligned because we use the real comparison functions
9006    */
9007   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9008
9009   ip = (ip4_header_t *) match;
9010
9011   /* These are realistically matched in practice */
9012   if (src)
9013     ip->src_address.as_u32 = src_val.as_u32;
9014
9015   if (dst)
9016     ip->dst_address.as_u32 = dst_val.as_u32;
9017
9018   if (proto)
9019     ip->protocol = proto_val;
9020
9021
9022   /* These are not, but they're included for completeness */
9023   if (version)
9024     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9025
9026   if (hdr_length)
9027     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9028
9029   if (tos)
9030     ip->tos = tos_val;
9031
9032   if (length)
9033     ip->length = clib_host_to_net_u16 (length_val);
9034
9035   if (ttl)
9036     ip->ttl = ttl_val;
9037
9038   if (checksum)
9039     ip->checksum = clib_host_to_net_u16 (checksum_val);
9040
9041   *matchp = match;
9042   return 1;
9043 }
9044
9045 uword
9046 unformat_ip6_match (unformat_input_t * input, va_list * args)
9047 {
9048   u8 **matchp = va_arg (*args, u8 **);
9049   u8 *match = 0;
9050   ip6_header_t *ip;
9051   int version = 0;
9052   u32 version_val;
9053   u8 traffic_class = 0;
9054   u32 traffic_class_val = 0;
9055   u8 flow_label = 0;
9056   u8 flow_label_val;
9057   int src = 0, dst = 0;
9058   ip6_address_t src_val, dst_val;
9059   int proto = 0;
9060   u32 proto_val;
9061   int payload_length = 0;
9062   u32 payload_length_val;
9063   int hop_limit = 0;
9064   int hop_limit_val;
9065   u32 ip_version_traffic_class_and_flow_label;
9066
9067   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9068     {
9069       if (unformat (input, "version %d", &version_val))
9070         version = 1;
9071       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9072         traffic_class = 1;
9073       else if (unformat (input, "flow_label %d", &flow_label_val))
9074         flow_label = 1;
9075       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9076         src = 1;
9077       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9078         dst = 1;
9079       else if (unformat (input, "proto %d", &proto_val))
9080         proto = 1;
9081       else if (unformat (input, "payload_length %d", &payload_length_val))
9082         payload_length = 1;
9083       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9084         hop_limit = 1;
9085       else
9086         break;
9087     }
9088
9089   if (version + traffic_class + flow_label + src + dst + proto +
9090       payload_length + hop_limit == 0)
9091     return 0;
9092
9093   /*
9094    * Aligned because we use the real comparison functions
9095    */
9096   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9097
9098   ip = (ip6_header_t *) match;
9099
9100   if (src)
9101     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9102
9103   if (dst)
9104     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9105
9106   if (proto)
9107     ip->protocol = proto_val;
9108
9109   ip_version_traffic_class_and_flow_label = 0;
9110
9111   if (version)
9112     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9113
9114   if (traffic_class)
9115     ip_version_traffic_class_and_flow_label |=
9116       (traffic_class_val & 0xFF) << 20;
9117
9118   if (flow_label)
9119     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9120
9121   ip->ip_version_traffic_class_and_flow_label =
9122     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9123
9124   if (payload_length)
9125     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9126
9127   if (hop_limit)
9128     ip->hop_limit = hop_limit_val;
9129
9130   *matchp = match;
9131   return 1;
9132 }
9133
9134 uword
9135 unformat_l3_match (unformat_input_t * input, va_list * args)
9136 {
9137   u8 **matchp = va_arg (*args, u8 **);
9138
9139   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9140     {
9141       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9142         return 1;
9143       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9144         return 1;
9145       else
9146         break;
9147     }
9148   return 0;
9149 }
9150
9151 uword
9152 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9153 {
9154   u8 *tagp = va_arg (*args, u8 *);
9155   u32 tag;
9156
9157   if (unformat (input, "%d", &tag))
9158     {
9159       tagp[0] = (tag >> 8) & 0x0F;
9160       tagp[1] = tag & 0xFF;
9161       return 1;
9162     }
9163
9164   return 0;
9165 }
9166
9167 uword
9168 unformat_l2_match (unformat_input_t * input, va_list * args)
9169 {
9170   u8 **matchp = va_arg (*args, u8 **);
9171   u8 *match = 0;
9172   u8 src = 0;
9173   u8 src_val[6];
9174   u8 dst = 0;
9175   u8 dst_val[6];
9176   u8 proto = 0;
9177   u16 proto_val;
9178   u8 tag1 = 0;
9179   u8 tag1_val[2];
9180   u8 tag2 = 0;
9181   u8 tag2_val[2];
9182   int len = 14;
9183   u8 ignore_tag1 = 0;
9184   u8 ignore_tag2 = 0;
9185   u8 cos1 = 0;
9186   u8 cos2 = 0;
9187   u32 cos1_val = 0;
9188   u32 cos2_val = 0;
9189
9190   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9191     {
9192       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9193         src = 1;
9194       else
9195         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9196         dst = 1;
9197       else if (unformat (input, "proto %U",
9198                          unformat_ethernet_type_host_byte_order, &proto_val))
9199         proto = 1;
9200       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9201         tag1 = 1;
9202       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9203         tag2 = 1;
9204       else if (unformat (input, "ignore-tag1"))
9205         ignore_tag1 = 1;
9206       else if (unformat (input, "ignore-tag2"))
9207         ignore_tag2 = 1;
9208       else if (unformat (input, "cos1 %d", &cos1_val))
9209         cos1 = 1;
9210       else if (unformat (input, "cos2 %d", &cos2_val))
9211         cos2 = 1;
9212       else
9213         break;
9214     }
9215   if ((src + dst + proto + tag1 + tag2 +
9216        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9217     return 0;
9218
9219   if (tag1 || ignore_tag1 || cos1)
9220     len = 18;
9221   if (tag2 || ignore_tag2 || cos2)
9222     len = 22;
9223
9224   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9225
9226   if (dst)
9227     clib_memcpy (match, dst_val, 6);
9228
9229   if (src)
9230     clib_memcpy (match + 6, src_val, 6);
9231
9232   if (tag2)
9233     {
9234       /* inner vlan tag */
9235       match[19] = tag2_val[1];
9236       match[18] = tag2_val[0];
9237       if (cos2)
9238         match[18] |= (cos2_val & 0x7) << 5;
9239       if (proto)
9240         {
9241           match[21] = proto_val & 0xff;
9242           match[20] = proto_val >> 8;
9243         }
9244       if (tag1)
9245         {
9246           match[15] = tag1_val[1];
9247           match[14] = tag1_val[0];
9248         }
9249       if (cos1)
9250         match[14] |= (cos1_val & 0x7) << 5;
9251       *matchp = match;
9252       return 1;
9253     }
9254   if (tag1)
9255     {
9256       match[15] = tag1_val[1];
9257       match[14] = tag1_val[0];
9258       if (proto)
9259         {
9260           match[17] = proto_val & 0xff;
9261           match[16] = proto_val >> 8;
9262         }
9263       if (cos1)
9264         match[14] |= (cos1_val & 0x7) << 5;
9265
9266       *matchp = match;
9267       return 1;
9268     }
9269   if (cos2)
9270     match[18] |= (cos2_val & 0x7) << 5;
9271   if (cos1)
9272     match[14] |= (cos1_val & 0x7) << 5;
9273   if (proto)
9274     {
9275       match[13] = proto_val & 0xff;
9276       match[12] = proto_val >> 8;
9277     }
9278
9279   *matchp = match;
9280   return 1;
9281 }
9282
9283
9284 uword
9285 unformat_classify_match (unformat_input_t * input, va_list * args)
9286 {
9287   u8 **matchp = va_arg (*args, u8 **);
9288   u32 skip_n_vectors = va_arg (*args, u32);
9289   u32 match_n_vectors = va_arg (*args, u32);
9290
9291   u8 *match = 0;
9292   u8 *l2 = 0;
9293   u8 *l3 = 0;
9294   u8 *l4 = 0;
9295
9296   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9297     {
9298       if (unformat (input, "hex %U", unformat_hex_string, &match))
9299         ;
9300       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9301         ;
9302       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9303         ;
9304       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9305         ;
9306       else
9307         break;
9308     }
9309
9310   if (l4 && !l3)
9311     {
9312       vec_free (match);
9313       vec_free (l2);
9314       vec_free (l4);
9315       return 0;
9316     }
9317
9318   if (match || l2 || l3 || l4)
9319     {
9320       if (l2 || l3 || l4)
9321         {
9322           /* "Win a free Ethernet header in every packet" */
9323           if (l2 == 0)
9324             vec_validate_aligned (l2, 13, sizeof (u32x4));
9325           match = l2;
9326           if (vec_len (l3))
9327             {
9328               vec_append_aligned (match, l3, sizeof (u32x4));
9329               vec_free (l3);
9330             }
9331           if (vec_len (l4))
9332             {
9333               vec_append_aligned (match, l4, sizeof (u32x4));
9334               vec_free (l4);
9335             }
9336         }
9337
9338       /* Make sure the vector is big enough even if key is all 0's */
9339       vec_validate_aligned
9340         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9341          sizeof (u32x4));
9342
9343       /* Set size, include skipped vectors */
9344       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9345
9346       *matchp = match;
9347
9348       return 1;
9349     }
9350
9351   return 0;
9352 }
9353
9354 static int
9355 api_classify_add_del_session (vat_main_t * vam)
9356 {
9357   unformat_input_t *i = vam->input;
9358   vl_api_classify_add_del_session_t *mp;
9359   int is_add = 1;
9360   u32 table_index = ~0;
9361   u32 hit_next_index = ~0;
9362   u32 opaque_index = ~0;
9363   u8 *match = 0;
9364   i32 advance = 0;
9365   f64 timeout;
9366   u32 skip_n_vectors = 0;
9367   u32 match_n_vectors = 0;
9368   u32 action = 0;
9369   u32 metadata = 0;
9370
9371   /*
9372    * Warning: you have to supply skip_n and match_n
9373    * because the API client cant simply look at the classify
9374    * table object.
9375    */
9376
9377   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9378     {
9379       if (unformat (i, "del"))
9380         is_add = 0;
9381       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9382                          &hit_next_index))
9383         ;
9384       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9385                          &hit_next_index))
9386         ;
9387       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9388                          &hit_next_index))
9389         ;
9390       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9391         ;
9392       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9393         ;
9394       else if (unformat (i, "opaque-index %d", &opaque_index))
9395         ;
9396       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9397         ;
9398       else if (unformat (i, "match_n %d", &match_n_vectors))
9399         ;
9400       else if (unformat (i, "match %U", unformat_classify_match,
9401                          &match, skip_n_vectors, match_n_vectors))
9402         ;
9403       else if (unformat (i, "advance %d", &advance))
9404         ;
9405       else if (unformat (i, "table-index %d", &table_index))
9406         ;
9407       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9408         action = 1;
9409       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9410         action = 2;
9411       else if (unformat (i, "action %d", &action))
9412         ;
9413       else if (unformat (i, "metadata %d", &metadata))
9414         ;
9415       else
9416         break;
9417     }
9418
9419   if (table_index == ~0)
9420     {
9421       errmsg ("Table index required\n");
9422       return -99;
9423     }
9424
9425   if (is_add && match == 0)
9426     {
9427       errmsg ("Match value required\n");
9428       return -99;
9429     }
9430
9431   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9432
9433   mp->is_add = is_add;
9434   mp->table_index = ntohl (table_index);
9435   mp->hit_next_index = ntohl (hit_next_index);
9436   mp->opaque_index = ntohl (opaque_index);
9437   mp->advance = ntohl (advance);
9438   mp->action = action;
9439   mp->metadata = ntohl (metadata);
9440   clib_memcpy (mp->match, match, vec_len (match));
9441   vec_free (match);
9442
9443   S;
9444   W;
9445   /* NOTREACHED */
9446 }
9447
9448 static int
9449 api_classify_set_interface_ip_table (vat_main_t * vam)
9450 {
9451   unformat_input_t *i = vam->input;
9452   vl_api_classify_set_interface_ip_table_t *mp;
9453   f64 timeout;
9454   u32 sw_if_index;
9455   int sw_if_index_set;
9456   u32 table_index = ~0;
9457   u8 is_ipv6 = 0;
9458
9459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9460     {
9461       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9462         sw_if_index_set = 1;
9463       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9464         sw_if_index_set = 1;
9465       else if (unformat (i, "table %d", &table_index))
9466         ;
9467       else
9468         {
9469           clib_warning ("parse error '%U'", format_unformat_error, i);
9470           return -99;
9471         }
9472     }
9473
9474   if (sw_if_index_set == 0)
9475     {
9476       errmsg ("missing interface name or sw_if_index\n");
9477       return -99;
9478     }
9479
9480
9481   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9482
9483   mp->sw_if_index = ntohl (sw_if_index);
9484   mp->table_index = ntohl (table_index);
9485   mp->is_ipv6 = is_ipv6;
9486
9487   S;
9488   W;
9489   /* NOTREACHED */
9490   return 0;
9491 }
9492
9493 static int
9494 api_classify_set_interface_l2_tables (vat_main_t * vam)
9495 {
9496   unformat_input_t *i = vam->input;
9497   vl_api_classify_set_interface_l2_tables_t *mp;
9498   f64 timeout;
9499   u32 sw_if_index;
9500   int sw_if_index_set;
9501   u32 ip4_table_index = ~0;
9502   u32 ip6_table_index = ~0;
9503   u32 other_table_index = ~0;
9504   u32 is_input = 1;
9505
9506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9507     {
9508       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9509         sw_if_index_set = 1;
9510       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9511         sw_if_index_set = 1;
9512       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9513         ;
9514       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9515         ;
9516       else if (unformat (i, "other-table %d", &other_table_index))
9517         ;
9518       else if (unformat (i, "is-input %d", &is_input))
9519         ;
9520       else
9521         {
9522           clib_warning ("parse error '%U'", format_unformat_error, i);
9523           return -99;
9524         }
9525     }
9526
9527   if (sw_if_index_set == 0)
9528     {
9529       errmsg ("missing interface name or sw_if_index\n");
9530       return -99;
9531     }
9532
9533
9534   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9535
9536   mp->sw_if_index = ntohl (sw_if_index);
9537   mp->ip4_table_index = ntohl (ip4_table_index);
9538   mp->ip6_table_index = ntohl (ip6_table_index);
9539   mp->other_table_index = ntohl (other_table_index);
9540   mp->is_input = (u8) is_input;
9541
9542   S;
9543   W;
9544   /* NOTREACHED */
9545   return 0;
9546 }
9547
9548 static int
9549 api_set_ipfix_exporter (vat_main_t * vam)
9550 {
9551   unformat_input_t *i = vam->input;
9552   vl_api_set_ipfix_exporter_t *mp;
9553   ip4_address_t collector_address;
9554   u8 collector_address_set = 0;
9555   u32 collector_port = ~0;
9556   ip4_address_t src_address;
9557   u8 src_address_set = 0;
9558   u32 vrf_id = ~0;
9559   u32 path_mtu = ~0;
9560   u32 template_interval = ~0;
9561   u8 udp_checksum = 0;
9562   f64 timeout;
9563
9564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9565     {
9566       if (unformat (i, "collector_address %U", unformat_ip4_address,
9567                     &collector_address))
9568         collector_address_set = 1;
9569       else if (unformat (i, "collector_port %d", &collector_port))
9570         ;
9571       else if (unformat (i, "src_address %U", unformat_ip4_address,
9572                          &src_address))
9573         src_address_set = 1;
9574       else if (unformat (i, "vrf_id %d", &vrf_id))
9575         ;
9576       else if (unformat (i, "path_mtu %d", &path_mtu))
9577         ;
9578       else if (unformat (i, "template_interval %d", &template_interval))
9579         ;
9580       else if (unformat (i, "udp_checksum"))
9581         udp_checksum = 1;
9582       else
9583         break;
9584     }
9585
9586   if (collector_address_set == 0)
9587     {
9588       errmsg ("collector_address required\n");
9589       return -99;
9590     }
9591
9592   if (src_address_set == 0)
9593     {
9594       errmsg ("src_address required\n");
9595       return -99;
9596     }
9597
9598   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9599
9600   memcpy (mp->collector_address, collector_address.data,
9601           sizeof (collector_address.data));
9602   mp->collector_port = htons ((u16) collector_port);
9603   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9604   mp->vrf_id = htonl (vrf_id);
9605   mp->path_mtu = htonl (path_mtu);
9606   mp->template_interval = htonl (template_interval);
9607   mp->udp_checksum = udp_checksum;
9608
9609   S;
9610   W;
9611   /* NOTREACHED */
9612 }
9613
9614 static int
9615 api_set_ipfix_classify_stream (vat_main_t * vam)
9616 {
9617   unformat_input_t *i = vam->input;
9618   vl_api_set_ipfix_classify_stream_t *mp;
9619   u32 domain_id = 0;
9620   u32 src_port = UDP_DST_PORT_ipfix;
9621   f64 timeout;
9622
9623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9624     {
9625       if (unformat (i, "domain %d", &domain_id))
9626         ;
9627       else if (unformat (i, "src_port %d", &src_port))
9628         ;
9629       else
9630         {
9631           errmsg ("unknown input `%U'", format_unformat_error, i);
9632           return -99;
9633         }
9634     }
9635
9636   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9637
9638   mp->domain_id = htonl (domain_id);
9639   mp->src_port = htons ((u16) src_port);
9640
9641   S;
9642   W;
9643   /* NOTREACHED */
9644 }
9645
9646 static int
9647 api_ipfix_classify_table_add_del (vat_main_t * vam)
9648 {
9649   unformat_input_t *i = vam->input;
9650   vl_api_ipfix_classify_table_add_del_t *mp;
9651   int is_add = -1;
9652   u32 classify_table_index = ~0;
9653   u8 ip_version = 0;
9654   u8 transport_protocol = 255;
9655   f64 timeout;
9656
9657   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9658     {
9659       if (unformat (i, "add"))
9660         is_add = 1;
9661       else if (unformat (i, "del"))
9662         is_add = 0;
9663       else if (unformat (i, "table %d", &classify_table_index))
9664         ;
9665       else if (unformat (i, "ip4"))
9666         ip_version = 4;
9667       else if (unformat (i, "ip6"))
9668         ip_version = 6;
9669       else if (unformat (i, "tcp"))
9670         transport_protocol = 6;
9671       else if (unformat (i, "udp"))
9672         transport_protocol = 17;
9673       else
9674         {
9675           errmsg ("unknown input `%U'", format_unformat_error, i);
9676           return -99;
9677         }
9678     }
9679
9680   if (is_add == -1)
9681     {
9682       errmsg ("expecting: add|del");
9683       return -99;
9684     }
9685   if (classify_table_index == ~0)
9686     {
9687       errmsg ("classifier table not specified");
9688       return -99;
9689     }
9690   if (ip_version == 0)
9691     {
9692       errmsg ("IP version not specified");
9693       return -99;
9694     }
9695
9696   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9697
9698   mp->is_add = is_add;
9699   mp->table_id = htonl (classify_table_index);
9700   mp->ip_version = ip_version;
9701   mp->transport_protocol = transport_protocol;
9702
9703   S;
9704   W;
9705   /* NOTREACHED */
9706 }
9707
9708 static int
9709 api_get_node_index (vat_main_t * vam)
9710 {
9711   unformat_input_t *i = vam->input;
9712   vl_api_get_node_index_t *mp;
9713   f64 timeout;
9714   u8 *name = 0;
9715
9716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9717     {
9718       if (unformat (i, "node %s", &name))
9719         ;
9720       else
9721         break;
9722     }
9723   if (name == 0)
9724     {
9725       errmsg ("node name required\n");
9726       return -99;
9727     }
9728   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9729     {
9730       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9731       return -99;
9732     }
9733
9734   M (GET_NODE_INDEX, get_node_index);
9735   clib_memcpy (mp->node_name, name, vec_len (name));
9736   vec_free (name);
9737
9738   S;
9739   W;
9740   /* NOTREACHED */
9741   return 0;
9742 }
9743
9744 static int
9745 api_get_next_index (vat_main_t * vam)
9746 {
9747   unformat_input_t *i = vam->input;
9748   vl_api_get_next_index_t *mp;
9749   f64 timeout;
9750   u8 *node_name = 0, *next_node_name = 0;
9751
9752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9753     {
9754       if (unformat (i, "node-name %s", &node_name))
9755         ;
9756       else if (unformat (i, "next-node-name %s", &next_node_name))
9757         break;
9758     }
9759
9760   if (node_name == 0)
9761     {
9762       errmsg ("node name required\n");
9763       return -99;
9764     }
9765   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9766     {
9767       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9768       return -99;
9769     }
9770
9771   if (next_node_name == 0)
9772     {
9773       errmsg ("next node name required\n");
9774       return -99;
9775     }
9776   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9777     {
9778       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9779       return -99;
9780     }
9781
9782   M (GET_NEXT_INDEX, get_next_index);
9783   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9784   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9785   vec_free (node_name);
9786   vec_free (next_node_name);
9787
9788   S;
9789   W;
9790   /* NOTREACHED */
9791   return 0;
9792 }
9793
9794 static int
9795 api_add_node_next (vat_main_t * vam)
9796 {
9797   unformat_input_t *i = vam->input;
9798   vl_api_add_node_next_t *mp;
9799   f64 timeout;
9800   u8 *name = 0;
9801   u8 *next = 0;
9802
9803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9804     {
9805       if (unformat (i, "node %s", &name))
9806         ;
9807       else if (unformat (i, "next %s", &next))
9808         ;
9809       else
9810         break;
9811     }
9812   if (name == 0)
9813     {
9814       errmsg ("node name required\n");
9815       return -99;
9816     }
9817   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9818     {
9819       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9820       return -99;
9821     }
9822   if (next == 0)
9823     {
9824       errmsg ("next node required\n");
9825       return -99;
9826     }
9827   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9828     {
9829       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9830       return -99;
9831     }
9832
9833   M (ADD_NODE_NEXT, add_node_next);
9834   clib_memcpy (mp->node_name, name, vec_len (name));
9835   clib_memcpy (mp->next_name, next, vec_len (next));
9836   vec_free (name);
9837   vec_free (next);
9838
9839   S;
9840   W;
9841   /* NOTREACHED */
9842   return 0;
9843 }
9844
9845 static int
9846 api_l2tpv3_create_tunnel (vat_main_t * vam)
9847 {
9848   unformat_input_t *i = vam->input;
9849   ip6_address_t client_address, our_address;
9850   int client_address_set = 0;
9851   int our_address_set = 0;
9852   u32 local_session_id = 0;
9853   u32 remote_session_id = 0;
9854   u64 local_cookie = 0;
9855   u64 remote_cookie = 0;
9856   u8 l2_sublayer_present = 0;
9857   vl_api_l2tpv3_create_tunnel_t *mp;
9858   f64 timeout;
9859
9860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9861     {
9862       if (unformat (i, "client_address %U", unformat_ip6_address,
9863                     &client_address))
9864         client_address_set = 1;
9865       else if (unformat (i, "our_address %U", unformat_ip6_address,
9866                          &our_address))
9867         our_address_set = 1;
9868       else if (unformat (i, "local_session_id %d", &local_session_id))
9869         ;
9870       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9871         ;
9872       else if (unformat (i, "local_cookie %lld", &local_cookie))
9873         ;
9874       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9875         ;
9876       else if (unformat (i, "l2-sublayer-present"))
9877         l2_sublayer_present = 1;
9878       else
9879         break;
9880     }
9881
9882   if (client_address_set == 0)
9883     {
9884       errmsg ("client_address required\n");
9885       return -99;
9886     }
9887
9888   if (our_address_set == 0)
9889     {
9890       errmsg ("our_address required\n");
9891       return -99;
9892     }
9893
9894   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9895
9896   clib_memcpy (mp->client_address, client_address.as_u8,
9897                sizeof (mp->client_address));
9898
9899   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9900
9901   mp->local_session_id = ntohl (local_session_id);
9902   mp->remote_session_id = ntohl (remote_session_id);
9903   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9904   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9905   mp->l2_sublayer_present = l2_sublayer_present;
9906   mp->is_ipv6 = 1;
9907
9908   S;
9909   W;
9910   /* NOTREACHED */
9911   return 0;
9912 }
9913
9914 static int
9915 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9916 {
9917   unformat_input_t *i = vam->input;
9918   u32 sw_if_index;
9919   u8 sw_if_index_set = 0;
9920   u64 new_local_cookie = 0;
9921   u64 new_remote_cookie = 0;
9922   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9923   f64 timeout;
9924
9925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9926     {
9927       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9928         sw_if_index_set = 1;
9929       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9930         sw_if_index_set = 1;
9931       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9932         ;
9933       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9934         ;
9935       else
9936         break;
9937     }
9938
9939   if (sw_if_index_set == 0)
9940     {
9941       errmsg ("missing interface name or sw_if_index\n");
9942       return -99;
9943     }
9944
9945   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9946
9947   mp->sw_if_index = ntohl (sw_if_index);
9948   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9949   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9950
9951   S;
9952   W;
9953   /* NOTREACHED */
9954   return 0;
9955 }
9956
9957 static int
9958 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9959 {
9960   unformat_input_t *i = vam->input;
9961   vl_api_l2tpv3_interface_enable_disable_t *mp;
9962   f64 timeout;
9963   u32 sw_if_index;
9964   u8 sw_if_index_set = 0;
9965   u8 enable_disable = 1;
9966
9967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9968     {
9969       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9970         sw_if_index_set = 1;
9971       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9972         sw_if_index_set = 1;
9973       else if (unformat (i, "enable"))
9974         enable_disable = 1;
9975       else if (unformat (i, "disable"))
9976         enable_disable = 0;
9977       else
9978         break;
9979     }
9980
9981   if (sw_if_index_set == 0)
9982     {
9983       errmsg ("missing interface name or sw_if_index\n");
9984       return -99;
9985     }
9986
9987   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9988
9989   mp->sw_if_index = ntohl (sw_if_index);
9990   mp->enable_disable = enable_disable;
9991
9992   S;
9993   W;
9994   /* NOTREACHED */
9995   return 0;
9996 }
9997
9998 static int
9999 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10000 {
10001   unformat_input_t *i = vam->input;
10002   vl_api_l2tpv3_set_lookup_key_t *mp;
10003   f64 timeout;
10004   u8 key = ~0;
10005
10006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10007     {
10008       if (unformat (i, "lookup_v6_src"))
10009         key = L2T_LOOKUP_SRC_ADDRESS;
10010       else if (unformat (i, "lookup_v6_dst"))
10011         key = L2T_LOOKUP_DST_ADDRESS;
10012       else if (unformat (i, "lookup_session_id"))
10013         key = L2T_LOOKUP_SESSION_ID;
10014       else
10015         break;
10016     }
10017
10018   if (key == (u8) ~ 0)
10019     {
10020       errmsg ("l2tp session lookup key unset\n");
10021       return -99;
10022     }
10023
10024   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
10025
10026   mp->key = key;
10027
10028   S;
10029   W;
10030   /* NOTREACHED */
10031   return 0;
10032 }
10033
10034 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10035   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10036 {
10037   vat_main_t *vam = &vat_main;
10038
10039   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
10040            format_ip6_address, mp->our_address,
10041            format_ip6_address, mp->client_address,
10042            clib_net_to_host_u32 (mp->sw_if_index));
10043
10044   fformat (vam->ofp,
10045            "   local cookies %016llx %016llx remote cookie %016llx\n",
10046            clib_net_to_host_u64 (mp->local_cookie[0]),
10047            clib_net_to_host_u64 (mp->local_cookie[1]),
10048            clib_net_to_host_u64 (mp->remote_cookie));
10049
10050   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
10051            clib_net_to_host_u32 (mp->local_session_id),
10052            clib_net_to_host_u32 (mp->remote_session_id));
10053
10054   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
10055            mp->l2_sublayer_present ? "preset" : "absent");
10056
10057 }
10058
10059 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10060   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10061 {
10062   vat_main_t *vam = &vat_main;
10063   vat_json_node_t *node = NULL;
10064   struct in6_addr addr;
10065
10066   if (VAT_JSON_ARRAY != vam->json_tree.type)
10067     {
10068       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10069       vat_json_init_array (&vam->json_tree);
10070     }
10071   node = vat_json_array_add (&vam->json_tree);
10072
10073   vat_json_init_object (node);
10074
10075   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10076   vat_json_object_add_ip6 (node, "our_address", addr);
10077   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10078   vat_json_object_add_ip6 (node, "client_address", addr);
10079
10080   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10081   vat_json_init_array (lc);
10082   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10083   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10084   vat_json_object_add_uint (node, "remote_cookie",
10085                             clib_net_to_host_u64 (mp->remote_cookie));
10086
10087   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10088   vat_json_object_add_uint (node, "local_session_id",
10089                             clib_net_to_host_u32 (mp->local_session_id));
10090   vat_json_object_add_uint (node, "remote_session_id",
10091                             clib_net_to_host_u32 (mp->remote_session_id));
10092   vat_json_object_add_string_copy (node, "l2_sublayer",
10093                                    mp->l2_sublayer_present ? (u8 *) "present"
10094                                    : (u8 *) "absent");
10095 }
10096
10097 static int
10098 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10099 {
10100   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10101   f64 timeout;
10102
10103   /* Get list of l2tpv3-tunnel interfaces */
10104   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10105   S;
10106
10107   /* Use a control ping for synchronization */
10108   {
10109     vl_api_control_ping_t *mp;
10110     M (CONTROL_PING, control_ping);
10111     S;
10112   }
10113   W;
10114 }
10115
10116
10117 static void vl_api_sw_interface_tap_details_t_handler
10118   (vl_api_sw_interface_tap_details_t * mp)
10119 {
10120   vat_main_t *vam = &vat_main;
10121
10122   fformat (vam->ofp, "%-16s %d\n",
10123            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10124 }
10125
10126 static void vl_api_sw_interface_tap_details_t_handler_json
10127   (vl_api_sw_interface_tap_details_t * mp)
10128 {
10129   vat_main_t *vam = &vat_main;
10130   vat_json_node_t *node = NULL;
10131
10132   if (VAT_JSON_ARRAY != vam->json_tree.type)
10133     {
10134       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10135       vat_json_init_array (&vam->json_tree);
10136     }
10137   node = vat_json_array_add (&vam->json_tree);
10138
10139   vat_json_init_object (node);
10140   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10141   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10142 }
10143
10144 static int
10145 api_sw_interface_tap_dump (vat_main_t * vam)
10146 {
10147   vl_api_sw_interface_tap_dump_t *mp;
10148   f64 timeout;
10149
10150   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10151   /* Get list of tap interfaces */
10152   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10153   S;
10154
10155   /* Use a control ping for synchronization */
10156   {
10157     vl_api_control_ping_t *mp;
10158     M (CONTROL_PING, control_ping);
10159     S;
10160   }
10161   W;
10162 }
10163
10164 static uword unformat_vxlan_decap_next
10165   (unformat_input_t * input, va_list * args)
10166 {
10167   u32 *result = va_arg (*args, u32 *);
10168   u32 tmp;
10169
10170   if (unformat (input, "l2"))
10171     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10172   else if (unformat (input, "%d", &tmp))
10173     *result = tmp;
10174   else
10175     return 0;
10176   return 1;
10177 }
10178
10179 static int
10180 api_vxlan_add_del_tunnel (vat_main_t * vam)
10181 {
10182   unformat_input_t *line_input = vam->input;
10183   vl_api_vxlan_add_del_tunnel_t *mp;
10184   f64 timeout;
10185   ip46_address_t src, dst;
10186   u8 is_add = 1;
10187   u8 ipv4_set = 0, ipv6_set = 0;
10188   u8 src_set = 0;
10189   u8 dst_set = 0;
10190   u8 grp_set = 0;
10191   u32 mcast_sw_if_index = ~0;
10192   u32 encap_vrf_id = 0;
10193   u32 decap_next_index = ~0;
10194   u32 vni = 0;
10195
10196   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10197   memset (&src, 0, sizeof src);
10198   memset (&dst, 0, sizeof dst);
10199
10200   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10201     {
10202       if (unformat (line_input, "del"))
10203         is_add = 0;
10204       else
10205         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10206         {
10207           ipv4_set = 1;
10208           src_set = 1;
10209         }
10210       else
10211         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10212         {
10213           ipv4_set = 1;
10214           dst_set = 1;
10215         }
10216       else
10217         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10218         {
10219           ipv6_set = 1;
10220           src_set = 1;
10221         }
10222       else
10223         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10224         {
10225           ipv6_set = 1;
10226           dst_set = 1;
10227         }
10228       else if (unformat (line_input, "group %U %U",
10229                          unformat_ip4_address, &dst.ip4,
10230                          unformat_sw_if_index, vam, &mcast_sw_if_index))
10231         {
10232           grp_set = dst_set = 1;
10233           ipv4_set = 1;
10234         }
10235       else if (unformat (line_input, "group %U",
10236                          unformat_ip4_address, &dst.ip4))
10237         {
10238           grp_set = dst_set = 1;
10239           ipv4_set = 1;
10240         }
10241       else if (unformat (line_input, "group %U %U",
10242                          unformat_ip6_address, &dst.ip6,
10243                          unformat_sw_if_index, vam, &mcast_sw_if_index))
10244         {
10245           grp_set = dst_set = 1;
10246           ipv6_set = 1;
10247         }
10248       else if (unformat (line_input, "group %U",
10249                          unformat_ip6_address, &dst.ip6))
10250         {
10251           grp_set = dst_set = 1;
10252           ipv6_set = 1;
10253         }
10254       else
10255         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10256         ;
10257       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10258         ;
10259       else if (unformat (line_input, "decap-next %U",
10260                          unformat_vxlan_decap_next, &decap_next_index))
10261         ;
10262       else if (unformat (line_input, "vni %d", &vni))
10263         ;
10264       else
10265         {
10266           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10267           return -99;
10268         }
10269     }
10270
10271   if (src_set == 0)
10272     {
10273       errmsg ("tunnel src address not specified\n");
10274       return -99;
10275     }
10276   if (dst_set == 0)
10277     {
10278       errmsg ("tunnel dst address not specified\n");
10279       return -99;
10280     }
10281
10282   if (grp_set && !ip46_address_is_multicast (&dst))
10283     {
10284       errmsg ("tunnel group address not multicast\n");
10285       return -99;
10286     }
10287   if (grp_set && mcast_sw_if_index == ~0)
10288     {
10289       errmsg ("tunnel nonexistent multicast device\n");
10290       return -99;
10291     }
10292
10293
10294   if (ipv4_set && ipv6_set)
10295     {
10296       errmsg ("both IPv4 and IPv6 addresses specified");
10297       return -99;
10298     }
10299
10300   if ((vni == 0) || (vni >> 24))
10301     {
10302       errmsg ("vni not specified or out of range\n");
10303       return -99;
10304     }
10305
10306   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10307
10308   if (ipv6_set)
10309     {
10310       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10311       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10312     }
10313   else
10314     {
10315       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10316       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10317     }
10318   mp->encap_vrf_id = ntohl (encap_vrf_id);
10319   mp->decap_next_index = ntohl (decap_next_index);
10320   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10321   mp->vni = ntohl (vni);
10322   mp->is_add = is_add;
10323   mp->is_ipv6 = ipv6_set;
10324
10325   S;
10326   W;
10327   /* NOTREACHED */
10328   return 0;
10329 }
10330
10331 static void vl_api_vxlan_tunnel_details_t_handler
10332   (vl_api_vxlan_tunnel_details_t * mp)
10333 {
10334   vat_main_t *vam = &vat_main;
10335   ip46_address_t src, dst;
10336
10337   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10338   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10339
10340   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d\n",
10341            ntohl (mp->sw_if_index),
10342            format_ip46_address, &src, IP46_TYPE_ANY,
10343            format_ip46_address, &dst, IP46_TYPE_ANY,
10344            ntohl (mp->encap_vrf_id),
10345            ntohl (mp->decap_next_index), ntohl (mp->vni),
10346            ntohl (mp->mcast_sw_if_index));
10347 }
10348
10349 static void vl_api_vxlan_tunnel_details_t_handler_json
10350   (vl_api_vxlan_tunnel_details_t * mp)
10351 {
10352   vat_main_t *vam = &vat_main;
10353   vat_json_node_t *node = NULL;
10354
10355   if (VAT_JSON_ARRAY != vam->json_tree.type)
10356     {
10357       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10358       vat_json_init_array (&vam->json_tree);
10359     }
10360   node = vat_json_array_add (&vam->json_tree);
10361
10362   vat_json_init_object (node);
10363   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10364   if (mp->is_ipv6)
10365     {
10366       struct in6_addr ip6;
10367
10368       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10369       vat_json_object_add_ip6 (node, "src_address", ip6);
10370       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10371       vat_json_object_add_ip6 (node, "dst_address", ip6);
10372     }
10373   else
10374     {
10375       struct in_addr ip4;
10376
10377       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10378       vat_json_object_add_ip4 (node, "src_address", ip4);
10379       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10380       vat_json_object_add_ip4 (node, "dst_address", ip4);
10381     }
10382   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10383   vat_json_object_add_uint (node, "decap_next_index",
10384                             ntohl (mp->decap_next_index));
10385   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10386   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10387   vat_json_object_add_uint (node, "mcast_sw_if_index",
10388                             ntohl (mp->mcast_sw_if_index));
10389 }
10390
10391 static int
10392 api_vxlan_tunnel_dump (vat_main_t * vam)
10393 {
10394   unformat_input_t *i = vam->input;
10395   vl_api_vxlan_tunnel_dump_t *mp;
10396   f64 timeout;
10397   u32 sw_if_index;
10398   u8 sw_if_index_set = 0;
10399
10400   /* Parse args required to build the message */
10401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10402     {
10403       if (unformat (i, "sw_if_index %d", &sw_if_index))
10404         sw_if_index_set = 1;
10405       else
10406         break;
10407     }
10408
10409   if (sw_if_index_set == 0)
10410     {
10411       sw_if_index = ~0;
10412     }
10413
10414   if (!vam->json_output)
10415     {
10416       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s\n",
10417                "sw_if_index", "src_address", "dst_address",
10418                "encap_vrf_id", "decap_next_index", "vni",
10419                "mcast_sw_if_index");
10420     }
10421
10422   /* Get list of vxlan-tunnel interfaces */
10423   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10424
10425   mp->sw_if_index = htonl (sw_if_index);
10426
10427   S;
10428
10429   /* Use a control ping for synchronization */
10430   {
10431     vl_api_control_ping_t *mp;
10432     M (CONTROL_PING, control_ping);
10433     S;
10434   }
10435   W;
10436 }
10437
10438 static int
10439 api_gre_add_del_tunnel (vat_main_t * vam)
10440 {
10441   unformat_input_t *line_input = vam->input;
10442   vl_api_gre_add_del_tunnel_t *mp;
10443   f64 timeout;
10444   ip4_address_t src4, dst4;
10445   u8 is_add = 1;
10446   u8 teb = 0;
10447   u8 src_set = 0;
10448   u8 dst_set = 0;
10449   u32 outer_fib_id = 0;
10450
10451   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10452     {
10453       if (unformat (line_input, "del"))
10454         is_add = 0;
10455       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10456         src_set = 1;
10457       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10458         dst_set = 1;
10459       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10460         ;
10461       else if (unformat (line_input, "teb"))
10462         teb = 1;
10463       else
10464         {
10465           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10466           return -99;
10467         }
10468     }
10469
10470   if (src_set == 0)
10471     {
10472       errmsg ("tunnel src address not specified\n");
10473       return -99;
10474     }
10475   if (dst_set == 0)
10476     {
10477       errmsg ("tunnel dst address not specified\n");
10478       return -99;
10479     }
10480
10481
10482   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10483
10484   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10485   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10486   mp->outer_fib_id = ntohl (outer_fib_id);
10487   mp->is_add = is_add;
10488   mp->teb = teb;
10489
10490   S;
10491   W;
10492   /* NOTREACHED */
10493   return 0;
10494 }
10495
10496 static void vl_api_gre_tunnel_details_t_handler
10497   (vl_api_gre_tunnel_details_t * mp)
10498 {
10499   vat_main_t *vam = &vat_main;
10500
10501   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10502            ntohl (mp->sw_if_index),
10503            format_ip4_address, &mp->src_address,
10504            format_ip4_address, &mp->dst_address,
10505            mp->teb, ntohl (mp->outer_fib_id));
10506 }
10507
10508 static void vl_api_gre_tunnel_details_t_handler_json
10509   (vl_api_gre_tunnel_details_t * mp)
10510 {
10511   vat_main_t *vam = &vat_main;
10512   vat_json_node_t *node = NULL;
10513   struct in_addr ip4;
10514
10515   if (VAT_JSON_ARRAY != vam->json_tree.type)
10516     {
10517       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10518       vat_json_init_array (&vam->json_tree);
10519     }
10520   node = vat_json_array_add (&vam->json_tree);
10521
10522   vat_json_init_object (node);
10523   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10524   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10525   vat_json_object_add_ip4 (node, "src_address", ip4);
10526   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10527   vat_json_object_add_ip4 (node, "dst_address", ip4);
10528   vat_json_object_add_uint (node, "teb", mp->teb);
10529   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10530 }
10531
10532 static int
10533 api_gre_tunnel_dump (vat_main_t * vam)
10534 {
10535   unformat_input_t *i = vam->input;
10536   vl_api_gre_tunnel_dump_t *mp;
10537   f64 timeout;
10538   u32 sw_if_index;
10539   u8 sw_if_index_set = 0;
10540
10541   /* Parse args required to build the message */
10542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10543     {
10544       if (unformat (i, "sw_if_index %d", &sw_if_index))
10545         sw_if_index_set = 1;
10546       else
10547         break;
10548     }
10549
10550   if (sw_if_index_set == 0)
10551     {
10552       sw_if_index = ~0;
10553     }
10554
10555   if (!vam->json_output)
10556     {
10557       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10558                "sw_if_index", "src_address", "dst_address", "teb",
10559                "outer_fib_id");
10560     }
10561
10562   /* Get list of gre-tunnel interfaces */
10563   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10564
10565   mp->sw_if_index = htonl (sw_if_index);
10566
10567   S;
10568
10569   /* Use a control ping for synchronization */
10570   {
10571     vl_api_control_ping_t *mp;
10572     M (CONTROL_PING, control_ping);
10573     S;
10574   }
10575   W;
10576 }
10577
10578 static int
10579 api_l2_fib_clear_table (vat_main_t * vam)
10580 {
10581 //  unformat_input_t * i = vam->input;
10582   vl_api_l2_fib_clear_table_t *mp;
10583   f64 timeout;
10584
10585   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10586
10587   S;
10588   W;
10589   /* NOTREACHED */
10590   return 0;
10591 }
10592
10593 static int
10594 api_l2_interface_efp_filter (vat_main_t * vam)
10595 {
10596   unformat_input_t *i = vam->input;
10597   vl_api_l2_interface_efp_filter_t *mp;
10598   f64 timeout;
10599   u32 sw_if_index;
10600   u8 enable = 1;
10601   u8 sw_if_index_set = 0;
10602
10603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10604     {
10605       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10606         sw_if_index_set = 1;
10607       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10608         sw_if_index_set = 1;
10609       else if (unformat (i, "enable"))
10610         enable = 1;
10611       else if (unformat (i, "disable"))
10612         enable = 0;
10613       else
10614         {
10615           clib_warning ("parse error '%U'", format_unformat_error, i);
10616           return -99;
10617         }
10618     }
10619
10620   if (sw_if_index_set == 0)
10621     {
10622       errmsg ("missing sw_if_index\n");
10623       return -99;
10624     }
10625
10626   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10627
10628   mp->sw_if_index = ntohl (sw_if_index);
10629   mp->enable_disable = enable;
10630
10631   S;
10632   W;
10633   /* NOTREACHED */
10634   return 0;
10635 }
10636
10637 #define foreach_vtr_op                          \
10638 _("disable",  L2_VTR_DISABLED)                  \
10639 _("push-1",  L2_VTR_PUSH_1)                     \
10640 _("push-2",  L2_VTR_PUSH_2)                     \
10641 _("pop-1",  L2_VTR_POP_1)                       \
10642 _("pop-2",  L2_VTR_POP_2)                       \
10643 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10644 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10645 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10646 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10647
10648 static int
10649 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10650 {
10651   unformat_input_t *i = vam->input;
10652   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10653   f64 timeout;
10654   u32 sw_if_index;
10655   u8 sw_if_index_set = 0;
10656   u8 vtr_op_set = 0;
10657   u32 vtr_op = 0;
10658   u32 push_dot1q = 1;
10659   u32 tag1 = ~0;
10660   u32 tag2 = ~0;
10661
10662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10663     {
10664       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10665         sw_if_index_set = 1;
10666       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10667         sw_if_index_set = 1;
10668       else if (unformat (i, "vtr_op %d", &vtr_op))
10669         vtr_op_set = 1;
10670 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10671       foreach_vtr_op
10672 #undef _
10673         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10674         ;
10675       else if (unformat (i, "tag1 %d", &tag1))
10676         ;
10677       else if (unformat (i, "tag2 %d", &tag2))
10678         ;
10679       else
10680         {
10681           clib_warning ("parse error '%U'", format_unformat_error, i);
10682           return -99;
10683         }
10684     }
10685
10686   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10687     {
10688       errmsg ("missing vtr operation or sw_if_index\n");
10689       return -99;
10690     }
10691
10692   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10693     mp->sw_if_index = ntohl (sw_if_index);
10694   mp->vtr_op = ntohl (vtr_op);
10695   mp->push_dot1q = ntohl (push_dot1q);
10696   mp->tag1 = ntohl (tag1);
10697   mp->tag2 = ntohl (tag2);
10698
10699   S;
10700   W;
10701   /* NOTREACHED */
10702   return 0;
10703 }
10704
10705 static int
10706 api_create_vhost_user_if (vat_main_t * vam)
10707 {
10708   unformat_input_t *i = vam->input;
10709   vl_api_create_vhost_user_if_t *mp;
10710   f64 timeout;
10711   u8 *file_name;
10712   u8 is_server = 0;
10713   u8 file_name_set = 0;
10714   u32 custom_dev_instance = ~0;
10715   u8 hwaddr[6];
10716   u8 use_custom_mac = 0;
10717   u8 *tag = 0;
10718
10719   /* Shut up coverity */
10720   memset (hwaddr, 0, sizeof (hwaddr));
10721
10722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10723     {
10724       if (unformat (i, "socket %s", &file_name))
10725         {
10726           file_name_set = 1;
10727         }
10728       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10729         ;
10730       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10731         use_custom_mac = 1;
10732       else if (unformat (i, "server"))
10733         is_server = 1;
10734       else if (unformat (i, "tag %s", &tag))
10735         ;
10736       else
10737         break;
10738     }
10739
10740   if (file_name_set == 0)
10741     {
10742       errmsg ("missing socket file name\n");
10743       return -99;
10744     }
10745
10746   if (vec_len (file_name) > 255)
10747     {
10748       errmsg ("socket file name too long\n");
10749       return -99;
10750     }
10751   vec_add1 (file_name, 0);
10752
10753   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10754
10755   mp->is_server = is_server;
10756   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10757   vec_free (file_name);
10758   if (custom_dev_instance != ~0)
10759     {
10760       mp->renumber = 1;
10761       mp->custom_dev_instance = ntohl (custom_dev_instance);
10762     }
10763   mp->use_custom_mac = use_custom_mac;
10764   clib_memcpy (mp->mac_address, hwaddr, 6);
10765   if (tag)
10766     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10767   vec_free (tag);
10768
10769   S;
10770   W;
10771   /* NOTREACHED */
10772   return 0;
10773 }
10774
10775 static int
10776 api_modify_vhost_user_if (vat_main_t * vam)
10777 {
10778   unformat_input_t *i = vam->input;
10779   vl_api_modify_vhost_user_if_t *mp;
10780   f64 timeout;
10781   u8 *file_name;
10782   u8 is_server = 0;
10783   u8 file_name_set = 0;
10784   u32 custom_dev_instance = ~0;
10785   u8 sw_if_index_set = 0;
10786   u32 sw_if_index = (u32) ~ 0;
10787
10788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10789     {
10790       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10791         sw_if_index_set = 1;
10792       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10793         sw_if_index_set = 1;
10794       else if (unformat (i, "socket %s", &file_name))
10795         {
10796           file_name_set = 1;
10797         }
10798       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10799         ;
10800       else if (unformat (i, "server"))
10801         is_server = 1;
10802       else
10803         break;
10804     }
10805
10806   if (sw_if_index_set == 0)
10807     {
10808       errmsg ("missing sw_if_index or interface name\n");
10809       return -99;
10810     }
10811
10812   if (file_name_set == 0)
10813     {
10814       errmsg ("missing socket file name\n");
10815       return -99;
10816     }
10817
10818   if (vec_len (file_name) > 255)
10819     {
10820       errmsg ("socket file name too long\n");
10821       return -99;
10822     }
10823   vec_add1 (file_name, 0);
10824
10825   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10826
10827   mp->sw_if_index = ntohl (sw_if_index);
10828   mp->is_server = is_server;
10829   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10830   vec_free (file_name);
10831   if (custom_dev_instance != ~0)
10832     {
10833       mp->renumber = 1;
10834       mp->custom_dev_instance = ntohl (custom_dev_instance);
10835     }
10836
10837   S;
10838   W;
10839   /* NOTREACHED */
10840   return 0;
10841 }
10842
10843 static int
10844 api_delete_vhost_user_if (vat_main_t * vam)
10845 {
10846   unformat_input_t *i = vam->input;
10847   vl_api_delete_vhost_user_if_t *mp;
10848   f64 timeout;
10849   u32 sw_if_index = ~0;
10850   u8 sw_if_index_set = 0;
10851
10852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10853     {
10854       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10855         sw_if_index_set = 1;
10856       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10857         sw_if_index_set = 1;
10858       else
10859         break;
10860     }
10861
10862   if (sw_if_index_set == 0)
10863     {
10864       errmsg ("missing sw_if_index or interface name\n");
10865       return -99;
10866     }
10867
10868
10869   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10870
10871   mp->sw_if_index = ntohl (sw_if_index);
10872
10873   S;
10874   W;
10875   /* NOTREACHED */
10876   return 0;
10877 }
10878
10879 static void vl_api_sw_interface_vhost_user_details_t_handler
10880   (vl_api_sw_interface_vhost_user_details_t * mp)
10881 {
10882   vat_main_t *vam = &vat_main;
10883
10884   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10885            (char *) mp->interface_name,
10886            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10887            clib_net_to_host_u64 (mp->features), mp->is_server,
10888            ntohl (mp->num_regions), (char *) mp->sock_filename);
10889   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10890 }
10891
10892 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10893   (vl_api_sw_interface_vhost_user_details_t * mp)
10894 {
10895   vat_main_t *vam = &vat_main;
10896   vat_json_node_t *node = NULL;
10897
10898   if (VAT_JSON_ARRAY != vam->json_tree.type)
10899     {
10900       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10901       vat_json_init_array (&vam->json_tree);
10902     }
10903   node = vat_json_array_add (&vam->json_tree);
10904
10905   vat_json_init_object (node);
10906   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10907   vat_json_object_add_string_copy (node, "interface_name",
10908                                    mp->interface_name);
10909   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10910                             ntohl (mp->virtio_net_hdr_sz));
10911   vat_json_object_add_uint (node, "features",
10912                             clib_net_to_host_u64 (mp->features));
10913   vat_json_object_add_uint (node, "is_server", mp->is_server);
10914   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10915   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10916   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10917 }
10918
10919 static int
10920 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10921 {
10922   vl_api_sw_interface_vhost_user_dump_t *mp;
10923   f64 timeout;
10924   fformat (vam->ofp,
10925            "Interface name           idx hdr_sz features server regions filename\n");
10926
10927   /* Get list of vhost-user interfaces */
10928   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10929   S;
10930
10931   /* Use a control ping for synchronization */
10932   {
10933     vl_api_control_ping_t *mp;
10934     M (CONTROL_PING, control_ping);
10935     S;
10936   }
10937   W;
10938 }
10939
10940 static int
10941 api_show_version (vat_main_t * vam)
10942 {
10943   vl_api_show_version_t *mp;
10944   f64 timeout;
10945
10946   M (SHOW_VERSION, show_version);
10947
10948   S;
10949   W;
10950   /* NOTREACHED */
10951   return 0;
10952 }
10953
10954
10955 static int
10956 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10957 {
10958   unformat_input_t *line_input = vam->input;
10959   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10960   f64 timeout;
10961   ip4_address_t local4, remote4;
10962   ip6_address_t local6, remote6;
10963   u8 is_add = 1;
10964   u8 ipv4_set = 0, ipv6_set = 0;
10965   u8 local_set = 0;
10966   u8 remote_set = 0;
10967   u32 encap_vrf_id = 0;
10968   u32 decap_vrf_id = 0;
10969   u8 protocol = ~0;
10970   u32 vni;
10971   u8 vni_set = 0;
10972
10973   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10974     {
10975       if (unformat (line_input, "del"))
10976         is_add = 0;
10977       else if (unformat (line_input, "local %U",
10978                          unformat_ip4_address, &local4))
10979         {
10980           local_set = 1;
10981           ipv4_set = 1;
10982         }
10983       else if (unformat (line_input, "remote %U",
10984                          unformat_ip4_address, &remote4))
10985         {
10986           remote_set = 1;
10987           ipv4_set = 1;
10988         }
10989       else if (unformat (line_input, "local %U",
10990                          unformat_ip6_address, &local6))
10991         {
10992           local_set = 1;
10993           ipv6_set = 1;
10994         }
10995       else if (unformat (line_input, "remote %U",
10996                          unformat_ip6_address, &remote6))
10997         {
10998           remote_set = 1;
10999           ipv6_set = 1;
11000         }
11001       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11002         ;
11003       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11004         ;
11005       else if (unformat (line_input, "vni %d", &vni))
11006         vni_set = 1;
11007       else if (unformat (line_input, "next-ip4"))
11008         protocol = 1;
11009       else if (unformat (line_input, "next-ip6"))
11010         protocol = 2;
11011       else if (unformat (line_input, "next-ethernet"))
11012         protocol = 3;
11013       else if (unformat (line_input, "next-nsh"))
11014         protocol = 4;
11015       else
11016         {
11017           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
11018           return -99;
11019         }
11020     }
11021
11022   if (local_set == 0)
11023     {
11024       errmsg ("tunnel local address not specified\n");
11025       return -99;
11026     }
11027   if (remote_set == 0)
11028     {
11029       errmsg ("tunnel remote address not specified\n");
11030       return -99;
11031     }
11032   if (ipv4_set && ipv6_set)
11033     {
11034       errmsg ("both IPv4 and IPv6 addresses specified");
11035       return -99;
11036     }
11037
11038   if (vni_set == 0)
11039     {
11040       errmsg ("vni not specified\n");
11041       return -99;
11042     }
11043
11044   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
11045
11046
11047   if (ipv6_set)
11048     {
11049       clib_memcpy (&mp->local, &local6, sizeof (local6));
11050       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11051     }
11052   else
11053     {
11054       clib_memcpy (&mp->local, &local4, sizeof (local4));
11055       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11056     }
11057
11058   mp->encap_vrf_id = ntohl (encap_vrf_id);
11059   mp->decap_vrf_id = ntohl (decap_vrf_id);
11060   mp->protocol = ntohl (protocol);
11061   mp->vni = ntohl (vni);
11062   mp->is_add = is_add;
11063   mp->is_ipv6 = ipv6_set;
11064
11065   S;
11066   W;
11067   /* NOTREACHED */
11068   return 0;
11069 }
11070
11071 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11072   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11073 {
11074   vat_main_t *vam = &vat_main;
11075
11076   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
11077            ntohl (mp->sw_if_index),
11078            format_ip46_address, &(mp->local[0]),
11079            format_ip46_address, &(mp->remote[0]),
11080            ntohl (mp->vni),
11081            ntohl (mp->protocol),
11082            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11083 }
11084
11085 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11086   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11087 {
11088   vat_main_t *vam = &vat_main;
11089   vat_json_node_t *node = NULL;
11090   struct in_addr ip4;
11091   struct in6_addr ip6;
11092
11093   if (VAT_JSON_ARRAY != vam->json_tree.type)
11094     {
11095       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11096       vat_json_init_array (&vam->json_tree);
11097     }
11098   node = vat_json_array_add (&vam->json_tree);
11099
11100   vat_json_init_object (node);
11101   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11102   if (mp->is_ipv6)
11103     {
11104       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11105       vat_json_object_add_ip6 (node, "local", ip6);
11106       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11107       vat_json_object_add_ip6 (node, "remote", ip6);
11108     }
11109   else
11110     {
11111       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11112       vat_json_object_add_ip4 (node, "local", ip4);
11113       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11114       vat_json_object_add_ip4 (node, "remote", ip4);
11115     }
11116   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11117   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11118   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11119   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11120   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11121 }
11122
11123 static int
11124 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11125 {
11126   unformat_input_t *i = vam->input;
11127   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11128   f64 timeout;
11129   u32 sw_if_index;
11130   u8 sw_if_index_set = 0;
11131
11132   /* Parse args required to build the message */
11133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11134     {
11135       if (unformat (i, "sw_if_index %d", &sw_if_index))
11136         sw_if_index_set = 1;
11137       else
11138         break;
11139     }
11140
11141   if (sw_if_index_set == 0)
11142     {
11143       sw_if_index = ~0;
11144     }
11145
11146   if (!vam->json_output)
11147     {
11148       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
11149                "sw_if_index", "local", "remote", "vni",
11150                "protocol", "encap_vrf_id", "decap_vrf_id");
11151     }
11152
11153   /* Get list of vxlan-tunnel interfaces */
11154   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11155
11156   mp->sw_if_index = htonl (sw_if_index);
11157
11158   S;
11159
11160   /* Use a control ping for synchronization */
11161   {
11162     vl_api_control_ping_t *mp;
11163     M (CONTROL_PING, control_ping);
11164     S;
11165   }
11166   W;
11167 }
11168
11169 u8 *
11170 format_l2_fib_mac_address (u8 * s, va_list * args)
11171 {
11172   u8 *a = va_arg (*args, u8 *);
11173
11174   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11175                  a[2], a[3], a[4], a[5], a[6], a[7]);
11176 }
11177
11178 static void vl_api_l2_fib_table_entry_t_handler
11179   (vl_api_l2_fib_table_entry_t * mp)
11180 {
11181   vat_main_t *vam = &vat_main;
11182
11183   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11184            "       %d       %d     %d\n",
11185            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11186            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11187            mp->bvi_mac);
11188 }
11189
11190 static void vl_api_l2_fib_table_entry_t_handler_json
11191   (vl_api_l2_fib_table_entry_t * mp)
11192 {
11193   vat_main_t *vam = &vat_main;
11194   vat_json_node_t *node = NULL;
11195
11196   if (VAT_JSON_ARRAY != vam->json_tree.type)
11197     {
11198       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11199       vat_json_init_array (&vam->json_tree);
11200     }
11201   node = vat_json_array_add (&vam->json_tree);
11202
11203   vat_json_init_object (node);
11204   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11205   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11206   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11207   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11208   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11209   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11210 }
11211
11212 static int
11213 api_l2_fib_table_dump (vat_main_t * vam)
11214 {
11215   unformat_input_t *i = vam->input;
11216   vl_api_l2_fib_table_dump_t *mp;
11217   f64 timeout;
11218   u32 bd_id;
11219   u8 bd_id_set = 0;
11220
11221   /* Parse args required to build the message */
11222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11223     {
11224       if (unformat (i, "bd_id %d", &bd_id))
11225         bd_id_set = 1;
11226       else
11227         break;
11228     }
11229
11230   if (bd_id_set == 0)
11231     {
11232       errmsg ("missing bridge domain\n");
11233       return -99;
11234     }
11235
11236   fformat (vam->ofp,
11237            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11238
11239   /* Get list of l2 fib entries */
11240   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11241
11242   mp->bd_id = ntohl (bd_id);
11243   S;
11244
11245   /* Use a control ping for synchronization */
11246   {
11247     vl_api_control_ping_t *mp;
11248     M (CONTROL_PING, control_ping);
11249     S;
11250   }
11251   W;
11252 }
11253
11254
11255 static int
11256 api_interface_name_renumber (vat_main_t * vam)
11257 {
11258   unformat_input_t *line_input = vam->input;
11259   vl_api_interface_name_renumber_t *mp;
11260   u32 sw_if_index = ~0;
11261   f64 timeout;
11262   u32 new_show_dev_instance = ~0;
11263
11264   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11265     {
11266       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11267                     &sw_if_index))
11268         ;
11269       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11270         ;
11271       else if (unformat (line_input, "new_show_dev_instance %d",
11272                          &new_show_dev_instance))
11273         ;
11274       else
11275         break;
11276     }
11277
11278   if (sw_if_index == ~0)
11279     {
11280       errmsg ("missing interface name or sw_if_index\n");
11281       return -99;
11282     }
11283
11284   if (new_show_dev_instance == ~0)
11285     {
11286       errmsg ("missing new_show_dev_instance\n");
11287       return -99;
11288     }
11289
11290   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11291
11292   mp->sw_if_index = ntohl (sw_if_index);
11293   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11294
11295   S;
11296   W;
11297 }
11298
11299 static int
11300 api_want_ip4_arp_events (vat_main_t * vam)
11301 {
11302   unformat_input_t *line_input = vam->input;
11303   vl_api_want_ip4_arp_events_t *mp;
11304   f64 timeout;
11305   ip4_address_t address;
11306   int address_set = 0;
11307   u32 enable_disable = 1;
11308
11309   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11310     {
11311       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11312         address_set = 1;
11313       else if (unformat (line_input, "del"))
11314         enable_disable = 0;
11315       else
11316         break;
11317     }
11318
11319   if (address_set == 0)
11320     {
11321       errmsg ("missing addresses\n");
11322       return -99;
11323     }
11324
11325   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11326   mp->enable_disable = enable_disable;
11327   mp->pid = getpid ();
11328   mp->address = address.as_u32;
11329
11330   S;
11331   W;
11332 }
11333
11334 static int
11335 api_want_ip6_nd_events (vat_main_t * vam)
11336 {
11337   unformat_input_t *line_input = vam->input;
11338   vl_api_want_ip6_nd_events_t *mp;
11339   f64 timeout;
11340   ip6_address_t address;
11341   int address_set = 0;
11342   u32 enable_disable = 1;
11343
11344   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11345     {
11346       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11347         address_set = 1;
11348       else if (unformat (line_input, "del"))
11349         enable_disable = 0;
11350       else
11351         break;
11352     }
11353
11354   if (address_set == 0)
11355     {
11356       errmsg ("missing addresses\n");
11357       return -99;
11358     }
11359
11360   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11361   mp->enable_disable = enable_disable;
11362   mp->pid = getpid ();
11363   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11364
11365   S;
11366   W;
11367 }
11368
11369 static int
11370 api_input_acl_set_interface (vat_main_t * vam)
11371 {
11372   unformat_input_t *i = vam->input;
11373   vl_api_input_acl_set_interface_t *mp;
11374   f64 timeout;
11375   u32 sw_if_index;
11376   int sw_if_index_set;
11377   u32 ip4_table_index = ~0;
11378   u32 ip6_table_index = ~0;
11379   u32 l2_table_index = ~0;
11380   u8 is_add = 1;
11381
11382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11383     {
11384       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11385         sw_if_index_set = 1;
11386       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11387         sw_if_index_set = 1;
11388       else if (unformat (i, "del"))
11389         is_add = 0;
11390       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11391         ;
11392       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11393         ;
11394       else if (unformat (i, "l2-table %d", &l2_table_index))
11395         ;
11396       else
11397         {
11398           clib_warning ("parse error '%U'", format_unformat_error, i);
11399           return -99;
11400         }
11401     }
11402
11403   if (sw_if_index_set == 0)
11404     {
11405       errmsg ("missing interface name or sw_if_index\n");
11406       return -99;
11407     }
11408
11409   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11410
11411   mp->sw_if_index = ntohl (sw_if_index);
11412   mp->ip4_table_index = ntohl (ip4_table_index);
11413   mp->ip6_table_index = ntohl (ip6_table_index);
11414   mp->l2_table_index = ntohl (l2_table_index);
11415   mp->is_add = is_add;
11416
11417   S;
11418   W;
11419   /* NOTREACHED */
11420   return 0;
11421 }
11422
11423 static int
11424 api_ip_address_dump (vat_main_t * vam)
11425 {
11426   unformat_input_t *i = vam->input;
11427   vl_api_ip_address_dump_t *mp;
11428   u32 sw_if_index = ~0;
11429   u8 sw_if_index_set = 0;
11430   u8 ipv4_set = 0;
11431   u8 ipv6_set = 0;
11432   f64 timeout;
11433
11434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11435     {
11436       if (unformat (i, "sw_if_index %d", &sw_if_index))
11437         sw_if_index_set = 1;
11438       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11439         sw_if_index_set = 1;
11440       else if (unformat (i, "ipv4"))
11441         ipv4_set = 1;
11442       else if (unformat (i, "ipv6"))
11443         ipv6_set = 1;
11444       else
11445         break;
11446     }
11447
11448   if (ipv4_set && ipv6_set)
11449     {
11450       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11451       return -99;
11452     }
11453
11454   if ((!ipv4_set) && (!ipv6_set))
11455     {
11456       errmsg ("no ipv4 nor ipv6 flag set\n");
11457       return -99;
11458     }
11459
11460   if (sw_if_index_set == 0)
11461     {
11462       errmsg ("missing interface name or sw_if_index\n");
11463       return -99;
11464     }
11465
11466   vam->current_sw_if_index = sw_if_index;
11467   vam->is_ipv6 = ipv6_set;
11468
11469   M (IP_ADDRESS_DUMP, ip_address_dump);
11470   mp->sw_if_index = ntohl (sw_if_index);
11471   mp->is_ipv6 = ipv6_set;
11472   S;
11473
11474   /* Use a control ping for synchronization */
11475   {
11476     vl_api_control_ping_t *mp;
11477     M (CONTROL_PING, control_ping);
11478     S;
11479   }
11480   W;
11481 }
11482
11483 static int
11484 api_ip_dump (vat_main_t * vam)
11485 {
11486   vl_api_ip_dump_t *mp;
11487   unformat_input_t *in = vam->input;
11488   int ipv4_set = 0;
11489   int ipv6_set = 0;
11490   int is_ipv6;
11491   f64 timeout;
11492   int i;
11493
11494   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11495     {
11496       if (unformat (in, "ipv4"))
11497         ipv4_set = 1;
11498       else if (unformat (in, "ipv6"))
11499         ipv6_set = 1;
11500       else
11501         break;
11502     }
11503
11504   if (ipv4_set && ipv6_set)
11505     {
11506       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11507       return -99;
11508     }
11509
11510   if ((!ipv4_set) && (!ipv6_set))
11511     {
11512       errmsg ("no ipv4 nor ipv6 flag set\n");
11513       return -99;
11514     }
11515
11516   is_ipv6 = ipv6_set;
11517   vam->is_ipv6 = is_ipv6;
11518
11519   /* free old data */
11520   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11521     {
11522       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11523     }
11524   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11525
11526   M (IP_DUMP, ip_dump);
11527   mp->is_ipv6 = ipv6_set;
11528   S;
11529
11530   /* Use a control ping for synchronization */
11531   {
11532     vl_api_control_ping_t *mp;
11533     M (CONTROL_PING, control_ping);
11534     S;
11535   }
11536   W;
11537 }
11538
11539 static int
11540 api_ipsec_spd_add_del (vat_main_t * vam)
11541 {
11542   unformat_input_t *i = vam->input;
11543   vl_api_ipsec_spd_add_del_t *mp;
11544   f64 timeout;
11545   u32 spd_id = ~0;
11546   u8 is_add = 1;
11547
11548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11549     {
11550       if (unformat (i, "spd_id %d", &spd_id))
11551         ;
11552       else if (unformat (i, "del"))
11553         is_add = 0;
11554       else
11555         {
11556           clib_warning ("parse error '%U'", format_unformat_error, i);
11557           return -99;
11558         }
11559     }
11560   if (spd_id == ~0)
11561     {
11562       errmsg ("spd_id must be set\n");
11563       return -99;
11564     }
11565
11566   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11567
11568   mp->spd_id = ntohl (spd_id);
11569   mp->is_add = is_add;
11570
11571   S;
11572   W;
11573   /* NOTREACHED */
11574   return 0;
11575 }
11576
11577 static int
11578 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11579 {
11580   unformat_input_t *i = vam->input;
11581   vl_api_ipsec_interface_add_del_spd_t *mp;
11582   f64 timeout;
11583   u32 sw_if_index;
11584   u8 sw_if_index_set = 0;
11585   u32 spd_id = (u32) ~ 0;
11586   u8 is_add = 1;
11587
11588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11589     {
11590       if (unformat (i, "del"))
11591         is_add = 0;
11592       else if (unformat (i, "spd_id %d", &spd_id))
11593         ;
11594       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11595         sw_if_index_set = 1;
11596       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11597         sw_if_index_set = 1;
11598       else
11599         {
11600           clib_warning ("parse error '%U'", format_unformat_error, i);
11601           return -99;
11602         }
11603
11604     }
11605
11606   if (spd_id == (u32) ~ 0)
11607     {
11608       errmsg ("spd_id must be set\n");
11609       return -99;
11610     }
11611
11612   if (sw_if_index_set == 0)
11613     {
11614       errmsg ("missing interface name or sw_if_index\n");
11615       return -99;
11616     }
11617
11618   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11619
11620   mp->spd_id = ntohl (spd_id);
11621   mp->sw_if_index = ntohl (sw_if_index);
11622   mp->is_add = is_add;
11623
11624   S;
11625   W;
11626   /* NOTREACHED */
11627   return 0;
11628 }
11629
11630 static int
11631 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11632 {
11633   unformat_input_t *i = vam->input;
11634   vl_api_ipsec_spd_add_del_entry_t *mp;
11635   f64 timeout;
11636   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11637   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11638   i32 priority = 0;
11639   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11640   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11641   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11642   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11643
11644   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11645   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11646   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11647   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11648   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11649   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11650
11651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11652     {
11653       if (unformat (i, "del"))
11654         is_add = 0;
11655       if (unformat (i, "outbound"))
11656         is_outbound = 1;
11657       if (unformat (i, "inbound"))
11658         is_outbound = 0;
11659       else if (unformat (i, "spd_id %d", &spd_id))
11660         ;
11661       else if (unformat (i, "sa_id %d", &sa_id))
11662         ;
11663       else if (unformat (i, "priority %d", &priority))
11664         ;
11665       else if (unformat (i, "protocol %d", &protocol))
11666         ;
11667       else if (unformat (i, "lport_start %d", &lport_start))
11668         ;
11669       else if (unformat (i, "lport_stop %d", &lport_stop))
11670         ;
11671       else if (unformat (i, "rport_start %d", &rport_start))
11672         ;
11673       else if (unformat (i, "rport_stop %d", &rport_stop))
11674         ;
11675       else
11676         if (unformat
11677             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11678         {
11679           is_ipv6 = 0;
11680           is_ip_any = 0;
11681         }
11682       else
11683         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11684         {
11685           is_ipv6 = 0;
11686           is_ip_any = 0;
11687         }
11688       else
11689         if (unformat
11690             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11691         {
11692           is_ipv6 = 0;
11693           is_ip_any = 0;
11694         }
11695       else
11696         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11697         {
11698           is_ipv6 = 0;
11699           is_ip_any = 0;
11700         }
11701       else
11702         if (unformat
11703             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11704         {
11705           is_ipv6 = 1;
11706           is_ip_any = 0;
11707         }
11708       else
11709         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11710         {
11711           is_ipv6 = 1;
11712           is_ip_any = 0;
11713         }
11714       else
11715         if (unformat
11716             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11717         {
11718           is_ipv6 = 1;
11719           is_ip_any = 0;
11720         }
11721       else
11722         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11723         {
11724           is_ipv6 = 1;
11725           is_ip_any = 0;
11726         }
11727       else
11728         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11729         {
11730           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11731             {
11732               clib_warning ("unsupported action: 'resolve'");
11733               return -99;
11734             }
11735         }
11736       else
11737         {
11738           clib_warning ("parse error '%U'", format_unformat_error, i);
11739           return -99;
11740         }
11741
11742     }
11743
11744   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11745
11746   mp->spd_id = ntohl (spd_id);
11747   mp->priority = ntohl (priority);
11748   mp->is_outbound = is_outbound;
11749
11750   mp->is_ipv6 = is_ipv6;
11751   if (is_ipv6 || is_ip_any)
11752     {
11753       clib_memcpy (mp->remote_address_start, &raddr6_start,
11754                    sizeof (ip6_address_t));
11755       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11756                    sizeof (ip6_address_t));
11757       clib_memcpy (mp->local_address_start, &laddr6_start,
11758                    sizeof (ip6_address_t));
11759       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11760                    sizeof (ip6_address_t));
11761     }
11762   else
11763     {
11764       clib_memcpy (mp->remote_address_start, &raddr4_start,
11765                    sizeof (ip4_address_t));
11766       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11767                    sizeof (ip4_address_t));
11768       clib_memcpy (mp->local_address_start, &laddr4_start,
11769                    sizeof (ip4_address_t));
11770       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11771                    sizeof (ip4_address_t));
11772     }
11773   mp->protocol = (u8) protocol;
11774   mp->local_port_start = ntohs ((u16) lport_start);
11775   mp->local_port_stop = ntohs ((u16) lport_stop);
11776   mp->remote_port_start = ntohs ((u16) rport_start);
11777   mp->remote_port_stop = ntohs ((u16) rport_stop);
11778   mp->policy = (u8) policy;
11779   mp->sa_id = ntohl (sa_id);
11780   mp->is_add = is_add;
11781   mp->is_ip_any = is_ip_any;
11782   S;
11783   W;
11784   /* NOTREACHED */
11785   return 0;
11786 }
11787
11788 static int
11789 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11790 {
11791   unformat_input_t *i = vam->input;
11792   vl_api_ipsec_sad_add_del_entry_t *mp;
11793   f64 timeout;
11794   u32 sad_id = 0, spi = 0;
11795   u8 *ck = 0, *ik = 0;
11796   u8 is_add = 1;
11797
11798   u8 protocol = IPSEC_PROTOCOL_AH;
11799   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11800   u32 crypto_alg = 0, integ_alg = 0;
11801   ip4_address_t tun_src4;
11802   ip4_address_t tun_dst4;
11803   ip6_address_t tun_src6;
11804   ip6_address_t tun_dst6;
11805
11806   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11807     {
11808       if (unformat (i, "del"))
11809         is_add = 0;
11810       else if (unformat (i, "sad_id %d", &sad_id))
11811         ;
11812       else if (unformat (i, "spi %d", &spi))
11813         ;
11814       else if (unformat (i, "esp"))
11815         protocol = IPSEC_PROTOCOL_ESP;
11816       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11817         {
11818           is_tunnel = 1;
11819           is_tunnel_ipv6 = 0;
11820         }
11821       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11822         {
11823           is_tunnel = 1;
11824           is_tunnel_ipv6 = 0;
11825         }
11826       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11827         {
11828           is_tunnel = 1;
11829           is_tunnel_ipv6 = 1;
11830         }
11831       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11832         {
11833           is_tunnel = 1;
11834           is_tunnel_ipv6 = 1;
11835         }
11836       else
11837         if (unformat
11838             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11839         {
11840           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11841               crypto_alg >= IPSEC_CRYPTO_N_ALG)
11842             {
11843               clib_warning ("unsupported crypto-alg: '%U'",
11844                             format_ipsec_crypto_alg, crypto_alg);
11845               return -99;
11846             }
11847         }
11848       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11849         ;
11850       else
11851         if (unformat
11852             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11853         {
11854 #if DPDK_CRYPTO==1
11855           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
11856 #else
11857           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11858 #endif
11859               integ_alg >= IPSEC_INTEG_N_ALG)
11860             {
11861               clib_warning ("unsupported integ-alg: '%U'",
11862                             format_ipsec_integ_alg, integ_alg);
11863               return -99;
11864             }
11865         }
11866       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11867         ;
11868       else
11869         {
11870           clib_warning ("parse error '%U'", format_unformat_error, i);
11871           return -99;
11872         }
11873
11874     }
11875
11876 #if DPDK_CRYPTO==1
11877   /*Special cases, aes-gcm-128 encryption */
11878   if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
11879     {
11880       if (integ_alg != IPSEC_INTEG_ALG_NONE
11881           && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
11882         {
11883           clib_warning
11884             ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
11885           return -99;
11886         }
11887       else                      /*set integ-alg internally to aes-gcm-128 */
11888         integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
11889     }
11890   else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
11891     {
11892       clib_warning ("unsupported integ-alg: aes-gcm-128");
11893       return -99;
11894     }
11895   else if (integ_alg == IPSEC_INTEG_ALG_NONE)
11896     {
11897       clib_warning ("unsupported integ-alg: none");
11898       return -99;
11899     }
11900 #endif
11901
11902
11903   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11904
11905   mp->sad_id = ntohl (sad_id);
11906   mp->is_add = is_add;
11907   mp->protocol = protocol;
11908   mp->spi = ntohl (spi);
11909   mp->is_tunnel = is_tunnel;
11910   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11911   mp->crypto_algorithm = crypto_alg;
11912   mp->integrity_algorithm = integ_alg;
11913   mp->crypto_key_length = vec_len (ck);
11914   mp->integrity_key_length = vec_len (ik);
11915
11916   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11917     mp->crypto_key_length = sizeof (mp->crypto_key);
11918
11919   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11920     mp->integrity_key_length = sizeof (mp->integrity_key);
11921
11922   if (ck)
11923     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11924   if (ik)
11925     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11926
11927   if (is_tunnel)
11928     {
11929       if (is_tunnel_ipv6)
11930         {
11931           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11932                        sizeof (ip6_address_t));
11933           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11934                        sizeof (ip6_address_t));
11935         }
11936       else
11937         {
11938           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11939                        sizeof (ip4_address_t));
11940           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11941                        sizeof (ip4_address_t));
11942         }
11943     }
11944
11945   S;
11946   W;
11947   /* NOTREACHED */
11948   return 0;
11949 }
11950
11951 static int
11952 api_ipsec_sa_set_key (vat_main_t * vam)
11953 {
11954   unformat_input_t *i = vam->input;
11955   vl_api_ipsec_sa_set_key_t *mp;
11956   f64 timeout;
11957   u32 sa_id;
11958   u8 *ck = 0, *ik = 0;
11959
11960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11961     {
11962       if (unformat (i, "sa_id %d", &sa_id))
11963         ;
11964       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11965         ;
11966       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11967         ;
11968       else
11969         {
11970           clib_warning ("parse error '%U'", format_unformat_error, i);
11971           return -99;
11972         }
11973     }
11974
11975   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11976
11977   mp->sa_id = ntohl (sa_id);
11978   mp->crypto_key_length = vec_len (ck);
11979   mp->integrity_key_length = vec_len (ik);
11980
11981   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11982     mp->crypto_key_length = sizeof (mp->crypto_key);
11983
11984   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11985     mp->integrity_key_length = sizeof (mp->integrity_key);
11986
11987   if (ck)
11988     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11989   if (ik)
11990     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11991
11992   S;
11993   W;
11994   /* NOTREACHED */
11995   return 0;
11996 }
11997
11998 static int
11999 api_ikev2_profile_add_del (vat_main_t * vam)
12000 {
12001   unformat_input_t *i = vam->input;
12002   vl_api_ikev2_profile_add_del_t *mp;
12003   f64 timeout;
12004   u8 is_add = 1;
12005   u8 *name = 0;
12006
12007   const char *valid_chars = "a-zA-Z0-9_";
12008
12009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12010     {
12011       if (unformat (i, "del"))
12012         is_add = 0;
12013       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12014         vec_add1 (name, 0);
12015       else
12016         {
12017           errmsg ("parse error '%U'", format_unformat_error, i);
12018           return -99;
12019         }
12020     }
12021
12022   if (!vec_len (name))
12023     {
12024       errmsg ("profile name must be specified");
12025       return -99;
12026     }
12027
12028   if (vec_len (name) > 64)
12029     {
12030       errmsg ("profile name too long");
12031       return -99;
12032     }
12033
12034   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
12035
12036   clib_memcpy (mp->name, name, vec_len (name));
12037   mp->is_add = is_add;
12038   vec_free (name);
12039
12040   S;
12041   W;
12042   /* NOTREACHED */
12043   return 0;
12044 }
12045
12046 static int
12047 api_ikev2_profile_set_auth (vat_main_t * vam)
12048 {
12049   unformat_input_t *i = vam->input;
12050   vl_api_ikev2_profile_set_auth_t *mp;
12051   f64 timeout;
12052   u8 *name = 0;
12053   u8 *data = 0;
12054   u32 auth_method = 0;
12055   u8 is_hex = 0;
12056
12057   const char *valid_chars = "a-zA-Z0-9_";
12058
12059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12060     {
12061       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12062         vec_add1 (name, 0);
12063       else if (unformat (i, "auth_method %U",
12064                          unformat_ikev2_auth_method, &auth_method))
12065         ;
12066       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12067         is_hex = 1;
12068       else if (unformat (i, "auth_data %v", &data))
12069         ;
12070       else
12071         {
12072           errmsg ("parse error '%U'", format_unformat_error, i);
12073           return -99;
12074         }
12075     }
12076
12077   if (!vec_len (name))
12078     {
12079       errmsg ("profile name must be specified");
12080       return -99;
12081     }
12082
12083   if (vec_len (name) > 64)
12084     {
12085       errmsg ("profile name too long");
12086       return -99;
12087     }
12088
12089   if (!vec_len (data))
12090     {
12091       errmsg ("auth_data must be specified");
12092       return -99;
12093     }
12094
12095   if (!auth_method)
12096     {
12097       errmsg ("auth_method must be specified");
12098       return -99;
12099     }
12100
12101   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12102
12103   mp->is_hex = is_hex;
12104   mp->auth_method = (u8) auth_method;
12105   mp->data_len = vec_len (data);
12106   clib_memcpy (mp->name, name, vec_len (name));
12107   clib_memcpy (mp->data, data, vec_len (data));
12108   vec_free (name);
12109   vec_free (data);
12110
12111   S;
12112   W;
12113   /* NOTREACHED */
12114   return 0;
12115 }
12116
12117 static int
12118 api_ikev2_profile_set_id (vat_main_t * vam)
12119 {
12120   unformat_input_t *i = vam->input;
12121   vl_api_ikev2_profile_set_id_t *mp;
12122   f64 timeout;
12123   u8 *name = 0;
12124   u8 *data = 0;
12125   u8 is_local = 0;
12126   u32 id_type = 0;
12127   ip4_address_t ip4;
12128
12129   const char *valid_chars = "a-zA-Z0-9_";
12130
12131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12132     {
12133       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12134         vec_add1 (name, 0);
12135       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12136         ;
12137       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12138         {
12139           data = vec_new (u8, 4);
12140           clib_memcpy (data, ip4.as_u8, 4);
12141         }
12142       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12143         ;
12144       else if (unformat (i, "id_data %v", &data))
12145         ;
12146       else if (unformat (i, "local"))
12147         is_local = 1;
12148       else if (unformat (i, "remote"))
12149         is_local = 0;
12150       else
12151         {
12152           errmsg ("parse error '%U'", format_unformat_error, i);
12153           return -99;
12154         }
12155     }
12156
12157   if (!vec_len (name))
12158     {
12159       errmsg ("profile name must be specified");
12160       return -99;
12161     }
12162
12163   if (vec_len (name) > 64)
12164     {
12165       errmsg ("profile name too long");
12166       return -99;
12167     }
12168
12169   if (!vec_len (data))
12170     {
12171       errmsg ("id_data must be specified");
12172       return -99;
12173     }
12174
12175   if (!id_type)
12176     {
12177       errmsg ("id_type must be specified");
12178       return -99;
12179     }
12180
12181   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12182
12183   mp->is_local = is_local;
12184   mp->id_type = (u8) id_type;
12185   mp->data_len = vec_len (data);
12186   clib_memcpy (mp->name, name, vec_len (name));
12187   clib_memcpy (mp->data, data, vec_len (data));
12188   vec_free (name);
12189   vec_free (data);
12190
12191   S;
12192   W;
12193   /* NOTREACHED */
12194   return 0;
12195 }
12196
12197 static int
12198 api_ikev2_profile_set_ts (vat_main_t * vam)
12199 {
12200   unformat_input_t *i = vam->input;
12201   vl_api_ikev2_profile_set_ts_t *mp;
12202   f64 timeout;
12203   u8 *name = 0;
12204   u8 is_local = 0;
12205   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12206   ip4_address_t start_addr, end_addr;
12207
12208   const char *valid_chars = "a-zA-Z0-9_";
12209
12210   start_addr.as_u32 = 0;
12211   end_addr.as_u32 = (u32) ~ 0;
12212
12213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12214     {
12215       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12216         vec_add1 (name, 0);
12217       else if (unformat (i, "protocol %d", &proto))
12218         ;
12219       else if (unformat (i, "start_port %d", &start_port))
12220         ;
12221       else if (unformat (i, "end_port %d", &end_port))
12222         ;
12223       else
12224         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12225         ;
12226       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12227         ;
12228       else if (unformat (i, "local"))
12229         is_local = 1;
12230       else if (unformat (i, "remote"))
12231         is_local = 0;
12232       else
12233         {
12234           errmsg ("parse error '%U'", format_unformat_error, i);
12235           return -99;
12236         }
12237     }
12238
12239   if (!vec_len (name))
12240     {
12241       errmsg ("profile name must be specified");
12242       return -99;
12243     }
12244
12245   if (vec_len (name) > 64)
12246     {
12247       errmsg ("profile name too long");
12248       return -99;
12249     }
12250
12251   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12252
12253   mp->is_local = is_local;
12254   mp->proto = (u8) proto;
12255   mp->start_port = (u16) start_port;
12256   mp->end_port = (u16) end_port;
12257   mp->start_addr = start_addr.as_u32;
12258   mp->end_addr = end_addr.as_u32;
12259   clib_memcpy (mp->name, name, vec_len (name));
12260   vec_free (name);
12261
12262   S;
12263   W;
12264   /* NOTREACHED */
12265   return 0;
12266 }
12267
12268 static int
12269 api_ikev2_set_local_key (vat_main_t * vam)
12270 {
12271   unformat_input_t *i = vam->input;
12272   vl_api_ikev2_set_local_key_t *mp;
12273   f64 timeout;
12274   u8 *file = 0;
12275
12276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12277     {
12278       if (unformat (i, "file %v", &file))
12279         vec_add1 (file, 0);
12280       else
12281         {
12282           errmsg ("parse error '%U'", format_unformat_error, i);
12283           return -99;
12284         }
12285     }
12286
12287   if (!vec_len (file))
12288     {
12289       errmsg ("RSA key file must be specified");
12290       return -99;
12291     }
12292
12293   if (vec_len (file) > 256)
12294     {
12295       errmsg ("file name too long");
12296       return -99;
12297     }
12298
12299   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12300
12301   clib_memcpy (mp->key_file, file, vec_len (file));
12302   vec_free (file);
12303
12304   S;
12305   W;
12306   /* NOTREACHED */
12307   return 0;
12308 }
12309
12310 /*
12311  * MAP
12312  */
12313 static int
12314 api_map_add_domain (vat_main_t * vam)
12315 {
12316   unformat_input_t *i = vam->input;
12317   vl_api_map_add_domain_t *mp;
12318   f64 timeout;
12319
12320   ip4_address_t ip4_prefix;
12321   ip6_address_t ip6_prefix;
12322   ip6_address_t ip6_src;
12323   u32 num_m_args = 0;
12324   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12325     0, psid_length = 0;
12326   u8 is_translation = 0;
12327   u32 mtu = 0;
12328   u32 ip6_src_len = 128;
12329
12330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12331     {
12332       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12333                     &ip4_prefix, &ip4_prefix_len))
12334         num_m_args++;
12335       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12336                          &ip6_prefix, &ip6_prefix_len))
12337         num_m_args++;
12338       else
12339         if (unformat
12340             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12341              &ip6_src_len))
12342         num_m_args++;
12343       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12344         num_m_args++;
12345       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12346         num_m_args++;
12347       else if (unformat (i, "psid-offset %d", &psid_offset))
12348         num_m_args++;
12349       else if (unformat (i, "psid-len %d", &psid_length))
12350         num_m_args++;
12351       else if (unformat (i, "mtu %d", &mtu))
12352         num_m_args++;
12353       else if (unformat (i, "map-t"))
12354         is_translation = 1;
12355       else
12356         {
12357           clib_warning ("parse error '%U'", format_unformat_error, i);
12358           return -99;
12359         }
12360     }
12361
12362   if (num_m_args < 3)
12363     {
12364       errmsg ("mandatory argument(s) missing\n");
12365       return -99;
12366     }
12367
12368   /* Construct the API message */
12369   M (MAP_ADD_DOMAIN, map_add_domain);
12370
12371   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12372   mp->ip4_prefix_len = ip4_prefix_len;
12373
12374   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12375   mp->ip6_prefix_len = ip6_prefix_len;
12376
12377   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12378   mp->ip6_src_prefix_len = ip6_src_len;
12379
12380   mp->ea_bits_len = ea_bits_len;
12381   mp->psid_offset = psid_offset;
12382   mp->psid_length = psid_length;
12383   mp->is_translation = is_translation;
12384   mp->mtu = htons (mtu);
12385
12386   /* send it... */
12387   S;
12388
12389   /* Wait for a reply, return good/bad news  */
12390   W;
12391 }
12392
12393 static int
12394 api_map_del_domain (vat_main_t * vam)
12395 {
12396   unformat_input_t *i = vam->input;
12397   vl_api_map_del_domain_t *mp;
12398   f64 timeout;
12399
12400   u32 num_m_args = 0;
12401   u32 index;
12402
12403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12404     {
12405       if (unformat (i, "index %d", &index))
12406         num_m_args++;
12407       else
12408         {
12409           clib_warning ("parse error '%U'", format_unformat_error, i);
12410           return -99;
12411         }
12412     }
12413
12414   if (num_m_args != 1)
12415     {
12416       errmsg ("mandatory argument(s) missing\n");
12417       return -99;
12418     }
12419
12420   /* Construct the API message */
12421   M (MAP_DEL_DOMAIN, map_del_domain);
12422
12423   mp->index = ntohl (index);
12424
12425   /* send it... */
12426   S;
12427
12428   /* Wait for a reply, return good/bad news  */
12429   W;
12430 }
12431
12432 static int
12433 api_map_add_del_rule (vat_main_t * vam)
12434 {
12435   unformat_input_t *i = vam->input;
12436   vl_api_map_add_del_rule_t *mp;
12437   f64 timeout;
12438   u8 is_add = 1;
12439   ip6_address_t ip6_dst;
12440   u32 num_m_args = 0, index, psid = 0;
12441
12442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12443     {
12444       if (unformat (i, "index %d", &index))
12445         num_m_args++;
12446       else if (unformat (i, "psid %d", &psid))
12447         num_m_args++;
12448       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12449         num_m_args++;
12450       else if (unformat (i, "del"))
12451         {
12452           is_add = 0;
12453         }
12454       else
12455         {
12456           clib_warning ("parse error '%U'", format_unformat_error, i);
12457           return -99;
12458         }
12459     }
12460
12461   /* Construct the API message */
12462   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12463
12464   mp->index = ntohl (index);
12465   mp->is_add = is_add;
12466   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12467   mp->psid = ntohs (psid);
12468
12469   /* send it... */
12470   S;
12471
12472   /* Wait for a reply, return good/bad news  */
12473   W;
12474 }
12475
12476 static int
12477 api_map_domain_dump (vat_main_t * vam)
12478 {
12479   vl_api_map_domain_dump_t *mp;
12480   f64 timeout;
12481
12482   /* Construct the API message */
12483   M (MAP_DOMAIN_DUMP, map_domain_dump);
12484
12485   /* send it... */
12486   S;
12487
12488   /* Use a control ping for synchronization */
12489   {
12490     vl_api_control_ping_t *mp;
12491     M (CONTROL_PING, control_ping);
12492     S;
12493   }
12494   W;
12495 }
12496
12497 static int
12498 api_map_rule_dump (vat_main_t * vam)
12499 {
12500   unformat_input_t *i = vam->input;
12501   vl_api_map_rule_dump_t *mp;
12502   f64 timeout;
12503   u32 domain_index = ~0;
12504
12505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12506     {
12507       if (unformat (i, "index %u", &domain_index))
12508         ;
12509       else
12510         break;
12511     }
12512
12513   if (domain_index == ~0)
12514     {
12515       clib_warning ("parse error: domain index expected");
12516       return -99;
12517     }
12518
12519   /* Construct the API message */
12520   M (MAP_RULE_DUMP, map_rule_dump);
12521
12522   mp->domain_index = htonl (domain_index);
12523
12524   /* send it... */
12525   S;
12526
12527   /* Use a control ping for synchronization */
12528   {
12529     vl_api_control_ping_t *mp;
12530     M (CONTROL_PING, control_ping);
12531     S;
12532   }
12533   W;
12534 }
12535
12536 static void vl_api_map_add_domain_reply_t_handler
12537   (vl_api_map_add_domain_reply_t * mp)
12538 {
12539   vat_main_t *vam = &vat_main;
12540   i32 retval = ntohl (mp->retval);
12541
12542   if (vam->async_mode)
12543     {
12544       vam->async_errors += (retval < 0);
12545     }
12546   else
12547     {
12548       vam->retval = retval;
12549       vam->result_ready = 1;
12550     }
12551 }
12552
12553 static void vl_api_map_add_domain_reply_t_handler_json
12554   (vl_api_map_add_domain_reply_t * mp)
12555 {
12556   vat_main_t *vam = &vat_main;
12557   vat_json_node_t node;
12558
12559   vat_json_init_object (&node);
12560   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12561   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12562
12563   vat_json_print (vam->ofp, &node);
12564   vat_json_free (&node);
12565
12566   vam->retval = ntohl (mp->retval);
12567   vam->result_ready = 1;
12568 }
12569
12570 static int
12571 api_get_first_msg_id (vat_main_t * vam)
12572 {
12573   vl_api_get_first_msg_id_t *mp;
12574   f64 timeout;
12575   unformat_input_t *i = vam->input;
12576   u8 *name;
12577   u8 name_set = 0;
12578
12579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12580     {
12581       if (unformat (i, "client %s", &name))
12582         name_set = 1;
12583       else
12584         break;
12585     }
12586
12587   if (name_set == 0)
12588     {
12589       errmsg ("missing client name\n");
12590       return -99;
12591     }
12592   vec_add1 (name, 0);
12593
12594   if (vec_len (name) > 63)
12595     {
12596       errmsg ("client name too long\n");
12597       return -99;
12598     }
12599
12600   M (GET_FIRST_MSG_ID, get_first_msg_id);
12601   clib_memcpy (mp->name, name, vec_len (name));
12602   S;
12603   W;
12604   /* NOTREACHED */
12605   return 0;
12606 }
12607
12608 static int
12609 api_cop_interface_enable_disable (vat_main_t * vam)
12610 {
12611   unformat_input_t *line_input = vam->input;
12612   vl_api_cop_interface_enable_disable_t *mp;
12613   f64 timeout;
12614   u32 sw_if_index = ~0;
12615   u8 enable_disable = 1;
12616
12617   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12618     {
12619       if (unformat (line_input, "disable"))
12620         enable_disable = 0;
12621       if (unformat (line_input, "enable"))
12622         enable_disable = 1;
12623       else if (unformat (line_input, "%U", unformat_sw_if_index,
12624                          vam, &sw_if_index))
12625         ;
12626       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12627         ;
12628       else
12629         break;
12630     }
12631
12632   if (sw_if_index == ~0)
12633     {
12634       errmsg ("missing interface name or sw_if_index\n");
12635       return -99;
12636     }
12637
12638   /* Construct the API message */
12639   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12640   mp->sw_if_index = ntohl (sw_if_index);
12641   mp->enable_disable = enable_disable;
12642
12643   /* send it... */
12644   S;
12645   /* Wait for the reply */
12646   W;
12647 }
12648
12649 static int
12650 api_cop_whitelist_enable_disable (vat_main_t * vam)
12651 {
12652   unformat_input_t *line_input = vam->input;
12653   vl_api_cop_whitelist_enable_disable_t *mp;
12654   f64 timeout;
12655   u32 sw_if_index = ~0;
12656   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12657   u32 fib_id = 0;
12658
12659   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12660     {
12661       if (unformat (line_input, "ip4"))
12662         ip4 = 1;
12663       else if (unformat (line_input, "ip6"))
12664         ip6 = 1;
12665       else if (unformat (line_input, "default"))
12666         default_cop = 1;
12667       else if (unformat (line_input, "%U", unformat_sw_if_index,
12668                          vam, &sw_if_index))
12669         ;
12670       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12671         ;
12672       else if (unformat (line_input, "fib-id %d", &fib_id))
12673         ;
12674       else
12675         break;
12676     }
12677
12678   if (sw_if_index == ~0)
12679     {
12680       errmsg ("missing interface name or sw_if_index\n");
12681       return -99;
12682     }
12683
12684   /* Construct the API message */
12685   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12686   mp->sw_if_index = ntohl (sw_if_index);
12687   mp->fib_id = ntohl (fib_id);
12688   mp->ip4 = ip4;
12689   mp->ip6 = ip6;
12690   mp->default_cop = default_cop;
12691
12692   /* send it... */
12693   S;
12694   /* Wait for the reply */
12695   W;
12696 }
12697
12698 static int
12699 api_get_node_graph (vat_main_t * vam)
12700 {
12701   vl_api_get_node_graph_t *mp;
12702   f64 timeout;
12703
12704   M (GET_NODE_GRAPH, get_node_graph);
12705
12706   /* send it... */
12707   S;
12708   /* Wait for the reply */
12709   W;
12710 }
12711
12712 /* *INDENT-OFF* */
12713 /** Used for parsing LISP eids */
12714 typedef CLIB_PACKED(struct{
12715   u8 addr[16];   /**< eid address */
12716   u32 len;       /**< prefix length if IP */
12717   u8 type;      /**< type of eid */
12718 }) lisp_eid_vat_t;
12719 /* *INDENT-ON* */
12720
12721 static uword
12722 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12723 {
12724   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12725
12726   memset (a, 0, sizeof (a[0]));
12727
12728   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12729     {
12730       a->type = 0;              /* ipv4 type */
12731     }
12732   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12733     {
12734       a->type = 1;              /* ipv6 type */
12735     }
12736   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12737     {
12738       a->type = 2;              /* mac type */
12739     }
12740   else
12741     {
12742       return 0;
12743     }
12744
12745   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12746     {
12747       return 0;
12748     }
12749
12750   return 1;
12751 }
12752
12753 static int
12754 lisp_eid_size_vat (u8 type)
12755 {
12756   switch (type)
12757     {
12758     case 0:
12759       return 4;
12760     case 1:
12761       return 16;
12762     case 2:
12763       return 6;
12764     }
12765   return 0;
12766 }
12767
12768 static void
12769 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12770 {
12771   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12772 }
12773
12774 /* *INDENT-OFF* */
12775 /** Used for transferring locators via VPP API */
12776 typedef CLIB_PACKED(struct
12777 {
12778   u32 sw_if_index; /**< locator sw_if_index */
12779   u8 priority; /**< locator priority */
12780   u8 weight;   /**< locator weight */
12781 }) ls_locator_t;
12782 /* *INDENT-ON* */
12783
12784 static int
12785 api_lisp_add_del_locator_set (vat_main_t * vam)
12786 {
12787   unformat_input_t *input = vam->input;
12788   vl_api_lisp_add_del_locator_set_t *mp;
12789   f64 timeout = ~0;
12790   u8 is_add = 1;
12791   u8 *locator_set_name = NULL;
12792   u8 locator_set_name_set = 0;
12793   ls_locator_t locator, *locators = 0;
12794   u32 sw_if_index, priority, weight;
12795   u32 data_len = 0;
12796
12797   /* Parse args required to build the message */
12798   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12799     {
12800       if (unformat (input, "del"))
12801         {
12802           is_add = 0;
12803         }
12804       else if (unformat (input, "locator-set %s", &locator_set_name))
12805         {
12806           locator_set_name_set = 1;
12807         }
12808       else if (unformat (input, "sw_if_index %u p %u w %u",
12809                          &sw_if_index, &priority, &weight))
12810         {
12811           locator.sw_if_index = htonl (sw_if_index);
12812           locator.priority = priority;
12813           locator.weight = weight;
12814           vec_add1 (locators, locator);
12815         }
12816       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12817                          vam, &sw_if_index, &priority, &weight))
12818         {
12819           locator.sw_if_index = htonl (sw_if_index);
12820           locator.priority = priority;
12821           locator.weight = weight;
12822           vec_add1 (locators, locator);
12823         }
12824       else
12825         break;
12826     }
12827
12828   if (locator_set_name_set == 0)
12829     {
12830       errmsg ("missing locator-set name");
12831       vec_free (locators);
12832       return -99;
12833     }
12834
12835   if (vec_len (locator_set_name) > 64)
12836     {
12837       errmsg ("locator-set name too long\n");
12838       vec_free (locator_set_name);
12839       vec_free (locators);
12840       return -99;
12841     }
12842   vec_add1 (locator_set_name, 0);
12843
12844   data_len = sizeof (ls_locator_t) * vec_len (locators);
12845
12846   /* Construct the API message */
12847   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12848
12849   mp->is_add = is_add;
12850   clib_memcpy (mp->locator_set_name, locator_set_name,
12851                vec_len (locator_set_name));
12852   vec_free (locator_set_name);
12853
12854   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12855   if (locators)
12856     clib_memcpy (mp->locators, locators, data_len);
12857   vec_free (locators);
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_locator (vat_main_t * vam)
12871 {
12872   unformat_input_t *input = vam->input;
12873   vl_api_lisp_add_del_locator_t *mp;
12874   f64 timeout = ~0;
12875   u32 tmp_if_index = ~0;
12876   u32 sw_if_index = ~0;
12877   u8 sw_if_index_set = 0;
12878   u8 sw_if_index_if_name_set = 0;
12879   u32 priority = ~0;
12880   u8 priority_set = 0;
12881   u32 weight = ~0;
12882   u8 weight_set = 0;
12883   u8 is_add = 1;
12884   u8 *locator_set_name = NULL;
12885   u8 locator_set_name_set = 0;
12886
12887   /* Parse args required to build the message */
12888   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12889     {
12890       if (unformat (input, "del"))
12891         {
12892           is_add = 0;
12893         }
12894       else if (unformat (input, "locator-set %s", &locator_set_name))
12895         {
12896           locator_set_name_set = 1;
12897         }
12898       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12899                          &tmp_if_index))
12900         {
12901           sw_if_index_if_name_set = 1;
12902           sw_if_index = tmp_if_index;
12903         }
12904       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12905         {
12906           sw_if_index_set = 1;
12907           sw_if_index = tmp_if_index;
12908         }
12909       else if (unformat (input, "p %d", &priority))
12910         {
12911           priority_set = 1;
12912         }
12913       else if (unformat (input, "w %d", &weight))
12914         {
12915           weight_set = 1;
12916         }
12917       else
12918         break;
12919     }
12920
12921   if (locator_set_name_set == 0)
12922     {
12923       errmsg ("missing locator-set name");
12924       return -99;
12925     }
12926
12927   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12928     {
12929       errmsg ("missing sw_if_index");
12930       vec_free (locator_set_name);
12931       return -99;
12932     }
12933
12934   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12935     {
12936       errmsg ("cannot use both params interface name and sw_if_index");
12937       vec_free (locator_set_name);
12938       return -99;
12939     }
12940
12941   if (priority_set == 0)
12942     {
12943       errmsg ("missing locator-set priority\n");
12944       vec_free (locator_set_name);
12945       return -99;
12946     }
12947
12948   if (weight_set == 0)
12949     {
12950       errmsg ("missing locator-set weight\n");
12951       vec_free (locator_set_name);
12952       return -99;
12953     }
12954
12955   if (vec_len (locator_set_name) > 64)
12956     {
12957       errmsg ("locator-set name too long\n");
12958       vec_free (locator_set_name);
12959       return -99;
12960     }
12961   vec_add1 (locator_set_name, 0);
12962
12963   /* Construct the API message */
12964   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12965
12966   mp->is_add = is_add;
12967   mp->sw_if_index = ntohl (sw_if_index);
12968   mp->priority = priority;
12969   mp->weight = weight;
12970   clib_memcpy (mp->locator_set_name, locator_set_name,
12971                vec_len (locator_set_name));
12972   vec_free (locator_set_name);
12973
12974   /* send it... */
12975   S;
12976
12977   /* Wait for a reply... */
12978   W;
12979
12980   /* NOTREACHED */
12981   return 0;
12982 }
12983
12984 uword
12985 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
12986 {
12987   u32 *key_id = va_arg (*args, u32 *);
12988   u8 *s = 0;
12989
12990   if (unformat (input, "%s", &s))
12991     {
12992       if (!strcmp ((char *) s, "sha1"))
12993         key_id[0] = HMAC_SHA_1_96;
12994       else if (!strcmp ((char *) s, "sha256"))
12995         key_id[0] = HMAC_SHA_256_128;
12996       else
12997         {
12998           clib_warning ("invalid key_id: '%s'", s);
12999           key_id[0] = HMAC_NO_KEY;
13000         }
13001     }
13002   else
13003     return 0;
13004
13005   vec_free (s);
13006   return 1;
13007 }
13008
13009 static int
13010 api_lisp_add_del_local_eid (vat_main_t * vam)
13011 {
13012   unformat_input_t *input = vam->input;
13013   vl_api_lisp_add_del_local_eid_t *mp;
13014   f64 timeout = ~0;
13015   u8 is_add = 1;
13016   u8 eid_set = 0;
13017   lisp_eid_vat_t _eid, *eid = &_eid;
13018   u8 *locator_set_name = 0;
13019   u8 locator_set_name_set = 0;
13020   u32 vni = 0;
13021   u16 key_id = 0;
13022   u8 *key = 0;
13023
13024   /* Parse args required to build the message */
13025   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13026     {
13027       if (unformat (input, "del"))
13028         {
13029           is_add = 0;
13030         }
13031       else if (unformat (input, "vni %d", &vni))
13032         {
13033           ;
13034         }
13035       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13036         {
13037           eid_set = 1;
13038         }
13039       else if (unformat (input, "locator-set %s", &locator_set_name))
13040         {
13041           locator_set_name_set = 1;
13042         }
13043       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13044         ;
13045       else if (unformat (input, "secret-key %_%v%_", &key))
13046         ;
13047       else
13048         break;
13049     }
13050
13051   if (locator_set_name_set == 0)
13052     {
13053       errmsg ("missing locator-set name\n");
13054       return -99;
13055     }
13056
13057   if (0 == eid_set)
13058     {
13059       errmsg ("EID address not set!");
13060       vec_free (locator_set_name);
13061       return -99;
13062     }
13063
13064   if (key && (0 == key_id))
13065     {
13066       errmsg ("invalid key_id!");
13067       return -99;
13068     }
13069
13070   if (vec_len (key) > 64)
13071     {
13072       errmsg ("key too long");
13073       vec_free (key);
13074       return -99;
13075     }
13076
13077   if (vec_len (locator_set_name) > 64)
13078     {
13079       errmsg ("locator-set name too long\n");
13080       vec_free (locator_set_name);
13081       return -99;
13082     }
13083   vec_add1 (locator_set_name, 0);
13084
13085   /* Construct the API message */
13086   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
13087
13088   mp->is_add = is_add;
13089   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13090   mp->eid_type = eid->type;
13091   mp->prefix_len = eid->len;
13092   mp->vni = clib_host_to_net_u32 (vni);
13093   mp->key_id = clib_host_to_net_u16 (key_id);
13094   clib_memcpy (mp->locator_set_name, locator_set_name,
13095                vec_len (locator_set_name));
13096   clib_memcpy (mp->key, key, vec_len (key));
13097
13098   vec_free (locator_set_name);
13099   vec_free (key);
13100
13101   /* send it... */
13102   S;
13103
13104   /* Wait for a reply... */
13105   W;
13106
13107   /* NOTREACHED */
13108   return 0;
13109 }
13110
13111 /* *INDENT-OFF* */
13112 /** Used for transferring locators via VPP API */
13113 typedef CLIB_PACKED(struct
13114 {
13115   u8 is_ip4; /**< is locator an IPv4 address? */
13116   u8 priority; /**< locator priority */
13117   u8 weight;   /**< locator weight */
13118   u8 addr[16]; /**< IPv4/IPv6 address */
13119 }) rloc_t;
13120 /* *INDENT-ON* */
13121
13122 static int
13123 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13124 {
13125   unformat_input_t *input = vam->input;
13126   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13127   f64 timeout = ~0;
13128   u8 is_add = 1;
13129   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13130   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13131   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13132   u32 action = ~0, p, w;
13133   ip4_address_t rmt_rloc4, lcl_rloc4;
13134   ip6_address_t rmt_rloc6, lcl_rloc6;
13135   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13136
13137   memset (&rloc, 0, sizeof (rloc));
13138
13139   /* Parse args required to build the message */
13140   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13141     {
13142       if (unformat (input, "del"))
13143         {
13144           is_add = 0;
13145         }
13146       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
13147         {
13148           rmt_eid_set = 1;
13149         }
13150       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
13151         {
13152           lcl_eid_set = 1;
13153         }
13154       else if (unformat (input, "p %d w %d", &p, &w))
13155         {
13156           if (!curr_rloc)
13157             {
13158               errmsg ("No RLOC configured for setting priority/weight!");
13159               return -99;
13160             }
13161           curr_rloc->priority = p;
13162           curr_rloc->weight = w;
13163         }
13164       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13165                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13166         {
13167           rloc.is_ip4 = 1;
13168
13169           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13170           rloc.priority = rloc.weight = 0;
13171           vec_add1 (lcl_locs, rloc);
13172
13173           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13174           vec_add1 (rmt_locs, rloc);
13175           /* priority and weight saved in rmt loc */
13176           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13177         }
13178       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13179                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13180         {
13181           rloc.is_ip4 = 0;
13182           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13183           rloc.priority = rloc.weight = 0;
13184           vec_add1 (lcl_locs, rloc);
13185
13186           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13187           vec_add1 (rmt_locs, rloc);
13188           /* priority and weight saved in rmt loc */
13189           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13190         }
13191       else if (unformat (input, "action %d", &action))
13192         {
13193           ;
13194         }
13195       else
13196         {
13197           clib_warning ("parse error '%U'", format_unformat_error, input);
13198           return -99;
13199         }
13200     }
13201
13202   if (!rmt_eid_set)
13203     {
13204       errmsg ("remote eid addresses not set\n");
13205       return -99;
13206     }
13207
13208   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13209     {
13210       errmsg ("eid types don't match\n");
13211       return -99;
13212     }
13213
13214   if (0 == rmt_locs && (u32) ~ 0 == action)
13215     {
13216       errmsg ("action not set for negative mapping\n");
13217       return -99;
13218     }
13219
13220   /* Construct the API message */
13221   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13222
13223   mp->is_add = is_add;
13224   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13225   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13226   mp->eid_type = rmt_eid->type;
13227   mp->rmt_len = rmt_eid->len;
13228   mp->lcl_len = lcl_eid->len;
13229   mp->action = action;
13230
13231   if (0 != rmt_locs && 0 != lcl_locs)
13232     {
13233       mp->loc_num = vec_len (rmt_locs);
13234       clib_memcpy (mp->lcl_locs, lcl_locs,
13235                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13236       clib_memcpy (mp->rmt_locs, rmt_locs,
13237                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13238     }
13239   vec_free (lcl_locs);
13240   vec_free (rmt_locs);
13241
13242   /* send it... */
13243   S;
13244
13245   /* Wait for a reply... */
13246   W;
13247
13248   /* NOTREACHED */
13249   return 0;
13250 }
13251
13252 static int
13253 api_lisp_add_del_map_server (vat_main_t * vam)
13254 {
13255   unformat_input_t *input = vam->input;
13256   vl_api_lisp_add_del_map_server_t *mp;
13257   f64 timeout = ~0;
13258   u8 is_add = 1;
13259   u8 ipv4_set = 0;
13260   u8 ipv6_set = 0;
13261   ip4_address_t ipv4;
13262   ip6_address_t ipv6;
13263
13264   /* Parse args required to build the message */
13265   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13266     {
13267       if (unformat (input, "del"))
13268         {
13269           is_add = 0;
13270         }
13271       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13272         {
13273           ipv4_set = 1;
13274         }
13275       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13276         {
13277           ipv6_set = 1;
13278         }
13279       else
13280         break;
13281     }
13282
13283   if (ipv4_set && ipv6_set)
13284     {
13285       errmsg ("both eid v4 and v6 addresses set\n");
13286       return -99;
13287     }
13288
13289   if (!ipv4_set && !ipv6_set)
13290     {
13291       errmsg ("eid addresses not set\n");
13292       return -99;
13293     }
13294
13295   /* Construct the API message */
13296   M (LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server);
13297
13298   mp->is_add = is_add;
13299   if (ipv6_set)
13300     {
13301       mp->is_ipv6 = 1;
13302       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13303     }
13304   else
13305     {
13306       mp->is_ipv6 = 0;
13307       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13308     }
13309
13310   /* send it... */
13311   S;
13312
13313   /* Wait for a reply... */
13314   W;
13315
13316   /* NOTREACHED */
13317   return 0;
13318 }
13319
13320 static int
13321 api_lisp_add_del_map_resolver (vat_main_t * vam)
13322 {
13323   unformat_input_t *input = vam->input;
13324   vl_api_lisp_add_del_map_resolver_t *mp;
13325   f64 timeout = ~0;
13326   u8 is_add = 1;
13327   u8 ipv4_set = 0;
13328   u8 ipv6_set = 0;
13329   ip4_address_t ipv4;
13330   ip6_address_t ipv6;
13331
13332   /* Parse args required to build the message */
13333   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13334     {
13335       if (unformat (input, "del"))
13336         {
13337           is_add = 0;
13338         }
13339       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13340         {
13341           ipv4_set = 1;
13342         }
13343       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13344         {
13345           ipv6_set = 1;
13346         }
13347       else
13348         break;
13349     }
13350
13351   if (ipv4_set && ipv6_set)
13352     {
13353       errmsg ("both eid v4 and v6 addresses set\n");
13354       return -99;
13355     }
13356
13357   if (!ipv4_set && !ipv6_set)
13358     {
13359       errmsg ("eid addresses not set\n");
13360       return -99;
13361     }
13362
13363   /* Construct the API message */
13364   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13365
13366   mp->is_add = is_add;
13367   if (ipv6_set)
13368     {
13369       mp->is_ipv6 = 1;
13370       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13371     }
13372   else
13373     {
13374       mp->is_ipv6 = 0;
13375       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13376     }
13377
13378   /* send it... */
13379   S;
13380
13381   /* Wait for a reply... */
13382   W;
13383
13384   /* NOTREACHED */
13385   return 0;
13386 }
13387
13388 static int
13389 api_lisp_gpe_enable_disable (vat_main_t * vam)
13390 {
13391   unformat_input_t *input = vam->input;
13392   vl_api_lisp_gpe_enable_disable_t *mp;
13393   f64 timeout = ~0;
13394   u8 is_set = 0;
13395   u8 is_en = 1;
13396
13397   /* Parse args required to build the message */
13398   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13399     {
13400       if (unformat (input, "enable"))
13401         {
13402           is_set = 1;
13403           is_en = 1;
13404         }
13405       else if (unformat (input, "disable"))
13406         {
13407           is_set = 1;
13408           is_en = 0;
13409         }
13410       else
13411         break;
13412     }
13413
13414   if (is_set == 0)
13415     {
13416       errmsg ("Value not set\n");
13417       return -99;
13418     }
13419
13420   /* Construct the API message */
13421   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13422
13423   mp->is_en = is_en;
13424
13425   /* send it... */
13426   S;
13427
13428   /* Wait for a reply... */
13429   W;
13430
13431   /* NOTREACHED */
13432   return 0;
13433 }
13434
13435 static int
13436 api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
13437 {
13438   unformat_input_t *input = vam->input;
13439   vl_api_lisp_rloc_probe_enable_disable_t *mp;
13440   f64 timeout = ~0;
13441   u8 is_set = 0;
13442   u8 is_en = 0;
13443
13444   /* Parse args required to build the message */
13445   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13446     {
13447       if (unformat (input, "enable"))
13448         {
13449           is_set = 1;
13450           is_en = 1;
13451         }
13452       else if (unformat (input, "disable"))
13453         is_set = 1;
13454       else
13455         break;
13456     }
13457
13458   if (!is_set)
13459     {
13460       errmsg ("Value not set\n");
13461       return -99;
13462     }
13463
13464   /* Construct the API message */
13465   M (LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable);
13466
13467   mp->is_enabled = is_en;
13468
13469   /* send it... */
13470   S;
13471
13472   /* Wait for a reply... */
13473   W;
13474
13475   /* NOTREACHED */
13476   return 0;
13477 }
13478
13479 static int
13480 api_lisp_map_register_enable_disable (vat_main_t * vam)
13481 {
13482   unformat_input_t *input = vam->input;
13483   vl_api_lisp_map_register_enable_disable_t *mp;
13484   f64 timeout = ~0;
13485   u8 is_set = 0;
13486   u8 is_en = 0;
13487
13488   /* Parse args required to build the message */
13489   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13490     {
13491       if (unformat (input, "enable"))
13492         {
13493           is_set = 1;
13494           is_en = 1;
13495         }
13496       else if (unformat (input, "disable"))
13497         is_set = 1;
13498       else
13499         break;
13500     }
13501
13502   if (!is_set)
13503     {
13504       errmsg ("Value not set\n");
13505       return -99;
13506     }
13507
13508   /* Construct the API message */
13509   M (LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable);
13510
13511   mp->is_enabled = is_en;
13512
13513   /* send it... */
13514   S;
13515
13516   /* Wait for a reply... */
13517   W;
13518
13519   /* NOTREACHED */
13520   return 0;
13521 }
13522
13523 static int
13524 api_lisp_enable_disable (vat_main_t * vam)
13525 {
13526   unformat_input_t *input = vam->input;
13527   vl_api_lisp_enable_disable_t *mp;
13528   f64 timeout = ~0;
13529   u8 is_set = 0;
13530   u8 is_en = 0;
13531
13532   /* Parse args required to build the message */
13533   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13534     {
13535       if (unformat (input, "enable"))
13536         {
13537           is_set = 1;
13538           is_en = 1;
13539         }
13540       else if (unformat (input, "disable"))
13541         {
13542           is_set = 1;
13543         }
13544       else
13545         break;
13546     }
13547
13548   if (!is_set)
13549     {
13550       errmsg ("Value not set\n");
13551       return -99;
13552     }
13553
13554   /* Construct the API message */
13555   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13556
13557   mp->is_en = is_en;
13558
13559   /* send it... */
13560   S;
13561
13562   /* Wait for a reply... */
13563   W;
13564
13565   /* NOTREACHED */
13566   return 0;
13567 }
13568
13569 static int
13570 api_show_lisp_map_register_state (vat_main_t * vam)
13571 {
13572   f64 timeout = ~0;
13573   vl_api_show_lisp_map_register_state_t *mp;
13574
13575   M (SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state);
13576
13577   /* send */
13578   S;
13579
13580   /* wait for reply */
13581   W;
13582
13583   return 0;
13584 }
13585
13586 static int
13587 api_show_lisp_rloc_probe_state (vat_main_t * vam)
13588 {
13589   f64 timeout = ~0;
13590   vl_api_show_lisp_rloc_probe_state_t *mp;
13591
13592   M (SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state);
13593
13594   /* send */
13595   S;
13596
13597   /* wait for reply */
13598   W;
13599
13600   return 0;
13601 }
13602
13603 static int
13604 api_show_lisp_map_request_mode (vat_main_t * vam)
13605 {
13606   f64 timeout = ~0;
13607   vl_api_show_lisp_map_request_mode_t *mp;
13608
13609   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13610
13611   /* send */
13612   S;
13613
13614   /* wait for reply */
13615   W;
13616
13617   return 0;
13618 }
13619
13620 static int
13621 api_lisp_map_request_mode (vat_main_t * vam)
13622 {
13623   f64 timeout = ~0;
13624   unformat_input_t *input = vam->input;
13625   vl_api_lisp_map_request_mode_t *mp;
13626   u8 mode = 0;
13627
13628   /* Parse args required to build the message */
13629   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13630     {
13631       if (unformat (input, "dst-only"))
13632         mode = 0;
13633       else if (unformat (input, "src-dst"))
13634         mode = 1;
13635       else
13636         {
13637           errmsg ("parse error '%U'", format_unformat_error, input);
13638           return -99;
13639         }
13640     }
13641
13642   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13643
13644   mp->mode = mode;
13645
13646   /* send */
13647   S;
13648
13649   /* wait for reply */
13650   W;
13651
13652   /* notreached */
13653   return 0;
13654 }
13655
13656 /**
13657  * Enable/disable LISP proxy ITR.
13658  *
13659  * @param vam vpp API test context
13660  * @return return code
13661  */
13662 static int
13663 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13664 {
13665   f64 timeout = ~0;
13666   u8 ls_name_set = 0;
13667   unformat_input_t *input = vam->input;
13668   vl_api_lisp_pitr_set_locator_set_t *mp;
13669   u8 is_add = 1;
13670   u8 *ls_name = 0;
13671
13672   /* Parse args required to build the message */
13673   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13674     {
13675       if (unformat (input, "del"))
13676         is_add = 0;
13677       else if (unformat (input, "locator-set %s", &ls_name))
13678         ls_name_set = 1;
13679       else
13680         {
13681           errmsg ("parse error '%U'", format_unformat_error, input);
13682           return -99;
13683         }
13684     }
13685
13686   if (!ls_name_set)
13687     {
13688       errmsg ("locator-set name not set!");
13689       return -99;
13690     }
13691
13692   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13693
13694   mp->is_add = is_add;
13695   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13696   vec_free (ls_name);
13697
13698   /* send */
13699   S;
13700
13701   /* wait for reply */
13702   W;
13703
13704   /* notreached */
13705   return 0;
13706 }
13707
13708 static int
13709 api_show_lisp_pitr (vat_main_t * vam)
13710 {
13711   vl_api_show_lisp_pitr_t *mp;
13712   f64 timeout = ~0;
13713
13714   if (!vam->json_output)
13715     {
13716       fformat (vam->ofp, "%=20s\n", "lisp status:");
13717     }
13718
13719   M (SHOW_LISP_PITR, show_lisp_pitr);
13720   /* send it... */
13721   S;
13722
13723   /* Wait for a reply... */
13724   W;
13725
13726   /* NOTREACHED */
13727   return 0;
13728 }
13729
13730 /**
13731  * Add/delete mapping between vni and vrf
13732  */
13733 static int
13734 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13735 {
13736   f64 timeout = ~0;
13737   unformat_input_t *input = vam->input;
13738   vl_api_lisp_eid_table_add_del_map_t *mp;
13739   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13740   u32 vni, vrf, bd_index;
13741
13742   /* Parse args required to build the message */
13743   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13744     {
13745       if (unformat (input, "del"))
13746         is_add = 0;
13747       else if (unformat (input, "vrf %d", &vrf))
13748         vrf_set = 1;
13749       else if (unformat (input, "bd_index %d", &bd_index))
13750         bd_index_set = 1;
13751       else if (unformat (input, "vni %d", &vni))
13752         vni_set = 1;
13753       else
13754         break;
13755     }
13756
13757   if (!vni_set || (!vrf_set && !bd_index_set))
13758     {
13759       errmsg ("missing arguments!");
13760       return -99;
13761     }
13762
13763   if (vrf_set && bd_index_set)
13764     {
13765       errmsg ("error: both vrf and bd entered!");
13766       return -99;
13767     }
13768
13769   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13770
13771   mp->is_add = is_add;
13772   mp->vni = htonl (vni);
13773   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13774   mp->is_l2 = bd_index_set;
13775
13776   /* send */
13777   S;
13778
13779   /* wait for reply */
13780   W;
13781
13782   /* notreached */
13783   return 0;
13784 }
13785
13786 uword
13787 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13788 {
13789   u32 *action = va_arg (*args, u32 *);
13790   u8 *s = 0;
13791
13792   if (unformat (input, "%s", &s))
13793     {
13794       if (!strcmp ((char *) s, "no-action"))
13795         action[0] = 0;
13796       else if (!strcmp ((char *) s, "natively-forward"))
13797         action[0] = 1;
13798       else if (!strcmp ((char *) s, "send-map-request"))
13799         action[0] = 2;
13800       else if (!strcmp ((char *) s, "drop"))
13801         action[0] = 3;
13802       else
13803         {
13804           clib_warning ("invalid action: '%s'", s);
13805           action[0] = 3;
13806         }
13807     }
13808   else
13809     return 0;
13810
13811   vec_free (s);
13812   return 1;
13813 }
13814
13815 /**
13816  * Add/del remote mapping to/from LISP control plane
13817  *
13818  * @param vam vpp API test context
13819  * @return return code
13820  */
13821 static int
13822 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13823 {
13824   unformat_input_t *input = vam->input;
13825   vl_api_lisp_add_del_remote_mapping_t *mp;
13826   f64 timeout = ~0;
13827   u32 vni = 0;
13828   lisp_eid_vat_t _eid, *eid = &_eid;
13829   lisp_eid_vat_t _seid, *seid = &_seid;
13830   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13831   u32 action = ~0, p, w, data_len;
13832   ip4_address_t rloc4;
13833   ip6_address_t rloc6;
13834   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13835
13836   memset (&rloc, 0, sizeof (rloc));
13837
13838   /* Parse args required to build the message */
13839   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13840     {
13841       if (unformat (input, "del-all"))
13842         {
13843           del_all = 1;
13844         }
13845       else if (unformat (input, "del"))
13846         {
13847           is_add = 0;
13848         }
13849       else if (unformat (input, "add"))
13850         {
13851           is_add = 1;
13852         }
13853       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13854         {
13855           eid_set = 1;
13856         }
13857       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13858         {
13859           seid_set = 1;
13860         }
13861       else if (unformat (input, "vni %d", &vni))
13862         {
13863           ;
13864         }
13865       else if (unformat (input, "p %d w %d", &p, &w))
13866         {
13867           if (!curr_rloc)
13868             {
13869               errmsg ("No RLOC configured for setting priority/weight!");
13870               return -99;
13871             }
13872           curr_rloc->priority = p;
13873           curr_rloc->weight = w;
13874         }
13875       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13876         {
13877           rloc.is_ip4 = 1;
13878           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13879           vec_add1 (rlocs, rloc);
13880           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13881         }
13882       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13883         {
13884           rloc.is_ip4 = 0;
13885           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13886           vec_add1 (rlocs, rloc);
13887           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13888         }
13889       else if (unformat (input, "action %U",
13890                          unformat_negative_mapping_action, &action))
13891         {
13892           ;
13893         }
13894       else
13895         {
13896           clib_warning ("parse error '%U'", format_unformat_error, input);
13897           return -99;
13898         }
13899     }
13900
13901   if (0 == eid_set)
13902     {
13903       errmsg ("missing params!");
13904       return -99;
13905     }
13906
13907   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13908     {
13909       errmsg ("no action set for negative map-reply!");
13910       return -99;
13911     }
13912
13913   data_len = vec_len (rlocs) * sizeof (rloc_t);
13914
13915   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13916   mp->is_add = is_add;
13917   mp->vni = htonl (vni);
13918   mp->action = (u8) action;
13919   mp->is_src_dst = seid_set;
13920   mp->eid_len = eid->len;
13921   mp->seid_len = seid->len;
13922   mp->del_all = del_all;
13923   mp->eid_type = eid->type;
13924   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13925   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13926
13927   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13928   clib_memcpy (mp->rlocs, rlocs, data_len);
13929   vec_free (rlocs);
13930
13931   /* send it... */
13932   S;
13933
13934   /* Wait for a reply... */
13935   W;
13936
13937   /* NOTREACHED */
13938   return 0;
13939 }
13940
13941 /**
13942  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13943  * forwarding entries in data-plane accordingly.
13944  *
13945  * @param vam vpp API test context
13946  * @return return code
13947  */
13948 static int
13949 api_lisp_add_del_adjacency (vat_main_t * vam)
13950 {
13951   unformat_input_t *input = vam->input;
13952   vl_api_lisp_add_del_adjacency_t *mp;
13953   f64 timeout = ~0;
13954   u32 vni = 0;
13955   ip4_address_t leid4, reid4;
13956   ip6_address_t leid6, reid6;
13957   u8 reid_mac[6] = { 0 };
13958   u8 leid_mac[6] = { 0 };
13959   u8 reid_type, leid_type;
13960   u32 leid_len = 0, reid_len = 0, len;
13961   u8 is_add = 1;
13962
13963   leid_type = reid_type = (u8) ~ 0;
13964
13965   /* Parse args required to build the message */
13966   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13967     {
13968       if (unformat (input, "del"))
13969         {
13970           is_add = 0;
13971         }
13972       else if (unformat (input, "add"))
13973         {
13974           is_add = 1;
13975         }
13976       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13977                          &reid4, &len))
13978         {
13979           reid_type = 0;        /* ipv4 */
13980           reid_len = len;
13981         }
13982       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13983                          &reid6, &len))
13984         {
13985           reid_type = 1;        /* ipv6 */
13986           reid_len = len;
13987         }
13988       else if (unformat (input, "reid %U", unformat_ethernet_address,
13989                          reid_mac))
13990         {
13991           reid_type = 2;        /* mac */
13992         }
13993       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13994                          &leid4, &len))
13995         {
13996           leid_type = 0;        /* ipv4 */
13997           leid_len = len;
13998         }
13999       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14000                          &leid6, &len))
14001         {
14002           leid_type = 1;        /* ipv6 */
14003           leid_len = len;
14004         }
14005       else if (unformat (input, "leid %U", unformat_ethernet_address,
14006                          leid_mac))
14007         {
14008           leid_type = 2;        /* mac */
14009         }
14010       else if (unformat (input, "vni %d", &vni))
14011         {
14012           ;
14013         }
14014       else
14015         {
14016           errmsg ("parse error '%U'", format_unformat_error, input);
14017           return -99;
14018         }
14019     }
14020
14021   if ((u8) ~ 0 == reid_type)
14022     {
14023       errmsg ("missing params!");
14024       return -99;
14025     }
14026
14027   if (leid_type != reid_type)
14028     {
14029       errmsg ("remote and local EIDs are of different types!");
14030       return -99;
14031     }
14032
14033   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
14034   mp->is_add = is_add;
14035   mp->vni = htonl (vni);
14036   mp->leid_len = leid_len;
14037   mp->reid_len = reid_len;
14038   mp->eid_type = reid_type;
14039
14040   switch (mp->eid_type)
14041     {
14042     case 0:
14043       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14044       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14045       break;
14046     case 1:
14047       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14048       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14049       break;
14050     case 2:
14051       clib_memcpy (mp->leid, leid_mac, 6);
14052       clib_memcpy (mp->reid, reid_mac, 6);
14053       break;
14054     default:
14055       errmsg ("unknown EID type %d!", mp->eid_type);
14056       return 0;
14057     }
14058
14059   /* send it... */
14060   S;
14061
14062   /* Wait for a reply... */
14063   W;
14064
14065   /* NOTREACHED */
14066   return 0;
14067 }
14068
14069 static int
14070 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14071 {
14072   unformat_input_t *input = vam->input;
14073   vl_api_lisp_gpe_add_del_iface_t *mp;
14074   f64 timeout = ~0;
14075   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14076   u32 dp_table = 0, vni = 0;
14077
14078   /* Parse args required to build the message */
14079   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14080     {
14081       if (unformat (input, "up"))
14082         {
14083           action_set = 1;
14084           is_add = 1;
14085         }
14086       else if (unformat (input, "down"))
14087         {
14088           action_set = 1;
14089           is_add = 0;
14090         }
14091       else if (unformat (input, "table_id %d", &dp_table))
14092         {
14093           dp_table_set = 1;
14094         }
14095       else if (unformat (input, "bd_id %d", &dp_table))
14096         {
14097           dp_table_set = 1;
14098           is_l2 = 1;
14099         }
14100       else if (unformat (input, "vni %d", &vni))
14101         {
14102           vni_set = 1;
14103         }
14104       else
14105         break;
14106     }
14107
14108   if (action_set == 0)
14109     {
14110       errmsg ("Action not set\n");
14111       return -99;
14112     }
14113   if (dp_table_set == 0 || vni_set == 0)
14114     {
14115       errmsg ("vni and dp_table must be set\n");
14116       return -99;
14117     }
14118
14119   /* Construct the API message */
14120   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
14121
14122   mp->is_add = is_add;
14123   mp->dp_table = dp_table;
14124   mp->is_l2 = is_l2;
14125   mp->vni = vni;
14126
14127   /* send it... */
14128   S;
14129
14130   /* Wait for a reply... */
14131   W;
14132
14133   /* NOTREACHED */
14134   return 0;
14135 }
14136
14137 /**
14138  * Add/del map request itr rlocs from LISP control plane and updates
14139  *
14140  * @param vam vpp API test context
14141  * @return return code
14142  */
14143 static int
14144 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14145 {
14146   unformat_input_t *input = vam->input;
14147   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14148   f64 timeout = ~0;
14149   u8 *locator_set_name = 0;
14150   u8 locator_set_name_set = 0;
14151   u8 is_add = 1;
14152
14153   /* Parse args required to build the message */
14154   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14155     {
14156       if (unformat (input, "del"))
14157         {
14158           is_add = 0;
14159         }
14160       else if (unformat (input, "%_%v%_", &locator_set_name))
14161         {
14162           locator_set_name_set = 1;
14163         }
14164       else
14165         {
14166           clib_warning ("parse error '%U'", format_unformat_error, input);
14167           return -99;
14168         }
14169     }
14170
14171   if (is_add && !locator_set_name_set)
14172     {
14173       errmsg ("itr-rloc is not set!");
14174       return -99;
14175     }
14176
14177   if (is_add && vec_len (locator_set_name) > 64)
14178     {
14179       errmsg ("itr-rloc locator-set name too long\n");
14180       vec_free (locator_set_name);
14181       return -99;
14182     }
14183
14184   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
14185   mp->is_add = is_add;
14186   if (is_add)
14187     {
14188       clib_memcpy (mp->locator_set_name, locator_set_name,
14189                    vec_len (locator_set_name));
14190     }
14191   else
14192     {
14193       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14194     }
14195   vec_free (locator_set_name);
14196
14197   /* send it... */
14198   S;
14199
14200   /* Wait for a reply... */
14201   W;
14202
14203   /* NOTREACHED */
14204   return 0;
14205 }
14206
14207 static int
14208 api_lisp_locator_dump (vat_main_t * vam)
14209 {
14210   unformat_input_t *input = vam->input;
14211   vl_api_lisp_locator_dump_t *mp;
14212   f64 timeout = ~0;
14213   u8 is_index_set = 0, is_name_set = 0;
14214   u8 *ls_name = 0;
14215   u32 ls_index = ~0;
14216
14217   /* Parse args required to build the message */
14218   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14219     {
14220       if (unformat (input, "ls_name %_%v%_", &ls_name))
14221         {
14222           is_name_set = 1;
14223         }
14224       else if (unformat (input, "ls_index %d", &ls_index))
14225         {
14226           is_index_set = 1;
14227         }
14228       else
14229         {
14230           errmsg ("parse error '%U'", format_unformat_error, input);
14231           return -99;
14232         }
14233     }
14234
14235   if (!is_index_set && !is_name_set)
14236     {
14237       errmsg ("error: expected one of index or name!\n");
14238       return -99;
14239     }
14240
14241   if (is_index_set && is_name_set)
14242     {
14243       errmsg ("error: only one param expected!\n");
14244       return -99;
14245     }
14246
14247   if (vec_len (ls_name) > 62)
14248     {
14249       errmsg ("error: locator set name too long!");
14250       return -99;
14251     }
14252
14253   if (!vam->json_output)
14254     {
14255       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
14256                "weight");
14257     }
14258
14259   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
14260   mp->is_index_set = is_index_set;
14261
14262   if (is_index_set)
14263     mp->ls_index = clib_host_to_net_u32 (ls_index);
14264   else
14265     {
14266       vec_add1 (ls_name, 0);
14267       strncpy ((char *) mp->ls_name, (char *) ls_name,
14268                sizeof (mp->ls_name) - 1);
14269     }
14270
14271   /* send it... */
14272   S;
14273
14274   /* Use a control ping for synchronization */
14275   {
14276     vl_api_control_ping_t *mp;
14277     M (CONTROL_PING, control_ping);
14278     S;
14279   }
14280   /* Wait for a reply... */
14281   W;
14282
14283   /* NOTREACHED */
14284   return 0;
14285 }
14286
14287 static int
14288 api_lisp_locator_set_dump (vat_main_t * vam)
14289 {
14290   vl_api_lisp_locator_set_dump_t *mp;
14291   unformat_input_t *input = vam->input;
14292   f64 timeout = ~0;
14293   u8 filter = 0;
14294
14295   /* Parse args required to build the message */
14296   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14297     {
14298       if (unformat (input, "local"))
14299         {
14300           filter = 1;
14301         }
14302       else if (unformat (input, "remote"))
14303         {
14304           filter = 2;
14305         }
14306       else
14307         {
14308           errmsg ("parse error '%U'", format_unformat_error, input);
14309           return -99;
14310         }
14311     }
14312
14313   if (!vam->json_output)
14314     {
14315       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
14316     }
14317
14318   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14319
14320   mp->filter = filter;
14321
14322   /* send it... */
14323   S;
14324
14325   /* Use a control ping for synchronization */
14326   {
14327     vl_api_control_ping_t *mp;
14328     M (CONTROL_PING, control_ping);
14329     S;
14330   }
14331   /* Wait for a reply... */
14332   W;
14333
14334   /* NOTREACHED */
14335   return 0;
14336 }
14337
14338 static int
14339 api_lisp_eid_table_map_dump (vat_main_t * vam)
14340 {
14341   u8 is_l2 = 0;
14342   u8 mode_set = 0;
14343   unformat_input_t *input = vam->input;
14344   vl_api_lisp_eid_table_map_dump_t *mp;
14345   f64 timeout = ~0;
14346
14347   /* Parse args required to build the message */
14348   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14349     {
14350       if (unformat (input, "l2"))
14351         {
14352           is_l2 = 1;
14353           mode_set = 1;
14354         }
14355       else if (unformat (input, "l3"))
14356         {
14357           is_l2 = 0;
14358           mode_set = 1;
14359         }
14360       else
14361         {
14362           errmsg ("parse error '%U'", format_unformat_error, input);
14363           return -99;
14364         }
14365     }
14366
14367   if (!mode_set)
14368     {
14369       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
14370       return -99;
14371     }
14372
14373   if (!vam->json_output)
14374     {
14375       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
14376     }
14377
14378   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14379   mp->is_l2 = is_l2;
14380
14381   /* send it... */
14382   S;
14383
14384   /* Use a control ping for synchronization */
14385   {
14386     vl_api_control_ping_t *mp;
14387     M (CONTROL_PING, control_ping);
14388     S;
14389   }
14390   /* Wait for a reply... */
14391   W;
14392
14393   /* NOTREACHED */
14394   return 0;
14395 }
14396
14397 static int
14398 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14399 {
14400   vl_api_lisp_eid_table_vni_dump_t *mp;
14401   f64 timeout = ~0;
14402
14403   if (!vam->json_output)
14404     {
14405       fformat (vam->ofp, "VNI\n");
14406     }
14407
14408   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14409
14410   /* send it... */
14411   S;
14412
14413   /* Use a control ping for synchronization */
14414   {
14415     vl_api_control_ping_t *mp;
14416     M (CONTROL_PING, control_ping);
14417     S;
14418   }
14419   /* Wait for a reply... */
14420   W;
14421
14422   /* NOTREACHED */
14423   return 0;
14424 }
14425
14426 static int
14427 api_lisp_eid_table_dump (vat_main_t * vam)
14428 {
14429   unformat_input_t *i = vam->input;
14430   vl_api_lisp_eid_table_dump_t *mp;
14431   f64 timeout = ~0;
14432   struct in_addr ip4;
14433   struct in6_addr ip6;
14434   u8 mac[6];
14435   u8 eid_type = ~0, eid_set = 0;
14436   u32 prefix_length = ~0, t, vni = 0;
14437   u8 filter = 0;
14438
14439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14440     {
14441       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14442         {
14443           eid_set = 1;
14444           eid_type = 0;
14445           prefix_length = t;
14446         }
14447       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14448         {
14449           eid_set = 1;
14450           eid_type = 1;
14451           prefix_length = t;
14452         }
14453       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14454         {
14455           eid_set = 1;
14456           eid_type = 2;
14457         }
14458       else if (unformat (i, "vni %d", &t))
14459         {
14460           vni = t;
14461         }
14462       else if (unformat (i, "local"))
14463         {
14464           filter = 1;
14465         }
14466       else if (unformat (i, "remote"))
14467         {
14468           filter = 2;
14469         }
14470       else
14471         {
14472           errmsg ("parse error '%U'", format_unformat_error, i);
14473           return -99;
14474         }
14475     }
14476
14477   if (!vam->json_output)
14478     {
14479       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s\n", "EID",
14480                "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14481     }
14482
14483   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14484
14485   mp->filter = filter;
14486   if (eid_set)
14487     {
14488       mp->eid_set = 1;
14489       mp->vni = htonl (vni);
14490       mp->eid_type = eid_type;
14491       switch (eid_type)
14492         {
14493         case 0:
14494           mp->prefix_length = prefix_length;
14495           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14496           break;
14497         case 1:
14498           mp->prefix_length = prefix_length;
14499           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14500           break;
14501         case 2:
14502           clib_memcpy (mp->eid, mac, sizeof (mac));
14503           break;
14504         default:
14505           errmsg ("unknown EID type %d!", eid_type);
14506           return -99;
14507         }
14508     }
14509
14510   /* send it... */
14511   S;
14512
14513   /* Use a control ping for synchronization */
14514   {
14515     vl_api_control_ping_t *mp;
14516     M (CONTROL_PING, control_ping);
14517     S;
14518   }
14519
14520   /* Wait for a reply... */
14521   W;
14522
14523   /* NOTREACHED */
14524   return 0;
14525 }
14526
14527 static int
14528 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14529 {
14530   vl_api_lisp_gpe_tunnel_dump_t *mp;
14531   f64 timeout = ~0;
14532
14533   if (!vam->json_output)
14534     {
14535       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14536                "%=16s%=16s%=16s%=16s%=16s\n",
14537                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14538                "Decap next", "Lisp version", "Flags", "Next protocol",
14539                "ver_res", "res", "iid");
14540     }
14541
14542   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14543   /* send it... */
14544   S;
14545
14546   /* Use a control ping for synchronization */
14547   {
14548     vl_api_control_ping_t *mp;
14549     M (CONTROL_PING, control_ping);
14550     S;
14551   }
14552   /* Wait for a reply... */
14553   W;
14554
14555   /* NOTREACHED */
14556   return 0;
14557 }
14558
14559 static int
14560 api_lisp_adjacencies_get (vat_main_t * vam)
14561 {
14562   unformat_input_t *i = vam->input;
14563   vl_api_lisp_adjacencies_get_t *mp;
14564   f64 timeout = ~0;
14565   u8 vni_set = 0;
14566   u32 vni = ~0;
14567
14568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14569     {
14570       if (unformat (i, "vni %d", &vni))
14571         {
14572           vni_set = 1;
14573         }
14574       else
14575         {
14576           errmsg ("parse error '%U'\n", format_unformat_error, i);
14577           return -99;
14578         }
14579     }
14580
14581   if (!vni_set)
14582     {
14583       errmsg ("vni not set!\n");
14584       return -99;
14585     }
14586
14587   if (!vam->json_output)
14588     {
14589       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14590     }
14591
14592   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14593   mp->vni = clib_host_to_net_u32 (vni);
14594
14595   /* send it... */
14596   S;
14597
14598   /* Wait for a reply... */
14599   W;
14600
14601   /* NOTREACHED */
14602   return 0;
14603 }
14604
14605 static int
14606 api_lisp_map_server_dump (vat_main_t * vam)
14607 {
14608   vl_api_lisp_map_server_dump_t *mp;
14609   f64 timeout = ~0;
14610
14611   if (!vam->json_output)
14612     {
14613       fformat (vam->ofp, "%=20s\n", "Map server");
14614     }
14615
14616   M (LISP_MAP_SERVER_DUMP, lisp_map_server_dump);
14617   /* send it... */
14618   S;
14619
14620   /* Use a control ping for synchronization */
14621   {
14622     vl_api_control_ping_t *mp;
14623     M (CONTROL_PING, control_ping);
14624     S;
14625   }
14626   /* Wait for a reply... */
14627   W;
14628
14629   /* NOTREACHED */
14630   return 0;
14631 }
14632
14633 static int
14634 api_lisp_map_resolver_dump (vat_main_t * vam)
14635 {
14636   vl_api_lisp_map_resolver_dump_t *mp;
14637   f64 timeout = ~0;
14638
14639   if (!vam->json_output)
14640     {
14641       fformat (vam->ofp, "%=20s\n", "Map resolver");
14642     }
14643
14644   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14645   /* send it... */
14646   S;
14647
14648   /* Use a control ping for synchronization */
14649   {
14650     vl_api_control_ping_t *mp;
14651     M (CONTROL_PING, control_ping);
14652     S;
14653   }
14654   /* Wait for a reply... */
14655   W;
14656
14657   /* NOTREACHED */
14658   return 0;
14659 }
14660
14661 static int
14662 api_show_lisp_status (vat_main_t * vam)
14663 {
14664   vl_api_show_lisp_status_t *mp;
14665   f64 timeout = ~0;
14666
14667   if (!vam->json_output)
14668     {
14669       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14670     }
14671
14672   M (SHOW_LISP_STATUS, show_lisp_status);
14673   /* send it... */
14674   S;
14675   /* Wait for a reply... */
14676   W;
14677
14678   /* NOTREACHED */
14679   return 0;
14680 }
14681
14682 static int
14683 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14684 {
14685   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14686   f64 timeout = ~0;
14687
14688   if (!vam->json_output)
14689     {
14690       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14691     }
14692
14693   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14694   /* send it... */
14695   S;
14696   /* Wait for a reply... */
14697   W;
14698
14699   /* NOTREACHED */
14700   return 0;
14701 }
14702
14703 static int
14704 api_af_packet_create (vat_main_t * vam)
14705 {
14706   unformat_input_t *i = vam->input;
14707   vl_api_af_packet_create_t *mp;
14708   f64 timeout;
14709   u8 *host_if_name = 0;
14710   u8 hw_addr[6];
14711   u8 random_hw_addr = 1;
14712
14713   memset (hw_addr, 0, sizeof (hw_addr));
14714
14715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14716     {
14717       if (unformat (i, "name %s", &host_if_name))
14718         vec_add1 (host_if_name, 0);
14719       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14720         random_hw_addr = 0;
14721       else
14722         break;
14723     }
14724
14725   if (!vec_len (host_if_name))
14726     {
14727       errmsg ("host-interface name must be specified");
14728       return -99;
14729     }
14730
14731   if (vec_len (host_if_name) > 64)
14732     {
14733       errmsg ("host-interface name too long");
14734       return -99;
14735     }
14736
14737   M (AF_PACKET_CREATE, af_packet_create);
14738
14739   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14740   clib_memcpy (mp->hw_addr, hw_addr, 6);
14741   mp->use_random_hw_addr = random_hw_addr;
14742   vec_free (host_if_name);
14743
14744   S;
14745   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14746   /* NOTREACHED */
14747   return 0;
14748 }
14749
14750 static int
14751 api_af_packet_delete (vat_main_t * vam)
14752 {
14753   unformat_input_t *i = vam->input;
14754   vl_api_af_packet_delete_t *mp;
14755   f64 timeout;
14756   u8 *host_if_name = 0;
14757
14758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14759     {
14760       if (unformat (i, "name %s", &host_if_name))
14761         vec_add1 (host_if_name, 0);
14762       else
14763         break;
14764     }
14765
14766   if (!vec_len (host_if_name))
14767     {
14768       errmsg ("host-interface name must be specified");
14769       return -99;
14770     }
14771
14772   if (vec_len (host_if_name) > 64)
14773     {
14774       errmsg ("host-interface name too long");
14775       return -99;
14776     }
14777
14778   M (AF_PACKET_DELETE, af_packet_delete);
14779
14780   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14781   vec_free (host_if_name);
14782
14783   S;
14784   W;
14785   /* NOTREACHED */
14786   return 0;
14787 }
14788
14789 static int
14790 api_policer_add_del (vat_main_t * vam)
14791 {
14792   unformat_input_t *i = vam->input;
14793   vl_api_policer_add_del_t *mp;
14794   f64 timeout;
14795   u8 is_add = 1;
14796   u8 *name = 0;
14797   u32 cir = 0;
14798   u32 eir = 0;
14799   u64 cb = 0;
14800   u64 eb = 0;
14801   u8 rate_type = 0;
14802   u8 round_type = 0;
14803   u8 type = 0;
14804   u8 color_aware = 0;
14805   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14806
14807   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14808   conform_action.dscp = 0;
14809   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14810   exceed_action.dscp = 0;
14811   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14812   violate_action.dscp = 0;
14813
14814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14815     {
14816       if (unformat (i, "del"))
14817         is_add = 0;
14818       else if (unformat (i, "name %s", &name))
14819         vec_add1 (name, 0);
14820       else if (unformat (i, "cir %u", &cir))
14821         ;
14822       else if (unformat (i, "eir %u", &eir))
14823         ;
14824       else if (unformat (i, "cb %u", &cb))
14825         ;
14826       else if (unformat (i, "eb %u", &eb))
14827         ;
14828       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14829                          &rate_type))
14830         ;
14831       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14832                          &round_type))
14833         ;
14834       else if (unformat (i, "type %U", unformat_policer_type, &type))
14835         ;
14836       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14837                          &conform_action))
14838         ;
14839       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14840                          &exceed_action))
14841         ;
14842       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14843                          &violate_action))
14844         ;
14845       else if (unformat (i, "color-aware"))
14846         color_aware = 1;
14847       else
14848         break;
14849     }
14850
14851   if (!vec_len (name))
14852     {
14853       errmsg ("policer name must be specified");
14854       return -99;
14855     }
14856
14857   if (vec_len (name) > 64)
14858     {
14859       errmsg ("policer name too long");
14860       return -99;
14861     }
14862
14863   M (POLICER_ADD_DEL, policer_add_del);
14864
14865   clib_memcpy (mp->name, name, vec_len (name));
14866   vec_free (name);
14867   mp->is_add = is_add;
14868   mp->cir = cir;
14869   mp->eir = eir;
14870   mp->cb = cb;
14871   mp->eb = eb;
14872   mp->rate_type = rate_type;
14873   mp->round_type = round_type;
14874   mp->type = type;
14875   mp->conform_action_type = conform_action.action_type;
14876   mp->conform_dscp = conform_action.dscp;
14877   mp->exceed_action_type = exceed_action.action_type;
14878   mp->exceed_dscp = exceed_action.dscp;
14879   mp->violate_action_type = violate_action.action_type;
14880   mp->violate_dscp = violate_action.dscp;
14881   mp->color_aware = color_aware;
14882
14883   S;
14884   W;
14885   /* NOTREACHED */
14886   return 0;
14887 }
14888
14889 static int
14890 api_policer_dump (vat_main_t * vam)
14891 {
14892   unformat_input_t *i = vam->input;
14893   vl_api_policer_dump_t *mp;
14894   f64 timeout = ~0;
14895   u8 *match_name = 0;
14896   u8 match_name_valid = 0;
14897
14898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14899     {
14900       if (unformat (i, "name %s", &match_name))
14901         {
14902           vec_add1 (match_name, 0);
14903           match_name_valid = 1;
14904         }
14905       else
14906         break;
14907     }
14908
14909   M (POLICER_DUMP, policer_dump);
14910   mp->match_name_valid = match_name_valid;
14911   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14912   vec_free (match_name);
14913   /* send it... */
14914   S;
14915
14916   /* Use a control ping for synchronization */
14917   {
14918     vl_api_control_ping_t *mp;
14919     M (CONTROL_PING, control_ping);
14920     S;
14921   }
14922   /* Wait for a reply... */
14923   W;
14924
14925   /* NOTREACHED */
14926   return 0;
14927 }
14928
14929 static int
14930 api_policer_classify_set_interface (vat_main_t * vam)
14931 {
14932   unformat_input_t *i = vam->input;
14933   vl_api_policer_classify_set_interface_t *mp;
14934   f64 timeout;
14935   u32 sw_if_index;
14936   int sw_if_index_set;
14937   u32 ip4_table_index = ~0;
14938   u32 ip6_table_index = ~0;
14939   u32 l2_table_index = ~0;
14940   u8 is_add = 1;
14941
14942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14943     {
14944       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14945         sw_if_index_set = 1;
14946       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14947         sw_if_index_set = 1;
14948       else if (unformat (i, "del"))
14949         is_add = 0;
14950       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14951         ;
14952       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14953         ;
14954       else if (unformat (i, "l2-table %d", &l2_table_index))
14955         ;
14956       else
14957         {
14958           clib_warning ("parse error '%U'", format_unformat_error, i);
14959           return -99;
14960         }
14961     }
14962
14963   if (sw_if_index_set == 0)
14964     {
14965       errmsg ("missing interface name or sw_if_index\n");
14966       return -99;
14967     }
14968
14969   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14970
14971   mp->sw_if_index = ntohl (sw_if_index);
14972   mp->ip4_table_index = ntohl (ip4_table_index);
14973   mp->ip6_table_index = ntohl (ip6_table_index);
14974   mp->l2_table_index = ntohl (l2_table_index);
14975   mp->is_add = is_add;
14976
14977   S;
14978   W;
14979   /* NOTREACHED */
14980   return 0;
14981 }
14982
14983 static int
14984 api_policer_classify_dump (vat_main_t * vam)
14985 {
14986   unformat_input_t *i = vam->input;
14987   vl_api_policer_classify_dump_t *mp;
14988   f64 timeout = ~0;
14989   u8 type = POLICER_CLASSIFY_N_TABLES;
14990
14991   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14992     ;
14993   else
14994     {
14995       errmsg ("classify table type must be specified\n");
14996       return -99;
14997     }
14998
14999   if (!vam->json_output)
15000     {
15001       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
15002     }
15003
15004   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
15005   mp->type = type;
15006   /* send it... */
15007   S;
15008
15009   /* Use a control ping for synchronization */
15010   {
15011     vl_api_control_ping_t *mp;
15012     M (CONTROL_PING, control_ping);
15013     S;
15014   }
15015   /* Wait for a reply... */
15016   W;
15017
15018   /* NOTREACHED */
15019   return 0;
15020 }
15021
15022 static int
15023 api_netmap_create (vat_main_t * vam)
15024 {
15025   unformat_input_t *i = vam->input;
15026   vl_api_netmap_create_t *mp;
15027   f64 timeout;
15028   u8 *if_name = 0;
15029   u8 hw_addr[6];
15030   u8 random_hw_addr = 1;
15031   u8 is_pipe = 0;
15032   u8 is_master = 0;
15033
15034   memset (hw_addr, 0, sizeof (hw_addr));
15035
15036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15037     {
15038       if (unformat (i, "name %s", &if_name))
15039         vec_add1 (if_name, 0);
15040       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15041         random_hw_addr = 0;
15042       else if (unformat (i, "pipe"))
15043         is_pipe = 1;
15044       else if (unformat (i, "master"))
15045         is_master = 1;
15046       else if (unformat (i, "slave"))
15047         is_master = 0;
15048       else
15049         break;
15050     }
15051
15052   if (!vec_len (if_name))
15053     {
15054       errmsg ("interface name must be specified");
15055       return -99;
15056     }
15057
15058   if (vec_len (if_name) > 64)
15059     {
15060       errmsg ("interface name too long");
15061       return -99;
15062     }
15063
15064   M (NETMAP_CREATE, netmap_create);
15065
15066   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15067   clib_memcpy (mp->hw_addr, hw_addr, 6);
15068   mp->use_random_hw_addr = random_hw_addr;
15069   mp->is_pipe = is_pipe;
15070   mp->is_master = is_master;
15071   vec_free (if_name);
15072
15073   S;
15074   W;
15075   /* NOTREACHED */
15076   return 0;
15077 }
15078
15079 static int
15080 api_netmap_delete (vat_main_t * vam)
15081 {
15082   unformat_input_t *i = vam->input;
15083   vl_api_netmap_delete_t *mp;
15084   f64 timeout;
15085   u8 *if_name = 0;
15086
15087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15088     {
15089       if (unformat (i, "name %s", &if_name))
15090         vec_add1 (if_name, 0);
15091       else
15092         break;
15093     }
15094
15095   if (!vec_len (if_name))
15096     {
15097       errmsg ("interface name must be specified");
15098       return -99;
15099     }
15100
15101   if (vec_len (if_name) > 64)
15102     {
15103       errmsg ("interface name too long");
15104       return -99;
15105     }
15106
15107   M (NETMAP_DELETE, netmap_delete);
15108
15109   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15110   vec_free (if_name);
15111
15112   S;
15113   W;
15114   /* NOTREACHED */
15115   return 0;
15116 }
15117
15118 static void vl_api_mpls_tunnel_details_t_handler
15119   (vl_api_mpls_tunnel_details_t * mp)
15120 {
15121   vat_main_t *vam = &vat_main;
15122   i32 len = mp->mt_next_hop_n_labels;
15123   i32 i;
15124
15125   fformat (vam->ofp, "[%d]: via %U %d labels ",
15126            mp->tunnel_index,
15127            format_ip4_address, mp->mt_next_hop,
15128            ntohl (mp->mt_next_hop_sw_if_index));
15129   for (i = 0; i < len; i++)
15130     {
15131       fformat (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15132     }
15133   fformat (vam->ofp, "\n");
15134 }
15135
15136 static void vl_api_mpls_tunnel_details_t_handler_json
15137   (vl_api_mpls_tunnel_details_t * mp)
15138 {
15139   vat_main_t *vam = &vat_main;
15140   vat_json_node_t *node = NULL;
15141   struct in_addr ip4;
15142   i32 i;
15143   i32 len = mp->mt_next_hop_n_labels;
15144
15145   if (VAT_JSON_ARRAY != vam->json_tree.type)
15146     {
15147       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15148       vat_json_init_array (&vam->json_tree);
15149     }
15150   node = vat_json_array_add (&vam->json_tree);
15151
15152   vat_json_init_object (node);
15153   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15154   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15155   vat_json_object_add_ip4 (node, "next_hop", ip4);
15156   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15157                             ntohl (mp->mt_next_hop_sw_if_index));
15158   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15159   vat_json_object_add_uint (node, "label_count", len);
15160   for (i = 0; i < len; i++)
15161     {
15162       vat_json_object_add_uint (node, "label",
15163                                 ntohl (mp->mt_next_hop_out_labels[i]));
15164     }
15165 }
15166
15167 static int
15168 api_mpls_tunnel_dump (vat_main_t * vam)
15169 {
15170   vl_api_mpls_tunnel_dump_t *mp;
15171   f64 timeout;
15172   i32 index = -1;
15173
15174   /* Parse args required to build the message */
15175   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15176     {
15177       if (!unformat (vam->input, "tunnel_index %d", &index))
15178         {
15179           index = -1;
15180           break;
15181         }
15182     }
15183
15184   fformat (vam->ofp, "  tunnel_index %d\n", index);
15185
15186   M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
15187   mp->tunnel_index = htonl (index);
15188   S;
15189
15190   /* Use a control ping for synchronization */
15191   {
15192     vl_api_control_ping_t *mp;
15193     M (CONTROL_PING, control_ping);
15194     S;
15195   }
15196   W;
15197 }
15198
15199 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15200 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15201
15202 static void
15203 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15204 {
15205   vat_main_t *vam = &vat_main;
15206   int count = ntohl (mp->count);
15207   vl_api_fib_path_t *fp;
15208   int i;
15209
15210   fformat (vam->ofp,
15211            "table-id %d, label %u, ess_bit %u\n",
15212            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15213   fp = mp->path;
15214   for (i = 0; i < count; i++)
15215     {
15216       if (fp->afi == IP46_TYPE_IP6)
15217         fformat (vam->ofp,
15218                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15219                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15220                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15221                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15222                  format_ip6_address, fp->next_hop);
15223       else if (fp->afi == IP46_TYPE_IP4)
15224         fformat (vam->ofp,
15225                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15226                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15227                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15228                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15229                  format_ip4_address, fp->next_hop);
15230       fp++;
15231     }
15232 }
15233
15234 static void vl_api_mpls_fib_details_t_handler_json
15235   (vl_api_mpls_fib_details_t * mp)
15236 {
15237   vat_main_t *vam = &vat_main;
15238   int count = ntohl (mp->count);
15239   vat_json_node_t *node = NULL;
15240   struct in_addr ip4;
15241   struct in6_addr ip6;
15242   vl_api_fib_path_t *fp;
15243   int i;
15244
15245   if (VAT_JSON_ARRAY != vam->json_tree.type)
15246     {
15247       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15248       vat_json_init_array (&vam->json_tree);
15249     }
15250   node = vat_json_array_add (&vam->json_tree);
15251
15252   vat_json_init_object (node);
15253   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15254   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15255   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15256   vat_json_object_add_uint (node, "path_count", count);
15257   fp = mp->path;
15258   for (i = 0; i < count; i++)
15259     {
15260       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15261       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15262       vat_json_object_add_uint (node, "is_local", fp->is_local);
15263       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15264       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15265       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15266       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15267       if (fp->afi == IP46_TYPE_IP4)
15268         {
15269           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15270           vat_json_object_add_ip4 (node, "next_hop", ip4);
15271         }
15272       else if (fp->afi == IP46_TYPE_IP6)
15273         {
15274           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15275           vat_json_object_add_ip6 (node, "next_hop", ip6);
15276         }
15277     }
15278 }
15279
15280 static int
15281 api_mpls_fib_dump (vat_main_t * vam)
15282 {
15283   vl_api_mpls_fib_dump_t *mp;
15284   f64 timeout;
15285
15286   M (MPLS_FIB_DUMP, mpls_fib_dump);
15287   S;
15288
15289   /* Use a control ping for synchronization */
15290   {
15291     vl_api_control_ping_t *mp;
15292     M (CONTROL_PING, control_ping);
15293     S;
15294   }
15295   W;
15296 }
15297
15298 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15299 #define vl_api_ip_fib_details_t_print vl_noop_handler
15300
15301 static void
15302 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15303 {
15304   vat_main_t *vam = &vat_main;
15305   int count = ntohl (mp->count);
15306   vl_api_fib_path_t *fp;
15307   int i;
15308
15309   fformat (vam->ofp,
15310            "table-id %d, prefix %U/%d\n",
15311            ntohl (mp->table_id), format_ip4_address, mp->address,
15312            mp->address_length);
15313   fp = mp->path;
15314   for (i = 0; i < count; i++)
15315     {
15316       if (fp->afi == IP46_TYPE_IP6)
15317         fformat (vam->ofp,
15318                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15319                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15320                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15321                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15322                  format_ip6_address, fp->next_hop);
15323       else if (fp->afi == IP46_TYPE_IP4)
15324         fformat (vam->ofp,
15325                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15326                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15327                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15328                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15329                  format_ip4_address, fp->next_hop);
15330       fp++;
15331     }
15332 }
15333
15334 static void vl_api_ip_fib_details_t_handler_json
15335   (vl_api_ip_fib_details_t * mp)
15336 {
15337   vat_main_t *vam = &vat_main;
15338   int count = ntohl (mp->count);
15339   vat_json_node_t *node = NULL;
15340   struct in_addr ip4;
15341   struct in6_addr ip6;
15342   vl_api_fib_path_t *fp;
15343   int i;
15344
15345   if (VAT_JSON_ARRAY != vam->json_tree.type)
15346     {
15347       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15348       vat_json_init_array (&vam->json_tree);
15349     }
15350   node = vat_json_array_add (&vam->json_tree);
15351
15352   vat_json_init_object (node);
15353   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15354   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15355   vat_json_object_add_ip4 (node, "prefix", ip4);
15356   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15357   vat_json_object_add_uint (node, "path_count", count);
15358   fp = mp->path;
15359   for (i = 0; i < count; i++)
15360     {
15361       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15362       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15363       vat_json_object_add_uint (node, "is_local", fp->is_local);
15364       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15365       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15366       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15367       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15368       if (fp->afi == IP46_TYPE_IP4)
15369         {
15370           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15371           vat_json_object_add_ip4 (node, "next_hop", ip4);
15372         }
15373       else if (fp->afi == IP46_TYPE_IP6)
15374         {
15375           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15376           vat_json_object_add_ip6 (node, "next_hop", ip6);
15377         }
15378     }
15379 }
15380
15381 static int
15382 api_ip_fib_dump (vat_main_t * vam)
15383 {
15384   vl_api_ip_fib_dump_t *mp;
15385   f64 timeout;
15386
15387   M (IP_FIB_DUMP, ip_fib_dump);
15388   S;
15389
15390   /* Use a control ping for synchronization */
15391   {
15392     vl_api_control_ping_t *mp;
15393     M (CONTROL_PING, control_ping);
15394     S;
15395   }
15396   W;
15397 }
15398
15399 static void vl_api_ip_neighbor_details_t_handler
15400   (vl_api_ip_neighbor_details_t * mp)
15401 {
15402   vat_main_t *vam = &vat_main;
15403
15404   fformat (vam->ofp, "%c %U %U\n",
15405            (mp->is_static) ? 'S' : 'D',
15406            format_ethernet_address, &mp->mac_address,
15407            (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15408            &mp->ip_address);
15409 }
15410
15411 static void vl_api_ip_neighbor_details_t_handler_json
15412   (vl_api_ip_neighbor_details_t * mp)
15413 {
15414
15415   vat_main_t *vam = &vat_main;
15416   vat_json_node_t *node;
15417   struct in_addr ip4;
15418   struct in6_addr ip6;
15419
15420   if (VAT_JSON_ARRAY != vam->json_tree.type)
15421     {
15422       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15423       vat_json_init_array (&vam->json_tree);
15424     }
15425   node = vat_json_array_add (&vam->json_tree);
15426
15427   vat_json_init_object (node);
15428   vat_json_object_add_string_copy (node, "flag",
15429                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15430                                    "dynamic");
15431
15432   vat_json_object_add_string_copy (node, "link_layer",
15433                                    format (0, "%U", format_ethernet_address,
15434                                            &mp->mac_address));
15435
15436   if (mp->is_ipv6)
15437     {
15438       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15439       vat_json_object_add_ip6 (node, "ip_address", ip6);
15440     }
15441   else
15442     {
15443       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15444       vat_json_object_add_ip4 (node, "ip_address", ip4);
15445     }
15446 }
15447
15448 static int
15449 api_ip_neighbor_dump (vat_main_t * vam)
15450 {
15451   unformat_input_t *i = vam->input;
15452   vl_api_ip_neighbor_dump_t *mp;
15453   f64 timeout;
15454   u8 is_ipv6 = 0;
15455   u32 sw_if_index = ~0;
15456
15457   /* Parse args required to build the message */
15458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15459     {
15460       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15461         ;
15462       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15463         ;
15464       else if (unformat (i, "ip6"))
15465         is_ipv6 = 1;
15466       else
15467         break;
15468     }
15469
15470   if (sw_if_index == ~0)
15471     {
15472       errmsg ("missing interface name or sw_if_index\n");
15473       return -99;
15474     }
15475
15476   M (IP_NEIGHBOR_DUMP, ip_neighbor_dump);
15477   mp->is_ipv6 = (u8) is_ipv6;
15478   mp->sw_if_index = ntohl (sw_if_index);
15479   S;
15480
15481   /* Use a control ping for synchronization */
15482   {
15483     vl_api_control_ping_t *mp;
15484     M (CONTROL_PING, control_ping);
15485     S;
15486   }
15487   W;
15488 }
15489
15490 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15491 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15492
15493 static void
15494 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15495 {
15496   vat_main_t *vam = &vat_main;
15497   int count = ntohl (mp->count);
15498   vl_api_fib_path_t *fp;
15499   int i;
15500
15501   fformat (vam->ofp,
15502            "table-id %d, prefix %U/%d\n",
15503            ntohl (mp->table_id), format_ip6_address, mp->address,
15504            mp->address_length);
15505   fp = mp->path;
15506   for (i = 0; i < count; i++)
15507     {
15508       if (fp->afi == IP46_TYPE_IP6)
15509         fformat (vam->ofp,
15510                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15511                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15512                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15513                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15514                  format_ip6_address, fp->next_hop);
15515       else if (fp->afi == IP46_TYPE_IP4)
15516         fformat (vam->ofp,
15517                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15518                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15519                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15520                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15521                  format_ip4_address, fp->next_hop);
15522       fp++;
15523     }
15524 }
15525
15526 static void vl_api_ip6_fib_details_t_handler_json
15527   (vl_api_ip6_fib_details_t * mp)
15528 {
15529   vat_main_t *vam = &vat_main;
15530   int count = ntohl (mp->count);
15531   vat_json_node_t *node = NULL;
15532   struct in_addr ip4;
15533   struct in6_addr ip6;
15534   vl_api_fib_path_t *fp;
15535   int i;
15536
15537   if (VAT_JSON_ARRAY != vam->json_tree.type)
15538     {
15539       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15540       vat_json_init_array (&vam->json_tree);
15541     }
15542   node = vat_json_array_add (&vam->json_tree);
15543
15544   vat_json_init_object (node);
15545   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15546   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15547   vat_json_object_add_ip6 (node, "prefix", ip6);
15548   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15549   vat_json_object_add_uint (node, "path_count", count);
15550   fp = mp->path;
15551   for (i = 0; i < count; i++)
15552     {
15553       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15554       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15555       vat_json_object_add_uint (node, "is_local", fp->is_local);
15556       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15557       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15558       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15559       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15560       if (fp->afi == IP46_TYPE_IP4)
15561         {
15562           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15563           vat_json_object_add_ip4 (node, "next_hop", ip4);
15564         }
15565       else if (fp->afi == IP46_TYPE_IP6)
15566         {
15567           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15568           vat_json_object_add_ip6 (node, "next_hop", ip6);
15569         }
15570     }
15571 }
15572
15573 static int
15574 api_ip6_fib_dump (vat_main_t * vam)
15575 {
15576   vl_api_ip6_fib_dump_t *mp;
15577   f64 timeout;
15578
15579   M (IP6_FIB_DUMP, ip6_fib_dump);
15580   S;
15581
15582   /* Use a control ping for synchronization */
15583   {
15584     vl_api_control_ping_t *mp;
15585     M (CONTROL_PING, control_ping);
15586     S;
15587   }
15588   W;
15589 }
15590
15591 int
15592 api_classify_table_ids (vat_main_t * vam)
15593 {
15594   vl_api_classify_table_ids_t *mp;
15595   f64 timeout;
15596
15597   /* Construct the API message */
15598   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15599   mp->context = 0;
15600
15601   S;
15602   W;
15603   /* NOTREACHED */
15604   return 0;
15605 }
15606
15607 int
15608 api_classify_table_by_interface (vat_main_t * vam)
15609 {
15610   unformat_input_t *input = vam->input;
15611   vl_api_classify_table_by_interface_t *mp;
15612   f64 timeout;
15613
15614   u32 sw_if_index = ~0;
15615   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15616     {
15617       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15618         ;
15619       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15620         ;
15621       else
15622         break;
15623     }
15624   if (sw_if_index == ~0)
15625     {
15626       errmsg ("missing interface name or sw_if_index\n");
15627       return -99;
15628     }
15629
15630   /* Construct the API message */
15631   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15632   mp->context = 0;
15633   mp->sw_if_index = ntohl (sw_if_index);
15634
15635   S;
15636   W;
15637   /* NOTREACHED */
15638   return 0;
15639 }
15640
15641 int
15642 api_classify_table_info (vat_main_t * vam)
15643 {
15644   unformat_input_t *input = vam->input;
15645   vl_api_classify_table_info_t *mp;
15646   f64 timeout;
15647
15648   u32 table_id = ~0;
15649   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15650     {
15651       if (unformat (input, "table_id %d", &table_id))
15652         ;
15653       else
15654         break;
15655     }
15656   if (table_id == ~0)
15657     {
15658       errmsg ("missing table id\n");
15659       return -99;
15660     }
15661
15662   /* Construct the API message */
15663   M (CLASSIFY_TABLE_INFO, classify_table_info);
15664   mp->context = 0;
15665   mp->table_id = ntohl (table_id);
15666
15667   S;
15668   W;
15669   /* NOTREACHED */
15670   return 0;
15671 }
15672
15673 int
15674 api_classify_session_dump (vat_main_t * vam)
15675 {
15676   unformat_input_t *input = vam->input;
15677   vl_api_classify_session_dump_t *mp;
15678   f64 timeout;
15679
15680   u32 table_id = ~0;
15681   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15682     {
15683       if (unformat (input, "table_id %d", &table_id))
15684         ;
15685       else
15686         break;
15687     }
15688   if (table_id == ~0)
15689     {
15690       errmsg ("missing table id\n");
15691       return -99;
15692     }
15693
15694   /* Construct the API message */
15695   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15696   mp->context = 0;
15697   mp->table_id = ntohl (table_id);
15698   S;
15699
15700   /* Use a control ping for synchronization */
15701   {
15702     vl_api_control_ping_t *mp;
15703     M (CONTROL_PING, control_ping);
15704     S;
15705   }
15706   W;
15707   /* NOTREACHED */
15708   return 0;
15709 }
15710
15711 static void
15712 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15713 {
15714   vat_main_t *vam = &vat_main;
15715
15716   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15717            "src_address %U, vrf_id %d, path_mtu %u, "
15718            "template_interval %u, udp_checksum %d\n",
15719            format_ip4_address, mp->collector_address,
15720            ntohs (mp->collector_port),
15721            format_ip4_address, mp->src_address,
15722            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15723            ntohl (mp->template_interval), mp->udp_checksum);
15724
15725   vam->retval = 0;
15726   vam->result_ready = 1;
15727 }
15728
15729 static void
15730   vl_api_ipfix_exporter_details_t_handler_json
15731   (vl_api_ipfix_exporter_details_t * mp)
15732 {
15733   vat_main_t *vam = &vat_main;
15734   vat_json_node_t node;
15735   struct in_addr collector_address;
15736   struct in_addr src_address;
15737
15738   vat_json_init_object (&node);
15739   clib_memcpy (&collector_address, &mp->collector_address,
15740                sizeof (collector_address));
15741   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15742   vat_json_object_add_uint (&node, "collector_port",
15743                             ntohs (mp->collector_port));
15744   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15745   vat_json_object_add_ip4 (&node, "src_address", src_address);
15746   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15747   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15748   vat_json_object_add_uint (&node, "template_interval",
15749                             ntohl (mp->template_interval));
15750   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15751
15752   vat_json_print (vam->ofp, &node);
15753   vat_json_free (&node);
15754   vam->retval = 0;
15755   vam->result_ready = 1;
15756 }
15757
15758 int
15759 api_ipfix_exporter_dump (vat_main_t * vam)
15760 {
15761   vl_api_ipfix_exporter_dump_t *mp;
15762   f64 timeout;
15763
15764   /* Construct the API message */
15765   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15766   mp->context = 0;
15767
15768   S;
15769   W;
15770   /* NOTREACHED */
15771   return 0;
15772 }
15773
15774 static int
15775 api_ipfix_classify_stream_dump (vat_main_t * vam)
15776 {
15777   vl_api_ipfix_classify_stream_dump_t *mp;
15778   f64 timeout;
15779
15780   /* Construct the API message */
15781   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15782   mp->context = 0;
15783
15784   S;
15785   W;
15786   /* NOTREACHED */
15787   return 0;
15788 }
15789
15790 static void
15791   vl_api_ipfix_classify_stream_details_t_handler
15792   (vl_api_ipfix_classify_stream_details_t * mp)
15793 {
15794   vat_main_t *vam = &vat_main;
15795   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15796            ntohl (mp->domain_id), ntohs (mp->src_port));
15797   vam->retval = 0;
15798   vam->result_ready = 1;
15799 }
15800
15801 static void
15802   vl_api_ipfix_classify_stream_details_t_handler_json
15803   (vl_api_ipfix_classify_stream_details_t * mp)
15804 {
15805   vat_main_t *vam = &vat_main;
15806   vat_json_node_t node;
15807
15808   vat_json_init_object (&node);
15809   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15810   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15811
15812   vat_json_print (vam->ofp, &node);
15813   vat_json_free (&node);
15814   vam->retval = 0;
15815   vam->result_ready = 1;
15816 }
15817
15818 static int
15819 api_ipfix_classify_table_dump (vat_main_t * vam)
15820 {
15821   vl_api_ipfix_classify_table_dump_t *mp;
15822   f64 timeout;
15823
15824   if (!vam->json_output)
15825     {
15826       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15827                "transport_protocol");
15828     }
15829
15830   /* Construct the API message */
15831   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15832
15833   /* send it... */
15834   S;
15835
15836   /* Use a control ping for synchronization */
15837   {
15838     vl_api_control_ping_t *mp;
15839     M (CONTROL_PING, control_ping);
15840     S;
15841   }
15842   W;
15843 }
15844
15845 static void
15846   vl_api_ipfix_classify_table_details_t_handler
15847   (vl_api_ipfix_classify_table_details_t * mp)
15848 {
15849   vat_main_t *vam = &vat_main;
15850   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15851            mp->transport_protocol);
15852 }
15853
15854 static void
15855   vl_api_ipfix_classify_table_details_t_handler_json
15856   (vl_api_ipfix_classify_table_details_t * mp)
15857 {
15858   vat_json_node_t *node = NULL;
15859   vat_main_t *vam = &vat_main;
15860
15861   if (VAT_JSON_ARRAY != vam->json_tree.type)
15862     {
15863       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15864       vat_json_init_array (&vam->json_tree);
15865     }
15866
15867   node = vat_json_array_add (&vam->json_tree);
15868   vat_json_init_object (node);
15869
15870   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15871   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15872   vat_json_object_add_uint (node, "transport_protocol",
15873                             mp->transport_protocol);
15874 }
15875
15876 static int
15877 api_sw_interface_span_enable_disable (vat_main_t * vam)
15878 {
15879   unformat_input_t *i = vam->input;
15880   vl_api_sw_interface_span_enable_disable_t *mp;
15881   f64 timeout;
15882   u32 src_sw_if_index = ~0;
15883   u32 dst_sw_if_index = ~0;
15884   u8 enable = 1;
15885
15886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15887     {
15888       if (unformat (i, "src %U", unformat_sw_if_index, vam, &src_sw_if_index))
15889         ;
15890       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15891         ;
15892       else
15893         if (unformat
15894             (i, "dst %U", unformat_sw_if_index, vam, &dst_sw_if_index))
15895         ;
15896       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15897         ;
15898       else if (unformat (i, "disable"))
15899         enable = 0;
15900       else
15901         break;
15902     }
15903
15904   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
15905
15906   mp->sw_if_index_from = htonl (src_sw_if_index);
15907   mp->sw_if_index_to = htonl (dst_sw_if_index);
15908   mp->enable = enable;
15909
15910   S;
15911   W;
15912   /* NOTREACHED */
15913   return 0;
15914 }
15915
15916 static void
15917 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
15918                                             * mp)
15919 {
15920   vat_main_t *vam = &vat_main;
15921
15922   fformat (vam->ofp, "%u => %u\n",
15923            ntohl (mp->sw_if_index_from), ntohl (mp->sw_if_index_to));
15924 }
15925
15926 static void
15927   vl_api_sw_interface_span_details_t_handler_json
15928   (vl_api_sw_interface_span_details_t * mp)
15929 {
15930   vat_main_t *vam = &vat_main;
15931   vat_json_node_t *node = NULL;
15932
15933   if (VAT_JSON_ARRAY != vam->json_tree.type)
15934     {
15935       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15936       vat_json_init_array (&vam->json_tree);
15937     }
15938   node = vat_json_array_add (&vam->json_tree);
15939
15940   vat_json_init_object (node);
15941   vat_json_object_add_uint (node, "src-if-index",
15942                             ntohl (mp->sw_if_index_from));
15943   vat_json_object_add_uint (node, "dst-if-index", ntohl (mp->sw_if_index_to));
15944 }
15945
15946 static int
15947 api_sw_interface_span_dump (vat_main_t * vam)
15948 {
15949   vl_api_sw_interface_span_dump_t *mp;
15950   f64 timeout;
15951
15952   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
15953   S;
15954
15955   /* Use a control ping for synchronization */
15956   {
15957     vl_api_control_ping_t *mp;
15958     M (CONTROL_PING, control_ping);
15959     S;
15960   }
15961   W;
15962 }
15963
15964 int
15965 api_pg_create_interface (vat_main_t * vam)
15966 {
15967   unformat_input_t *input = vam->input;
15968   vl_api_pg_create_interface_t *mp;
15969   f64 timeout;
15970
15971   u32 if_id = ~0;
15972   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15973     {
15974       if (unformat (input, "if_id %d", &if_id))
15975         ;
15976       else
15977         break;
15978     }
15979   if (if_id == ~0)
15980     {
15981       errmsg ("missing pg interface index\n");
15982       return -99;
15983     }
15984
15985   /* Construct the API message */
15986   M (PG_CREATE_INTERFACE, pg_create_interface);
15987   mp->context = 0;
15988   mp->interface_id = ntohl (if_id);
15989
15990   S;
15991   W;
15992   /* NOTREACHED */
15993   return 0;
15994 }
15995
15996 int
15997 api_pg_capture (vat_main_t * vam)
15998 {
15999   unformat_input_t *input = vam->input;
16000   vl_api_pg_capture_t *mp;
16001   f64 timeout;
16002
16003   u32 if_id = ~0;
16004   u8 enable = 1;
16005   u32 count = 1;
16006   u8 pcap_file_set = 0;
16007   u8 *pcap_file = 0;
16008   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16009     {
16010       if (unformat (input, "if_id %d", &if_id))
16011         ;
16012       else if (unformat (input, "pcap %s", &pcap_file))
16013         pcap_file_set = 1;
16014       else if (unformat (input, "count %d", &count))
16015         ;
16016       else if (unformat (input, "disable"))
16017         enable = 0;
16018       else
16019         break;
16020     }
16021   if (if_id == ~0)
16022     {
16023       errmsg ("missing pg interface index\n");
16024       return -99;
16025     }
16026   if (pcap_file_set > 0)
16027     {
16028       if (vec_len (pcap_file) > 255)
16029         {
16030           errmsg ("pcap file name is too long\n");
16031           return -99;
16032         }
16033     }
16034
16035   u32 name_len = vec_len (pcap_file);
16036   /* Construct the API message */
16037   M (PG_CAPTURE, pg_capture);
16038   mp->context = 0;
16039   mp->interface_id = ntohl (if_id);
16040   mp->is_enabled = enable;
16041   mp->count = ntohl (count);
16042   mp->pcap_name_length = ntohl (name_len);
16043   if (pcap_file_set != 0)
16044     {
16045       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16046     }
16047   vec_free (pcap_file);
16048
16049   S;
16050   W;
16051   /* NOTREACHED */
16052   return 0;
16053 }
16054
16055 int
16056 api_pg_enable_disable (vat_main_t * vam)
16057 {
16058   unformat_input_t *input = vam->input;
16059   vl_api_pg_enable_disable_t *mp;
16060   f64 timeout;
16061
16062   u8 enable = 1;
16063   u8 stream_name_set = 0;
16064   u8 *stream_name = 0;
16065   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16066     {
16067       if (unformat (input, "stream %s", &stream_name))
16068         stream_name_set = 1;
16069       else if (unformat (input, "disable"))
16070         enable = 0;
16071       else
16072         break;
16073     }
16074
16075   if (stream_name_set > 0)
16076     {
16077       if (vec_len (stream_name) > 255)
16078         {
16079           errmsg ("stream name too long\n");
16080           return -99;
16081         }
16082     }
16083
16084   u32 name_len = vec_len (stream_name);
16085   /* Construct the API message */
16086   M (PG_ENABLE_DISABLE, pg_enable_disable);
16087   mp->context = 0;
16088   mp->is_enabled = enable;
16089   if (stream_name_set != 0)
16090     {
16091       mp->stream_name_length = ntohl (name_len);
16092       clib_memcpy (mp->stream_name, stream_name, name_len);
16093     }
16094   vec_free (stream_name);
16095
16096   S;
16097   W;
16098   /* NOTREACHED */
16099   return 0;
16100 }
16101
16102 int
16103 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16104 {
16105   unformat_input_t *input = vam->input;
16106   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16107   f64 timeout;
16108
16109   u16 *low_ports = 0;
16110   u16 *high_ports = 0;
16111   u16 this_low;
16112   u16 this_hi;
16113   ip4_address_t ip4_addr;
16114   ip6_address_t ip6_addr;
16115   u32 length;
16116   u32 tmp, tmp2;
16117   u8 prefix_set = 0;
16118   u32 vrf_id = ~0;
16119   u8 is_add = 1;
16120   u8 is_ipv6 = 0;
16121
16122   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16123     {
16124       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16125         {
16126           prefix_set = 1;
16127         }
16128       else
16129         if (unformat
16130             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16131         {
16132           prefix_set = 1;
16133           is_ipv6 = 1;
16134         }
16135       else if (unformat (input, "vrf %d", &vrf_id))
16136         ;
16137       else if (unformat (input, "del"))
16138         is_add = 0;
16139       else if (unformat (input, "port %d", &tmp))
16140         {
16141           if (tmp == 0 || tmp > 65535)
16142             {
16143               errmsg ("port %d out of range", tmp);
16144               return -99;
16145             }
16146           this_low = tmp;
16147           this_hi = this_low + 1;
16148           vec_add1 (low_ports, this_low);
16149           vec_add1 (high_ports, this_hi);
16150         }
16151       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16152         {
16153           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16154             {
16155               errmsg ("incorrect range parameters\n");
16156               return -99;
16157             }
16158           this_low = tmp;
16159           /* Note: in debug CLI +1 is added to high before
16160              passing to real fn that does "the work"
16161              (ip_source_and_port_range_check_add_del).
16162              This fn is a wrapper around the binary API fn a
16163              control plane will call, which expects this increment
16164              to have occurred. Hence letting the binary API control
16165              plane fn do the increment for consistency between VAT
16166              and other control planes.
16167            */
16168           this_hi = tmp2;
16169           vec_add1 (low_ports, this_low);
16170           vec_add1 (high_ports, this_hi);
16171         }
16172       else
16173         break;
16174     }
16175
16176   if (prefix_set == 0)
16177     {
16178       errmsg ("<address>/<mask> not specified\n");
16179       return -99;
16180     }
16181
16182   if (vrf_id == ~0)
16183     {
16184       errmsg ("VRF ID required, not specified\n");
16185       return -99;
16186     }
16187
16188   if (vrf_id == 0)
16189     {
16190       errmsg
16191         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
16192       return -99;
16193     }
16194
16195   if (vec_len (low_ports) == 0)
16196     {
16197       errmsg ("At least one port or port range required\n");
16198       return -99;
16199     }
16200
16201   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
16202      ip_source_and_port_range_check_add_del);
16203
16204   mp->is_add = is_add;
16205
16206   if (is_ipv6)
16207     {
16208       mp->is_ipv6 = 1;
16209       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16210     }
16211   else
16212     {
16213       mp->is_ipv6 = 0;
16214       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16215     }
16216
16217   mp->mask_length = length;
16218   mp->number_of_ranges = vec_len (low_ports);
16219
16220   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16221   vec_free (low_ports);
16222
16223   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16224   vec_free (high_ports);
16225
16226   mp->vrf_id = ntohl (vrf_id);
16227
16228   S;
16229   W;
16230   /* NOTREACHED */
16231   return 0;
16232 }
16233
16234 int
16235 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16236 {
16237   unformat_input_t *input = vam->input;
16238   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16239   f64 timeout;
16240   u32 sw_if_index = ~0;
16241   int vrf_set = 0;
16242   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16243   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16244   u8 is_add = 1;
16245
16246   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16247     {
16248       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
16249         ;
16250       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16251         ;
16252       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16253         vrf_set = 1;
16254       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16255         vrf_set = 1;
16256       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16257         vrf_set = 1;
16258       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16259         vrf_set = 1;
16260       else if (unformat (input, "del"))
16261         is_add = 0;
16262       else
16263         break;
16264     }
16265
16266   if (sw_if_index == ~0)
16267     {
16268       errmsg ("Interface required but not specified\n");
16269       return -99;
16270     }
16271
16272   if (vrf_set == 0)
16273     {
16274       errmsg ("VRF ID required but not specified\n");
16275       return -99;
16276     }
16277
16278   if (tcp_out_vrf_id == 0
16279       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16280     {
16281       errmsg
16282         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
16283       return -99;
16284     }
16285
16286   /* Construct the API message */
16287   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
16288      ip_source_and_port_range_check_interface_add_del);
16289
16290   mp->sw_if_index = ntohl (sw_if_index);
16291   mp->is_add = is_add;
16292   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16293   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16294   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16295   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16296
16297   /* send it... */
16298   S;
16299
16300   /* Wait for a reply... */
16301   W;
16302 }
16303
16304 static int
16305 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16306 {
16307   unformat_input_t *i = vam->input;
16308   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16309   f64 timeout;
16310   u32 local_sa_id = 0;
16311   u32 remote_sa_id = 0;
16312   ip4_address_t src_address;
16313   ip4_address_t dst_address;
16314   u8 is_add = 1;
16315
16316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16317     {
16318       if (unformat (i, "local_sa %d", &local_sa_id))
16319         ;
16320       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16321         ;
16322       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16323         ;
16324       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16325         ;
16326       else if (unformat (i, "del"))
16327         is_add = 0;
16328       else
16329         {
16330           clib_warning ("parse error '%U'", format_unformat_error, i);
16331           return -99;
16332         }
16333     }
16334
16335   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
16336
16337   mp->local_sa_id = ntohl (local_sa_id);
16338   mp->remote_sa_id = ntohl (remote_sa_id);
16339   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16340   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16341   mp->is_add = is_add;
16342
16343   S;
16344   W;
16345   /* NOTREACHED */
16346   return 0;
16347 }
16348
16349 static int
16350 api_punt (vat_main_t * vam)
16351 {
16352   unformat_input_t *i = vam->input;
16353   vl_api_punt_t *mp;
16354   f64 timeout;
16355   u32 ipv = ~0;
16356   u32 protocol = ~0;
16357   u32 port = ~0;
16358   int is_add = 1;
16359
16360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16361     {
16362       if (unformat (i, "ip %d", &ipv))
16363         ;
16364       else if (unformat (i, "protocol %d", &protocol))
16365         ;
16366       else if (unformat (i, "port %d", &port))
16367         ;
16368       else if (unformat (i, "del"))
16369         is_add = 0;
16370       else
16371         {
16372           clib_warning ("parse error '%U'", format_unformat_error, i);
16373           return -99;
16374         }
16375     }
16376
16377   M (PUNT, punt);
16378
16379   mp->is_add = (u8) is_add;
16380   mp->ipv = (u8) ipv;
16381   mp->l4_protocol = (u8) protocol;
16382   mp->l4_port = htons ((u16) port);
16383
16384   S;
16385   W;
16386   /* NOTREACHED */
16387   return 0;
16388 }
16389
16390 static void vl_api_ipsec_gre_tunnel_details_t_handler
16391   (vl_api_ipsec_gre_tunnel_details_t * mp)
16392 {
16393   vat_main_t *vam = &vat_main;
16394
16395   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
16396            ntohl (mp->sw_if_index),
16397            format_ip4_address, &mp->src_address,
16398            format_ip4_address, &mp->dst_address,
16399            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16400 }
16401
16402 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16403   (vl_api_ipsec_gre_tunnel_details_t * mp)
16404 {
16405   vat_main_t *vam = &vat_main;
16406   vat_json_node_t *node = NULL;
16407   struct in_addr ip4;
16408
16409   if (VAT_JSON_ARRAY != vam->json_tree.type)
16410     {
16411       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16412       vat_json_init_array (&vam->json_tree);
16413     }
16414   node = vat_json_array_add (&vam->json_tree);
16415
16416   vat_json_init_object (node);
16417   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16418   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16419   vat_json_object_add_ip4 (node, "src_address", ip4);
16420   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16421   vat_json_object_add_ip4 (node, "dst_address", ip4);
16422   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16423   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16424 }
16425
16426 static int
16427 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16428 {
16429   unformat_input_t *i = vam->input;
16430   vl_api_ipsec_gre_tunnel_dump_t *mp;
16431   f64 timeout;
16432   u32 sw_if_index;
16433   u8 sw_if_index_set = 0;
16434
16435   /* Parse args required to build the message */
16436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16437     {
16438       if (unformat (i, "sw_if_index %d", &sw_if_index))
16439         sw_if_index_set = 1;
16440       else
16441         break;
16442     }
16443
16444   if (sw_if_index_set == 0)
16445     {
16446       sw_if_index = ~0;
16447     }
16448
16449   if (!vam->json_output)
16450     {
16451       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
16452                "sw_if_index", "src_address", "dst_address",
16453                "local_sa_id", "remote_sa_id");
16454     }
16455
16456   /* Get list of gre-tunnel interfaces */
16457   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16458
16459   mp->sw_if_index = htonl (sw_if_index);
16460
16461   S;
16462
16463   /* Use a control ping for synchronization */
16464   {
16465     vl_api_control_ping_t *mp;
16466     M (CONTROL_PING, control_ping);
16467     S;
16468   }
16469   W;
16470 }
16471
16472 static int
16473 api_delete_subif (vat_main_t * vam)
16474 {
16475   unformat_input_t *i = vam->input;
16476   vl_api_delete_subif_t *mp;
16477   f64 timeout;
16478   u32 sw_if_index = ~0;
16479
16480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16481     {
16482       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16483         ;
16484       if (unformat (i, "sw_if_index %d", &sw_if_index))
16485         ;
16486       else
16487         break;
16488     }
16489
16490   if (sw_if_index == ~0)
16491     {
16492       errmsg ("missing sw_if_index\n");
16493       return -99;
16494     }
16495
16496   /* Construct the API message */
16497   M (DELETE_SUBIF, delete_subif);
16498   mp->sw_if_index = ntohl (sw_if_index);
16499
16500   S;
16501   W;
16502 }
16503
16504 #define foreach_pbb_vtr_op      \
16505 _("disable",  L2_VTR_DISABLED)  \
16506 _("pop",  L2_VTR_POP_2)         \
16507 _("push",  L2_VTR_PUSH_2)
16508
16509 static int
16510 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16511 {
16512   unformat_input_t *i = vam->input;
16513   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16514   f64 timeout;
16515   u32 sw_if_index = ~0, vtr_op = ~0;
16516   u16 outer_tag = ~0;
16517   u8 dmac[6], smac[6];
16518   u8 dmac_set = 0, smac_set = 0;
16519   u16 vlanid = 0;
16520   u32 sid = ~0;
16521   u32 tmp;
16522
16523   /* Shut up coverity */
16524   memset (dmac, 0, sizeof (dmac));
16525   memset (smac, 0, sizeof (smac));
16526
16527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16528     {
16529       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16530         ;
16531       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16532         ;
16533       else if (unformat (i, "vtr_op %d", &vtr_op))
16534         ;
16535 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16536       foreach_pbb_vtr_op
16537 #undef _
16538         else if (unformat (i, "translate_pbb_stag"))
16539         {
16540           if (unformat (i, "%d", &tmp))
16541             {
16542               vtr_op = L2_VTR_TRANSLATE_2_1;
16543               outer_tag = tmp;
16544             }
16545           else
16546             {
16547               errmsg
16548                 ("translate_pbb_stag operation requires outer tag definition\n");
16549               return -99;
16550             }
16551         }
16552       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16553         dmac_set++;
16554       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16555         smac_set++;
16556       else if (unformat (i, "sid %d", &sid))
16557         ;
16558       else if (unformat (i, "vlanid %d", &tmp))
16559         vlanid = tmp;
16560       else
16561         {
16562           clib_warning ("parse error '%U'", format_unformat_error, i);
16563           return -99;
16564         }
16565     }
16566
16567   if ((sw_if_index == ~0) || (vtr_op == ~0))
16568     {
16569       errmsg ("missing sw_if_index or vtr operation\n");
16570       return -99;
16571     }
16572   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16573       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16574     {
16575       errmsg
16576         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
16577       return -99;
16578     }
16579
16580   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16581   mp->sw_if_index = ntohl (sw_if_index);
16582   mp->vtr_op = ntohl (vtr_op);
16583   mp->outer_tag = ntohs (outer_tag);
16584   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16585   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16586   mp->b_vlanid = ntohs (vlanid);
16587   mp->i_sid = ntohl (sid);
16588
16589   S;
16590   W;
16591   /* NOTREACHED */
16592   return 0;
16593 }
16594
16595 static int
16596 api_flow_classify_set_interface (vat_main_t * vam)
16597 {
16598   unformat_input_t *i = vam->input;
16599   vl_api_flow_classify_set_interface_t *mp;
16600   f64 timeout;
16601   u32 sw_if_index;
16602   int sw_if_index_set;
16603   u32 ip4_table_index = ~0;
16604   u32 ip6_table_index = ~0;
16605   u8 is_add = 1;
16606
16607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16608     {
16609       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16610         sw_if_index_set = 1;
16611       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16612         sw_if_index_set = 1;
16613       else if (unformat (i, "del"))
16614         is_add = 0;
16615       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16616         ;
16617       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16618         ;
16619       else
16620         {
16621           clib_warning ("parse error '%U'", format_unformat_error, i);
16622           return -99;
16623         }
16624     }
16625
16626   if (sw_if_index_set == 0)
16627     {
16628       errmsg ("missing interface name or sw_if_index\n");
16629       return -99;
16630     }
16631
16632   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16633
16634   mp->sw_if_index = ntohl (sw_if_index);
16635   mp->ip4_table_index = ntohl (ip4_table_index);
16636   mp->ip6_table_index = ntohl (ip6_table_index);
16637   mp->is_add = is_add;
16638
16639   S;
16640   W;
16641   /* NOTREACHED */
16642   return 0;
16643 }
16644
16645 static int
16646 api_flow_classify_dump (vat_main_t * vam)
16647 {
16648   unformat_input_t *i = vam->input;
16649   vl_api_flow_classify_dump_t *mp;
16650   f64 timeout = ~0;
16651   u8 type = FLOW_CLASSIFY_N_TABLES;
16652
16653   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16654     ;
16655   else
16656     {
16657       errmsg ("classify table type must be specified\n");
16658       return -99;
16659     }
16660
16661   if (!vam->json_output)
16662     {
16663       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
16664     }
16665
16666   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16667   mp->type = type;
16668   /* send it... */
16669   S;
16670
16671   /* Use a control ping for synchronization */
16672   {
16673     vl_api_control_ping_t *mp;
16674     M (CONTROL_PING, control_ping);
16675     S;
16676   }
16677   /* Wait for a reply... */
16678   W;
16679
16680   /* NOTREACHED */
16681   return 0;
16682 }
16683
16684 static int
16685 api_feature_enable_disable (vat_main_t * vam)
16686 {
16687   unformat_input_t *i = vam->input;
16688   vl_api_feature_enable_disable_t *mp;
16689   f64 timeout;
16690   u8 *arc_name = 0;
16691   u8 *feature_name = 0;
16692   u32 sw_if_index = ~0;
16693   u8 enable = 1;
16694
16695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16696     {
16697       if (unformat (i, "arc_name %s", &arc_name))
16698         ;
16699       else if (unformat (i, "feature_name %s", &feature_name))
16700         ;
16701       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16702         ;
16703       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16704         ;
16705       else if (unformat (i, "disable"))
16706         enable = 0;
16707       else
16708         break;
16709     }
16710
16711   if (arc_name == 0)
16712     {
16713       errmsg ("missing arc name\n");
16714       return -99;
16715     }
16716   if (vec_len (arc_name) > 63)
16717     {
16718       errmsg ("arc name too long\n");
16719     }
16720
16721   if (feature_name == 0)
16722     {
16723       errmsg ("missing feature name\n");
16724       return -99;
16725     }
16726   if (vec_len (feature_name) > 63)
16727     {
16728       errmsg ("feature name too long\n");
16729     }
16730
16731   if (sw_if_index == ~0)
16732     {
16733       errmsg ("missing interface name or sw_if_index\n");
16734       return -99;
16735     }
16736
16737   /* Construct the API message */
16738   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16739   mp->sw_if_index = ntohl (sw_if_index);
16740   mp->enable = enable;
16741   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16742   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16743   vec_free (arc_name);
16744   vec_free (feature_name);
16745
16746   S;
16747   W;
16748 }
16749
16750 static int
16751 api_sw_interface_tag_add_del (vat_main_t * vam)
16752 {
16753   unformat_input_t *i = vam->input;
16754   vl_api_sw_interface_tag_add_del_t *mp;
16755   f64 timeout;
16756   u32 sw_if_index = ~0;
16757   u8 *tag = 0;
16758   u8 enable = 1;
16759
16760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16761     {
16762       if (unformat (i, "tag %s", &tag))
16763         ;
16764       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16765         ;
16766       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16767         ;
16768       else if (unformat (i, "del"))
16769         enable = 0;
16770       else
16771         break;
16772     }
16773
16774   if (sw_if_index == ~0)
16775     {
16776       errmsg ("missing interface name or sw_if_index\n");
16777       return -99;
16778     }
16779
16780   if (enable && (tag == 0))
16781     {
16782       errmsg ("no tag specified\n");
16783       return -99;
16784     }
16785
16786   /* Construct the API message */
16787   M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
16788   mp->sw_if_index = ntohl (sw_if_index);
16789   mp->is_add = enable;
16790   if (enable)
16791     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
16792   vec_free (tag);
16793
16794   S;
16795   W;
16796 }
16797
16798 static void vl_api_l2_xconnect_details_t_handler
16799   (vl_api_l2_xconnect_details_t * mp)
16800 {
16801   vat_main_t *vam = &vat_main;
16802
16803   fformat (vam->ofp, "%15d%15d\n",
16804            ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
16805 }
16806
16807 static void vl_api_l2_xconnect_details_t_handler_json
16808   (vl_api_l2_xconnect_details_t * mp)
16809 {
16810   vat_main_t *vam = &vat_main;
16811   vat_json_node_t *node = NULL;
16812
16813   if (VAT_JSON_ARRAY != vam->json_tree.type)
16814     {
16815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16816       vat_json_init_array (&vam->json_tree);
16817     }
16818   node = vat_json_array_add (&vam->json_tree);
16819
16820   vat_json_init_object (node);
16821   vat_json_object_add_uint (node, "rx_sw_if_index",
16822                             ntohl (mp->rx_sw_if_index));
16823   vat_json_object_add_uint (node, "tx_sw_if_index",
16824                             ntohl (mp->tx_sw_if_index));
16825 }
16826
16827 static int
16828 api_l2_xconnect_dump (vat_main_t * vam)
16829 {
16830   vl_api_l2_xconnect_dump_t *mp;
16831   f64 timeout;
16832
16833   if (!vam->json_output)
16834     {
16835       fformat (vam->ofp, "%15s%15s\n", "rx_sw_if_index", "tx_sw_if_index");
16836     }
16837
16838   M (L2_XCONNECT_DUMP, l2_xconnect_dump);
16839
16840   S;
16841
16842   /* Use a control ping for synchronization */
16843   {
16844     vl_api_control_ping_t *mp;
16845     M (CONTROL_PING, control_ping);
16846     S;
16847   }
16848   W;
16849 }
16850
16851 static int
16852 api_sw_interface_set_mtu (vat_main_t * vam)
16853 {
16854   unformat_input_t *i = vam->input;
16855   vl_api_sw_interface_set_mtu_t *mp;
16856   f64 timeout;
16857   u32 sw_if_index = ~0;
16858   u32 mtu = 0;
16859
16860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16861     {
16862       if (unformat (i, "mtu %d", &mtu))
16863         ;
16864       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16865         ;
16866       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16867         ;
16868       else
16869         break;
16870     }
16871
16872   if (sw_if_index == ~0)
16873     {
16874       errmsg ("missing interface name or sw_if_index\n");
16875       return -99;
16876     }
16877
16878   if (mtu == 0)
16879     {
16880       errmsg ("no mtu specified\n");
16881       return -99;
16882     }
16883
16884   /* Construct the API message */
16885   M (SW_INTERFACE_SET_MTU, sw_interface_set_mtu);
16886   mp->sw_if_index = ntohl (sw_if_index);
16887   mp->mtu = ntohs ((u16) mtu);
16888
16889   S;
16890   W;
16891 }
16892
16893
16894 static int
16895 q_or_quit (vat_main_t * vam)
16896 {
16897   longjmp (vam->jump_buf, 1);
16898   return 0;                     /* not so much */
16899 }
16900
16901 static int
16902 q (vat_main_t * vam)
16903 {
16904   return q_or_quit (vam);
16905 }
16906
16907 static int
16908 quit (vat_main_t * vam)
16909 {
16910   return q_or_quit (vam);
16911 }
16912
16913 static int
16914 comment (vat_main_t * vam)
16915 {
16916   return 0;
16917 }
16918
16919 static int
16920 cmd_cmp (void *a1, void *a2)
16921 {
16922   u8 **c1 = a1;
16923   u8 **c2 = a2;
16924
16925   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
16926 }
16927
16928 static int
16929 help (vat_main_t * vam)
16930 {
16931   u8 **cmds = 0;
16932   u8 *name = 0;
16933   hash_pair_t *p;
16934   unformat_input_t *i = vam->input;
16935   int j;
16936
16937   if (unformat (i, "%s", &name))
16938     {
16939       uword *hs;
16940
16941       vec_add1 (name, 0);
16942
16943       hs = hash_get_mem (vam->help_by_name, name);
16944       if (hs)
16945         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
16946       else
16947         fformat (vam->ofp, "No such msg / command '%s'\n", name);
16948       vec_free (name);
16949       return 0;
16950     }
16951
16952   fformat (vam->ofp, "Help is available for the following:\n");
16953
16954     /* *INDENT-OFF* */
16955     hash_foreach_pair (p, vam->function_by_name,
16956     ({
16957       vec_add1 (cmds, (u8 *)(p->key));
16958     }));
16959     /* *INDENT-ON* */
16960
16961   vec_sort_with_function (cmds, cmd_cmp);
16962
16963   for (j = 0; j < vec_len (cmds); j++)
16964     fformat (vam->ofp, "%s\n", cmds[j]);
16965
16966   vec_free (cmds);
16967   return 0;
16968 }
16969
16970 static int
16971 set (vat_main_t * vam)
16972 {
16973   u8 *name = 0, *value = 0;
16974   unformat_input_t *i = vam->input;
16975
16976   if (unformat (i, "%s", &name))
16977     {
16978       /* The input buffer is a vector, not a string. */
16979       value = vec_dup (i->buffer);
16980       vec_delete (value, i->index, 0);
16981       /* Almost certainly has a trailing newline */
16982       if (value[vec_len (value) - 1] == '\n')
16983         value[vec_len (value) - 1] = 0;
16984       /* Make sure it's a proper string, one way or the other */
16985       vec_add1 (value, 0);
16986       (void) clib_macro_set_value (&vam->macro_main,
16987                                    (char *) name, (char *) value);
16988     }
16989   else
16990     errmsg ("usage: set <name> <value>\n");
16991
16992   vec_free (name);
16993   vec_free (value);
16994   return 0;
16995 }
16996
16997 static int
16998 unset (vat_main_t * vam)
16999 {
17000   u8 *name = 0;
17001
17002   if (unformat (vam->input, "%s", &name))
17003     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17004       errmsg ("unset: %s wasn't set\n", name);
17005   vec_free (name);
17006   return 0;
17007 }
17008
17009 typedef struct
17010 {
17011   u8 *name;
17012   u8 *value;
17013 } macro_sort_t;
17014
17015
17016 static int
17017 macro_sort_cmp (void *a1, void *a2)
17018 {
17019   macro_sort_t *s1 = a1;
17020   macro_sort_t *s2 = a2;
17021
17022   return strcmp ((char *) (s1->name), (char *) (s2->name));
17023 }
17024
17025 static int
17026 dump_macro_table (vat_main_t * vam)
17027 {
17028   macro_sort_t *sort_me = 0, *sm;
17029   int i;
17030   hash_pair_t *p;
17031
17032     /* *INDENT-OFF* */
17033     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17034     ({
17035       vec_add2 (sort_me, sm, 1);
17036       sm->name = (u8 *)(p->key);
17037       sm->value = (u8 *) (p->value[0]);
17038     }));
17039     /* *INDENT-ON* */
17040
17041   vec_sort_with_function (sort_me, macro_sort_cmp);
17042
17043   if (vec_len (sort_me))
17044     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
17045   else
17046     fformat (vam->ofp, "The macro table is empty...\n");
17047
17048   for (i = 0; i < vec_len (sort_me); i++)
17049     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
17050   return 0;
17051 }
17052
17053 static int
17054 dump_node_table (vat_main_t * vam)
17055 {
17056   int i, j;
17057   vlib_node_t *node, *next_node;
17058
17059   if (vec_len (vam->graph_nodes) == 0)
17060     {
17061       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
17062       return 0;
17063     }
17064
17065   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17066     {
17067       node = vam->graph_nodes[i];
17068       fformat (vam->ofp, "[%d] %s\n", i, node->name);
17069       for (j = 0; j < vec_len (node->next_nodes); j++)
17070         {
17071           if (node->next_nodes[j] != ~0)
17072             {
17073               next_node = vam->graph_nodes[node->next_nodes[j]];
17074               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
17075             }
17076         }
17077     }
17078   return 0;
17079 }
17080
17081 static int
17082 value_sort_cmp (void *a1, void *a2)
17083 {
17084   name_sort_t *n1 = a1;
17085   name_sort_t *n2 = a2;
17086
17087   if (n1->value < n2->value)
17088     return -1;
17089   if (n1->value > n2->value)
17090     return 1;
17091   return 0;
17092 }
17093
17094
17095 static int
17096 dump_msg_api_table (vat_main_t * vam)
17097 {
17098   api_main_t *am = &api_main;
17099   name_sort_t *nses = 0, *ns;
17100   hash_pair_t *hp;
17101   int i;
17102
17103   /* *INDENT-OFF* */
17104   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17105   ({
17106     vec_add2 (nses, ns, 1);
17107     ns->name = (u8 *)(hp->key);
17108     ns->value = (u32) hp->value[0];
17109   }));
17110   /* *INDENT-ON* */
17111
17112   vec_sort_with_function (nses, value_sort_cmp);
17113
17114   for (i = 0; i < vec_len (nses); i++)
17115     fformat (vam->ofp, " [%d]: %s\n", nses[i].value, nses[i].name);
17116   vec_free (nses);
17117   return 0;
17118 }
17119
17120 static int
17121 get_msg_id (vat_main_t * vam)
17122 {
17123   u8 *name_and_crc;
17124   u32 message_index;
17125
17126   if (unformat (vam->input, "%s", &name_and_crc))
17127     {
17128       message_index = vl_api_get_msg_index (name_and_crc);
17129       if (message_index == ~0)
17130         {
17131           fformat (vam->ofp, " '%s' not found\n", name_and_crc);
17132           return 0;
17133         }
17134       fformat (vam->ofp, " '%s' has message index %d\n",
17135                name_and_crc, message_index);
17136       return 0;
17137     }
17138   errmsg ("name_and_crc required...\n");
17139   return 0;
17140 }
17141
17142 static int
17143 search_node_table (vat_main_t * vam)
17144 {
17145   unformat_input_t *line_input = vam->input;
17146   u8 *node_to_find;
17147   int j;
17148   vlib_node_t *node, *next_node;
17149   uword *p;
17150
17151   if (vam->graph_node_index_by_name == 0)
17152     {
17153       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
17154       return 0;
17155     }
17156
17157   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17158     {
17159       if (unformat (line_input, "%s", &node_to_find))
17160         {
17161           vec_add1 (node_to_find, 0);
17162           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17163           if (p == 0)
17164             {
17165               fformat (vam->ofp, "%s not found...\n", node_to_find);
17166               goto out;
17167             }
17168           node = vam->graph_nodes[p[0]];
17169           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
17170           for (j = 0; j < vec_len (node->next_nodes); j++)
17171             {
17172               if (node->next_nodes[j] != ~0)
17173                 {
17174                   next_node = vam->graph_nodes[node->next_nodes[j]];
17175                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
17176                 }
17177             }
17178         }
17179
17180       else
17181         {
17182           clib_warning ("parse error '%U'", format_unformat_error,
17183                         line_input);
17184           return -99;
17185         }
17186
17187     out:
17188       vec_free (node_to_find);
17189
17190     }
17191
17192   return 0;
17193 }
17194
17195
17196 static int
17197 script (vat_main_t * vam)
17198 {
17199   u8 *s = 0;
17200   char *save_current_file;
17201   unformat_input_t save_input;
17202   jmp_buf save_jump_buf;
17203   u32 save_line_number;
17204
17205   FILE *new_fp, *save_ifp;
17206
17207   if (unformat (vam->input, "%s", &s))
17208     {
17209       new_fp = fopen ((char *) s, "r");
17210       if (new_fp == 0)
17211         {
17212           errmsg ("Couldn't open script file %s\n", s);
17213           vec_free (s);
17214           return -99;
17215         }
17216     }
17217   else
17218     {
17219       errmsg ("Missing script name\n");
17220       return -99;
17221     }
17222
17223   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17224   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17225   save_ifp = vam->ifp;
17226   save_line_number = vam->input_line_number;
17227   save_current_file = (char *) vam->current_file;
17228
17229   vam->input_line_number = 0;
17230   vam->ifp = new_fp;
17231   vam->current_file = s;
17232   do_one_file (vam);
17233
17234   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17235   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17236   vam->ifp = save_ifp;
17237   vam->input_line_number = save_line_number;
17238   vam->current_file = (u8 *) save_current_file;
17239   vec_free (s);
17240
17241   return 0;
17242 }
17243
17244 static int
17245 echo (vat_main_t * vam)
17246 {
17247   fformat (vam->ofp, "%v", vam->input->buffer);
17248   return 0;
17249 }
17250
17251 /* List of API message constructors, CLI names map to api_xxx */
17252 #define foreach_vpe_api_msg                                             \
17253 _(create_loopback,"[mac <mac-addr>]")                                   \
17254 _(sw_interface_dump,"")                                                 \
17255 _(sw_interface_set_flags,                                               \
17256   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17257 _(sw_interface_add_del_address,                                         \
17258   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17259 _(sw_interface_set_table,                                               \
17260   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17261 _(sw_interface_set_mpls_enable,                                                \
17262   "<intfc> | sw_if_index [disable | dis]")                                \
17263 _(sw_interface_set_vpath,                                               \
17264   "<intfc> | sw_if_index <id> enable | disable")                        \
17265 _(sw_interface_set_vxlan_bypass,                                               \
17266   "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable")                        \
17267 _(sw_interface_set_l2_xconnect,                                         \
17268   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17269   "enable | disable")                                                   \
17270 _(sw_interface_set_l2_bridge,                                           \
17271   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
17272   "[shg <split-horizon-group>] [bvi]\n"                                 \
17273   "enable | disable")                                                   \
17274 _(sw_interface_set_dpdk_hqos_pipe,                                      \
17275   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
17276   "profile <profile-id>\n")                                             \
17277 _(sw_interface_set_dpdk_hqos_subport,                                   \
17278   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
17279   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
17280 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
17281   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
17282 _(bridge_domain_add_del,                                                \
17283   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
17284 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
17285 _(l2fib_add_del,                                                        \
17286   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17287 _(l2_flags,                                                             \
17288   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
17289 _(bridge_flags,                                                         \
17290   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17291 _(tap_connect,                                                          \
17292   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17293 _(tap_modify,                                                           \
17294   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17295 _(tap_delete,                                                           \
17296   "<vpp-if-name> | sw_if_index <id>")                                   \
17297 _(sw_interface_tap_dump, "")                                            \
17298 _(ip_add_del_route,                                                     \
17299   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17300   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17301   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17302   "[multipath] [count <n>]")                                            \
17303 _(mpls_route_add_del,                                                   \
17304   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17305   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17306   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17307   "[multipath] [count <n>]")                                            \
17308 _(mpls_ip_bind_unbind,                                                  \
17309   "<label> <addr/len>")                                                 \
17310 _(mpls_tunnel_add_del,                                                  \
17311   " via <addr> [table-id <n>]\n"                                        \
17312   "sw_if_index <id>] [l2]  [del]")                                      \
17313 _(proxy_arp_add_del,                                                    \
17314   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17315 _(proxy_arp_intfc_enable_disable,                                       \
17316   "<intfc> | sw_if_index <id> enable | disable")                        \
17317 _(sw_interface_set_unnumbered,                                          \
17318   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17319 _(ip_neighbor_add_del,                                                  \
17320   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17321   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17322 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17323 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17324 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17325   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17326   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17327   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17328 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17329 _(reset_fib, "vrf <n> [ipv6]")                                          \
17330 _(dhcp_proxy_config,                                                    \
17331   "svr <v46-address> src <v46-address>\n"                               \
17332    "insert-cid <n> [del]")                                              \
17333 _(dhcp_proxy_config_2,                                                  \
17334   "svr <v46-address> src <v46-address>\n"                               \
17335    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
17336 _(dhcp_proxy_set_vss,                                                   \
17337   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17338 _(dhcp_client_config,                                                   \
17339   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17340 _(set_ip_flow_hash,                                                     \
17341   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17342 _(sw_interface_ip6_enable_disable,                                      \
17343   "<intfc> | sw_if_index <id> enable | disable")                        \
17344 _(sw_interface_ip6_set_link_local_address,                              \
17345   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17346 _(sw_interface_ip6nd_ra_prefix,                                         \
17347   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17348   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17349   "[nolink] [isno]")                                                    \
17350 _(sw_interface_ip6nd_ra_config,                                         \
17351   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17352   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17353   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17354 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17355 _(l2_patch_add_del,                                                     \
17356   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17357   "enable | disable")                                                   \
17358 _(sr_tunnel_add_del,                                                    \
17359   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
17360   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
17361   "[policy <policy_name>]")                                             \
17362 _(sr_policy_add_del,                                                    \
17363   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
17364 _(sr_multicast_map_add_del,                                             \
17365   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
17366 _(classify_add_del_table,                                               \
17367   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17368   " [del] mask <mask-value>\n"                                          \
17369   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17370   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17371 _(classify_add_del_session,                                             \
17372   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17373   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17374   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17375   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17376 _(classify_set_interface_ip_table,                                      \
17377   "<intfc> | sw_if_index <nn> table <nn>")                              \
17378 _(classify_set_interface_l2_tables,                                     \
17379   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17380   "  [other-table <nn>]")                                               \
17381 _(get_node_index, "node <node-name")                                    \
17382 _(add_node_next, "node <node-name> next <next-node-name>")              \
17383 _(l2tpv3_create_tunnel,                                                 \
17384   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17385   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
17386   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17387 _(l2tpv3_set_tunnel_cookies,                                            \
17388   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17389   "[new_remote_cookie <nn>]\n")                                         \
17390 _(l2tpv3_interface_enable_disable,                                      \
17391   "<intfc> | sw_if_index <nn> enable | disable")                        \
17392 _(l2tpv3_set_lookup_key,                                                \
17393   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
17394 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
17395 _(vxlan_add_del_tunnel,                                                 \
17396   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
17397   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
17398   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
17399 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
17400 _(gre_add_del_tunnel,                                                   \
17401   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
17402 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
17403 _(l2_fib_clear_table, "")                                               \
17404 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
17405 _(l2_interface_vlan_tag_rewrite,                                        \
17406   "<intfc> | sw_if_index <nn> \n"                                       \
17407   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
17408   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
17409 _(create_vhost_user_if,                                                 \
17410         "socket <filename> [server] [renumber <dev_instance>] "         \
17411         "[mac <mac_address>]")                                          \
17412 _(modify_vhost_user_if,                                                 \
17413         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
17414         "[server] [renumber <dev_instance>]")                           \
17415 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
17416 _(sw_interface_vhost_user_dump, "")                                     \
17417 _(show_version, "")                                                     \
17418 _(vxlan_gpe_add_del_tunnel,                                             \
17419   "local <addr> remote <addr> vni <nn>\n"                               \
17420     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
17421   "[next-ethernet] [next-nsh]\n")                                       \
17422 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
17423 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
17424 _(interface_name_renumber,                                              \
17425   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
17426 _(input_acl_set_interface,                                              \
17427   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17428   "  [l2-table <nn>] [del]")                                            \
17429 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
17430 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
17431 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
17432 _(ip_dump, "ipv4 | ipv6")                                               \
17433 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
17434 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
17435   "  spid_id <n> ")                                                     \
17436 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
17437   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
17438   "  integ_alg <alg> integ_key <hex>")                                  \
17439 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
17440   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
17441   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
17442   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
17443 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
17444 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
17445 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
17446   "(auth_data 0x<data> | auth_data <data>)")                            \
17447 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
17448   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
17449 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
17450   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
17451   "(local|remote)")                                                     \
17452 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
17453 _(delete_loopback,"sw_if_index <nn>")                                   \
17454 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
17455 _(map_add_domain,                                                       \
17456   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
17457   "ip6-src <ip6addr> "                                                  \
17458   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
17459 _(map_del_domain, "index <n>")                                          \
17460 _(map_add_del_rule,                                                     \
17461   "index <n> psid <n> dst <ip6addr> [del]")                             \
17462 _(map_domain_dump, "")                                                  \
17463 _(map_rule_dump, "index <map-domain>")                                  \
17464 _(want_interface_events,  "enable|disable")                             \
17465 _(want_stats,"enable|disable")                                          \
17466 _(get_first_msg_id, "client <name>")                                    \
17467 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
17468 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
17469   "fib-id <nn> [ip4][ip6][default]")                                    \
17470 _(get_node_graph, " ")                                                  \
17471 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
17472 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
17473 _(ioam_disable, "")                                                \
17474 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
17475                             " sw_if_index <sw_if_index> p <priority> "  \
17476                             "w <weight>] [del]")                        \
17477 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
17478                         "iface <intf> | sw_if_index <sw_if_index> "     \
17479                         "p <priority> w <weight> [del]")                \
17480 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
17481                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
17482                          "locator-set <locator_name> [del]"             \
17483                          "[key-id sha1|sha256 secret-key <secret-key>]")\
17484 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
17485   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
17486 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
17487 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
17488 _(lisp_gpe_enable_disable, "enable|disable")                            \
17489 _(lisp_enable_disable, "enable|disable")                                \
17490 _(lisp_map_register_enable_disable, "enable|disable")                   \
17491 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
17492 _(lisp_gpe_add_del_iface, "up|down")                                    \
17493 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
17494                                "[seid <seid>] "                         \
17495                                "rloc <locator> p <prio> "               \
17496                                "w <weight> [rloc <loc> ... ] "          \
17497                                "action <action> [del-all]")             \
17498 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
17499                           "<local-eid>")                                \
17500 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
17501 _(lisp_map_request_mode, "src-dst|dst-only")                            \
17502 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
17503 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
17504 _(lisp_locator_set_dump, "[local | remote]")                            \
17505 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
17506 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
17507                        "[local] | [remote]")                            \
17508 _(lisp_eid_table_vni_dump, "")                                          \
17509 _(lisp_eid_table_map_dump, "l2|l3")                                     \
17510 _(lisp_gpe_tunnel_dump, "")                                             \
17511 _(lisp_map_resolver_dump, "")                                           \
17512 _(lisp_map_server_dump, "")                                             \
17513 _(lisp_adjacencies_get, "vni <vni>")                                    \
17514 _(show_lisp_rloc_probe_state, "")                                       \
17515 _(show_lisp_map_register_state, "")                                     \
17516 _(show_lisp_status, "")                                                 \
17517 _(lisp_get_map_request_itr_rlocs, "")                                   \
17518 _(show_lisp_pitr, "")                                                   \
17519 _(show_lisp_map_request_mode, "")                                       \
17520 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
17521 _(af_packet_delete, "name <host interface name>")                       \
17522 _(policer_add_del, "name <policer name> <params> [del]")                \
17523 _(policer_dump, "[name <policer name>]")                                \
17524 _(policer_classify_set_interface,                                       \
17525   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17526   "  [l2-table <nn>] [del]")                                            \
17527 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
17528 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
17529     "[master|slave]")                                                   \
17530 _(netmap_delete, "name <interface name>")                               \
17531 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
17532 _(mpls_fib_dump, "")                                                    \
17533 _(classify_table_ids, "")                                               \
17534 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
17535 _(classify_table_info, "table_id <nn>")                                 \
17536 _(classify_session_dump, "table_id <nn>")                               \
17537 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
17538     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
17539     "[template_interval <nn>] [udp_checksum]")                          \
17540 _(ipfix_exporter_dump, "")                                              \
17541 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17542 _(ipfix_classify_stream_dump, "")                                       \
17543 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
17544 _(ipfix_classify_table_dump, "")                                        \
17545 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [[dst <intfc> | dst_sw_if_index <id>] | disable]") \
17546 _(sw_interface_span_dump, "")                                           \
17547 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
17548 _(pg_create_interface, "if_id <nn>")                                    \
17549 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
17550 _(pg_enable_disable, "[stream <id>] disable")                           \
17551 _(ip_source_and_port_range_check_add_del,                               \
17552   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
17553 _(ip_source_and_port_range_check_interface_add_del,                     \
17554   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
17555   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
17556 _(ipsec_gre_add_del_tunnel,                                             \
17557   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
17558 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
17559 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
17560 _(l2_interface_pbb_tag_rewrite,                                         \
17561   "<intfc> | sw_if_index <nn> \n"                                       \
17562   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
17563   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
17564 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
17565 _(flow_classify_set_interface,                                          \
17566   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17567 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17568 _(ip_fib_dump, "")                                                      \
17569 _(ip6_fib_dump, "")                                                     \
17570 _(feature_enable_disable, "arc_name <arc_name> "                        \
17571   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
17572 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
17573 "[disable]")                                                            \
17574 _(l2_xconnect_dump, "")                                                 \
17575 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
17576 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")
17577
17578 /* List of command functions, CLI names map directly to functions */
17579 #define foreach_cli_function                                    \
17580 _(comment, "usage: comment <ignore-rest-of-line>")              \
17581 _(dump_interface_table, "usage: dump_interface_table")          \
17582 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17583 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17584 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17585 _(dump_stats_table, "usage: dump_stats_table")                  \
17586 _(dump_macro_table, "usage: dump_macro_table ")                 \
17587 _(dump_node_table, "usage: dump_node_table")                    \
17588 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17589 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17590 _(echo, "usage: echo <message>")                                \
17591 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17592 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17593 _(help, "usage: help")                                          \
17594 _(q, "usage: quit")                                             \
17595 _(quit, "usage: quit")                                          \
17596 _(search_node_table, "usage: search_node_table <name>...")      \
17597 _(set, "usage: set <variable-name> <value>")                    \
17598 _(script, "usage: script <file-name>")                          \
17599 _(unset, "usage: unset <variable-name>")
17600
17601 #define _(N,n)                                  \
17602     static void vl_api_##n##_t_handler_uni      \
17603     (vl_api_##n##_t * mp)                       \
17604     {                                           \
17605         vat_main_t * vam = &vat_main;           \
17606         if (vam->json_output) {                 \
17607             vl_api_##n##_t_handler_json(mp);    \
17608         } else {                                \
17609             vl_api_##n##_t_handler(mp);         \
17610         }                                       \
17611     }
17612 foreach_vpe_api_reply_msg;
17613 #undef _
17614
17615 void
17616 vat_api_hookup (vat_main_t * vam)
17617 {
17618 #define _(N,n)                                                  \
17619     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17620                            vl_api_##n##_t_handler_uni,          \
17621                            vl_noop_handler,                     \
17622                            vl_api_##n##_t_endian,               \
17623                            vl_api_##n##_t_print,                \
17624                            sizeof(vl_api_##n##_t), 1);
17625   foreach_vpe_api_reply_msg;
17626 #undef _
17627
17628   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17629
17630   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17631
17632   vam->function_by_name = hash_create_string (0, sizeof (uword));
17633
17634   vam->help_by_name = hash_create_string (0, sizeof (uword));
17635
17636   /* API messages we can send */
17637 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17638   foreach_vpe_api_msg;
17639 #undef _
17640
17641   /* Help strings */
17642 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17643   foreach_vpe_api_msg;
17644 #undef _
17645
17646   /* CLI functions */
17647 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17648   foreach_cli_function;
17649 #undef _
17650
17651   /* Help strings */
17652 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17653   foreach_cli_function;
17654 #undef _
17655 }
17656
17657 #undef vl_api_version
17658 #define vl_api_version(n,v) static u32 memory_api_version = v;
17659 #include <vlibmemory/vl_memory_api_h.h>
17660 #undef vl_api_version
17661
17662 #undef vl_api_version
17663 #define vl_api_version(n,v) static u32 vnet_interface_api_version = v;
17664 #include <vnet/interface.api.h>
17665 #undef vl_api_version
17666
17667 #undef vl_api_version
17668 #define vl_api_version(n,v) static u32 vpp_api_version = v;
17669 #include <vpp-api/vpe.api.h>
17670 #undef vl_api_version
17671
17672 static u32 *api_versions[] = {
17673   &memory_api_version,
17674   &vnet_interface_api_version,
17675   &vpp_api_version,
17676 };
17677
17678 void
17679 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
17680 {
17681   int i;
17682
17683   ASSERT (ARRAY_LEN (mp->api_versions) >= ARRAY_LEN (api_versions));
17684
17685   /*
17686    * Send the API signatures. This bit of code must
17687    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
17688    */
17689
17690   for (i = 0; i < ARRAY_LEN (api_versions); i++)
17691     mp->api_versions[i] = clib_host_to_net_u32 (*api_versions[i]);
17692 }
17693
17694 /*
17695  * fd.io coding-style-patch-verification: ON
17696  *
17697  * Local Variables:
17698  * eval: (c-set-style "gnu")
17699  * End:
17700  */