258c67f8e0cbf7519f8a0e95c83615754e2519ba
[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 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
3926
3927 /* M: construct, but don't yet send a message */
3928
3929 #define M(T,t)                                  \
3930 do {                                            \
3931     vam->result_ready = 0;                      \
3932     mp = vl_msg_api_alloc(sizeof(*mp));         \
3933     memset (mp, 0, sizeof (*mp));               \
3934     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3935     mp->client_index = vam->my_client_index;    \
3936 } while(0);
3937
3938 #define M2(T,t,n)                               \
3939 do {                                            \
3940     vam->result_ready = 0;                      \
3941     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3942     memset (mp, 0, sizeof (*mp));               \
3943     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3944     mp->client_index = vam->my_client_index;    \
3945 } while(0);
3946
3947
3948 /* S: send a message */
3949 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3950
3951 /* W: wait for results, with timeout */
3952 #define W                                       \
3953 do {                                            \
3954     timeout = vat_time_now (vam) + 1.0;         \
3955                                                 \
3956     while (vat_time_now (vam) < timeout) {      \
3957         if (vam->result_ready == 1) {           \
3958             return (vam->retval);               \
3959         }                                       \
3960     }                                           \
3961     return -99;                                 \
3962 } while(0);
3963
3964 /* W2: wait for results, with timeout */
3965 #define W2(body)                                \
3966 do {                                            \
3967     timeout = vat_time_now (vam) + 1.0;         \
3968                                                 \
3969     while (vat_time_now (vam) < timeout) {      \
3970         if (vam->result_ready == 1) {           \
3971           (body);                               \
3972           return (vam->retval);                 \
3973         }                                       \
3974     }                                           \
3975     return -99;                                 \
3976 } while(0);
3977
3978 typedef struct
3979 {
3980   u8 *name;
3981   u32 value;
3982 } name_sort_t;
3983
3984
3985 #define STR_VTR_OP_CASE(op)     \
3986     case L2_VTR_ ## op:         \
3987         return "" # op;
3988
3989 static const char *
3990 str_vtr_op (u32 vtr_op)
3991 {
3992   switch (vtr_op)
3993     {
3994       STR_VTR_OP_CASE (DISABLED);
3995       STR_VTR_OP_CASE (PUSH_1);
3996       STR_VTR_OP_CASE (PUSH_2);
3997       STR_VTR_OP_CASE (POP_1);
3998       STR_VTR_OP_CASE (POP_2);
3999       STR_VTR_OP_CASE (TRANSLATE_1_1);
4000       STR_VTR_OP_CASE (TRANSLATE_1_2);
4001       STR_VTR_OP_CASE (TRANSLATE_2_1);
4002       STR_VTR_OP_CASE (TRANSLATE_2_2);
4003     }
4004
4005   return "UNKNOWN";
4006 }
4007
4008 static int
4009 dump_sub_interface_table (vat_main_t * vam)
4010 {
4011   const sw_interface_subif_t *sub = NULL;
4012
4013   if (vam->json_output)
4014     {
4015       clib_warning
4016         ("JSON output supported only for VPE API calls and dump_stats_table");
4017       return -99;
4018     }
4019
4020   fformat (vam->ofp,
4021            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
4022            "Interface", "sw_if_index",
4023            "sub id", "dot1ad", "tags", "outer id",
4024            "inner id", "exact", "default", "outer any", "inner any");
4025
4026   vec_foreach (sub, vam->sw_if_subif_table)
4027   {
4028     fformat (vam->ofp,
4029              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
4030              sub->interface_name,
4031              sub->sw_if_index,
4032              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4033              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4034              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4035              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4036     if (sub->vtr_op != L2_VTR_DISABLED)
4037       {
4038         fformat (vam->ofp,
4039                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4040                  "tag1: %d tag2: %d ]\n",
4041                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4042                  sub->vtr_tag1, sub->vtr_tag2);
4043       }
4044   }
4045
4046   return 0;
4047 }
4048
4049 static int
4050 name_sort_cmp (void *a1, void *a2)
4051 {
4052   name_sort_t *n1 = a1;
4053   name_sort_t *n2 = a2;
4054
4055   return strcmp ((char *) n1->name, (char *) n2->name);
4056 }
4057
4058 static int
4059 dump_interface_table (vat_main_t * vam)
4060 {
4061   hash_pair_t *p;
4062   name_sort_t *nses = 0, *ns;
4063
4064   if (vam->json_output)
4065     {
4066       clib_warning
4067         ("JSON output supported only for VPE API calls and dump_stats_table");
4068       return -99;
4069     }
4070
4071   /* *INDENT-OFF* */
4072   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4073   ({
4074     vec_add2 (nses, ns, 1);
4075     ns->name = (u8 *)(p->key);
4076     ns->value = (u32) p->value[0];
4077   }));
4078   /* *INDENT-ON* */
4079
4080   vec_sort_with_function (nses, name_sort_cmp);
4081
4082   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
4083   vec_foreach (ns, nses)
4084   {
4085     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
4086   }
4087   vec_free (nses);
4088   return 0;
4089 }
4090
4091 static int
4092 dump_ip_table (vat_main_t * vam, int is_ipv6)
4093 {
4094   const ip_details_t *det = NULL;
4095   const ip_address_details_t *address = NULL;
4096   u32 i = ~0;
4097
4098   fformat (vam->ofp, "%-12s\n", "sw_if_index");
4099
4100   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4101   {
4102     i++;
4103     if (!det->present)
4104       {
4105         continue;
4106       }
4107     fformat (vam->ofp, "%-12d\n", i);
4108     fformat (vam->ofp,
4109              "            %-30s%-13s\n", "Address", "Prefix length");
4110     if (!det->addr)
4111       {
4112         continue;
4113       }
4114     vec_foreach (address, det->addr)
4115     {
4116       fformat (vam->ofp,
4117                "            %-30U%-13d\n",
4118                is_ipv6 ? format_ip6_address : format_ip4_address,
4119                address->ip, address->prefix_length);
4120     }
4121   }
4122
4123   return 0;
4124 }
4125
4126 static int
4127 dump_ipv4_table (vat_main_t * vam)
4128 {
4129   if (vam->json_output)
4130     {
4131       clib_warning
4132         ("JSON output supported only for VPE API calls and dump_stats_table");
4133       return -99;
4134     }
4135
4136   return dump_ip_table (vam, 0);
4137 }
4138
4139 static int
4140 dump_ipv6_table (vat_main_t * vam)
4141 {
4142   if (vam->json_output)
4143     {
4144       clib_warning
4145         ("JSON output supported only for VPE API calls and dump_stats_table");
4146       return -99;
4147     }
4148
4149   return dump_ip_table (vam, 1);
4150 }
4151
4152 static char *
4153 counter_type_to_str (u8 counter_type, u8 is_combined)
4154 {
4155   if (!is_combined)
4156     {
4157       switch (counter_type)
4158         {
4159         case VNET_INTERFACE_COUNTER_DROP:
4160           return "drop";
4161         case VNET_INTERFACE_COUNTER_PUNT:
4162           return "punt";
4163         case VNET_INTERFACE_COUNTER_IP4:
4164           return "ip4";
4165         case VNET_INTERFACE_COUNTER_IP6:
4166           return "ip6";
4167         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4168           return "rx-no-buf";
4169         case VNET_INTERFACE_COUNTER_RX_MISS:
4170           return "rx-miss";
4171         case VNET_INTERFACE_COUNTER_RX_ERROR:
4172           return "rx-error";
4173         case VNET_INTERFACE_COUNTER_TX_ERROR:
4174           return "tx-error";
4175         default:
4176           return "INVALID-COUNTER-TYPE";
4177         }
4178     }
4179   else
4180     {
4181       switch (counter_type)
4182         {
4183         case VNET_INTERFACE_COUNTER_RX:
4184           return "rx";
4185         case VNET_INTERFACE_COUNTER_TX:
4186           return "tx";
4187         default:
4188           return "INVALID-COUNTER-TYPE";
4189         }
4190     }
4191 }
4192
4193 static int
4194 dump_stats_table (vat_main_t * vam)
4195 {
4196   vat_json_node_t node;
4197   vat_json_node_t *msg_array;
4198   vat_json_node_t *msg;
4199   vat_json_node_t *counter_array;
4200   vat_json_node_t *counter;
4201   interface_counter_t c;
4202   u64 packets;
4203   ip4_fib_counter_t *c4;
4204   ip6_fib_counter_t *c6;
4205   int i, j;
4206
4207   if (!vam->json_output)
4208     {
4209       clib_warning ("dump_stats_table supported only in JSON format");
4210       return -99;
4211     }
4212
4213   vat_json_init_object (&node);
4214
4215   /* interface counters */
4216   msg_array = vat_json_object_add (&node, "interface_counters");
4217   vat_json_init_array (msg_array);
4218   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4219     {
4220       msg = vat_json_array_add (msg_array);
4221       vat_json_init_object (msg);
4222       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4223                                        (u8 *) counter_type_to_str (i, 0));
4224       vat_json_object_add_int (msg, "is_combined", 0);
4225       counter_array = vat_json_object_add (msg, "data");
4226       vat_json_init_array (counter_array);
4227       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4228         {
4229           packets = vam->simple_interface_counters[i][j];
4230           vat_json_array_add_uint (counter_array, packets);
4231         }
4232     }
4233   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4234     {
4235       msg = vat_json_array_add (msg_array);
4236       vat_json_init_object (msg);
4237       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4238                                        (u8 *) counter_type_to_str (i, 1));
4239       vat_json_object_add_int (msg, "is_combined", 1);
4240       counter_array = vat_json_object_add (msg, "data");
4241       vat_json_init_array (counter_array);
4242       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4243         {
4244           c = vam->combined_interface_counters[i][j];
4245           counter = vat_json_array_add (counter_array);
4246           vat_json_init_object (counter);
4247           vat_json_object_add_uint (counter, "packets", c.packets);
4248           vat_json_object_add_uint (counter, "bytes", c.bytes);
4249         }
4250     }
4251
4252   /* ip4 fib counters */
4253   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4254   vat_json_init_array (msg_array);
4255   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4256     {
4257       msg = vat_json_array_add (msg_array);
4258       vat_json_init_object (msg);
4259       vat_json_object_add_uint (msg, "vrf_id",
4260                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4261       counter_array = vat_json_object_add (msg, "c");
4262       vat_json_init_array (counter_array);
4263       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4264         {
4265           counter = vat_json_array_add (counter_array);
4266           vat_json_init_object (counter);
4267           c4 = &vam->ip4_fib_counters[i][j];
4268           vat_json_object_add_ip4 (counter, "address", c4->address);
4269           vat_json_object_add_uint (counter, "address_length",
4270                                     c4->address_length);
4271           vat_json_object_add_uint (counter, "packets", c4->packets);
4272           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4273         }
4274     }
4275
4276   /* ip6 fib counters */
4277   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4278   vat_json_init_array (msg_array);
4279   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4280     {
4281       msg = vat_json_array_add (msg_array);
4282       vat_json_init_object (msg);
4283       vat_json_object_add_uint (msg, "vrf_id",
4284                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4285       counter_array = vat_json_object_add (msg, "c");
4286       vat_json_init_array (counter_array);
4287       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4288         {
4289           counter = vat_json_array_add (counter_array);
4290           vat_json_init_object (counter);
4291           c6 = &vam->ip6_fib_counters[i][j];
4292           vat_json_object_add_ip6 (counter, "address", c6->address);
4293           vat_json_object_add_uint (counter, "address_length",
4294                                     c6->address_length);
4295           vat_json_object_add_uint (counter, "packets", c6->packets);
4296           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4297         }
4298     }
4299
4300   vat_json_print (vam->ofp, &node);
4301   vat_json_free (&node);
4302
4303   return 0;
4304 }
4305
4306 int
4307 exec (vat_main_t * vam)
4308 {
4309   api_main_t *am = &api_main;
4310   vl_api_cli_request_t *mp;
4311   f64 timeout;
4312   void *oldheap;
4313   u8 *cmd = 0;
4314   unformat_input_t *i = vam->input;
4315
4316   if (vec_len (i->buffer) == 0)
4317     return -1;
4318
4319   if (vam->exec_mode == 0 && unformat (i, "mode"))
4320     {
4321       vam->exec_mode = 1;
4322       return 0;
4323     }
4324   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4325     {
4326       vam->exec_mode = 0;
4327       return 0;
4328     }
4329
4330
4331   M (CLI_REQUEST, cli_request);
4332
4333   /*
4334    * Copy cmd into shared memory.
4335    * In order for the CLI command to work, it
4336    * must be a vector ending in \n, not a C-string ending
4337    * in \n\0.
4338    */
4339   pthread_mutex_lock (&am->vlib_rp->mutex);
4340   oldheap = svm_push_data_heap (am->vlib_rp);
4341
4342   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4343   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4344
4345   svm_pop_heap (oldheap);
4346   pthread_mutex_unlock (&am->vlib_rp->mutex);
4347
4348   mp->cmd_in_shmem = (u64) cmd;
4349   S;
4350   timeout = vat_time_now (vam) + 10.0;
4351
4352   while (vat_time_now (vam) < timeout)
4353     {
4354       if (vam->result_ready == 1)
4355         {
4356           u8 *free_me;
4357           if (vam->shmem_result != NULL)
4358             fformat (vam->ofp, "%s", vam->shmem_result);
4359           pthread_mutex_lock (&am->vlib_rp->mutex);
4360           oldheap = svm_push_data_heap (am->vlib_rp);
4361
4362           free_me = (u8 *) vam->shmem_result;
4363           vec_free (free_me);
4364
4365           svm_pop_heap (oldheap);
4366           pthread_mutex_unlock (&am->vlib_rp->mutex);
4367           return 0;
4368         }
4369     }
4370   return -99;
4371 }
4372
4373 /*
4374  * Future replacement of exec() that passes CLI buffers directly in
4375  * the API messages instead of an additional shared memory area.
4376  */
4377 static int
4378 exec_inband (vat_main_t * vam)
4379 {
4380   vl_api_cli_inband_t *mp;
4381   f64 timeout;
4382   unformat_input_t *i = vam->input;
4383
4384   if (vec_len (i->buffer) == 0)
4385     return -1;
4386
4387   if (vam->exec_mode == 0 && unformat (i, "mode"))
4388     {
4389       vam->exec_mode = 1;
4390       return 0;
4391     }
4392   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4393     {
4394       vam->exec_mode = 0;
4395       return 0;
4396     }
4397
4398   /*
4399    * In order for the CLI command to work, it
4400    * must be a vector ending in \n, not a C-string ending
4401    * in \n\0.
4402    */
4403   u32 len = vec_len (vam->input->buffer);
4404   M2 (CLI_INBAND, cli_inband, len);
4405   clib_memcpy (mp->cmd, vam->input->buffer, len);
4406   mp->length = htonl (len);
4407
4408   S;
4409   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4410 }
4411
4412 static int
4413 api_create_loopback (vat_main_t * vam)
4414 {
4415   unformat_input_t *i = vam->input;
4416   vl_api_create_loopback_t *mp;
4417   f64 timeout;
4418   u8 mac_address[6];
4419   u8 mac_set = 0;
4420
4421   memset (mac_address, 0, sizeof (mac_address));
4422
4423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4424     {
4425       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4426         mac_set = 1;
4427       else
4428         break;
4429     }
4430
4431   /* Construct the API message */
4432   M (CREATE_LOOPBACK, create_loopback);
4433   if (mac_set)
4434     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4435
4436   S;
4437   W;
4438 }
4439
4440 static int
4441 api_delete_loopback (vat_main_t * vam)
4442 {
4443   unformat_input_t *i = vam->input;
4444   vl_api_delete_loopback_t *mp;
4445   f64 timeout;
4446   u32 sw_if_index = ~0;
4447
4448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4449     {
4450       if (unformat (i, "sw_if_index %d", &sw_if_index))
4451         ;
4452       else
4453         break;
4454     }
4455
4456   if (sw_if_index == ~0)
4457     {
4458       errmsg ("missing sw_if_index\n");
4459       return -99;
4460     }
4461
4462   /* Construct the API message */
4463   M (DELETE_LOOPBACK, delete_loopback);
4464   mp->sw_if_index = ntohl (sw_if_index);
4465
4466   S;
4467   W;
4468 }
4469
4470 static int
4471 api_want_stats (vat_main_t * vam)
4472 {
4473   unformat_input_t *i = vam->input;
4474   vl_api_want_stats_t *mp;
4475   f64 timeout;
4476   int enable = -1;
4477
4478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4479     {
4480       if (unformat (i, "enable"))
4481         enable = 1;
4482       else if (unformat (i, "disable"))
4483         enable = 0;
4484       else
4485         break;
4486     }
4487
4488   if (enable == -1)
4489     {
4490       errmsg ("missing enable|disable\n");
4491       return -99;
4492     }
4493
4494   M (WANT_STATS, want_stats);
4495   mp->enable_disable = enable;
4496
4497   S;
4498   W;
4499 }
4500
4501 static int
4502 api_want_interface_events (vat_main_t * vam)
4503 {
4504   unformat_input_t *i = vam->input;
4505   vl_api_want_interface_events_t *mp;
4506   f64 timeout;
4507   int enable = -1;
4508
4509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4510     {
4511       if (unformat (i, "enable"))
4512         enable = 1;
4513       else if (unformat (i, "disable"))
4514         enable = 0;
4515       else
4516         break;
4517     }
4518
4519   if (enable == -1)
4520     {
4521       errmsg ("missing enable|disable\n");
4522       return -99;
4523     }
4524
4525   M (WANT_INTERFACE_EVENTS, want_interface_events);
4526   mp->enable_disable = enable;
4527
4528   vam->interface_event_display = enable;
4529
4530   S;
4531   W;
4532 }
4533
4534
4535 /* Note: non-static, called once to set up the initial intfc table */
4536 int
4537 api_sw_interface_dump (vat_main_t * vam)
4538 {
4539   vl_api_sw_interface_dump_t *mp;
4540   f64 timeout;
4541   hash_pair_t *p;
4542   name_sort_t *nses = 0, *ns;
4543   sw_interface_subif_t *sub = NULL;
4544
4545   /* Toss the old name table */
4546   /* *INDENT-OFF* */
4547   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4548   ({
4549     vec_add2 (nses, ns, 1);
4550     ns->name = (u8 *)(p->key);
4551     ns->value = (u32) p->value[0];
4552   }));
4553   /* *INDENT-ON* */
4554
4555   hash_free (vam->sw_if_index_by_interface_name);
4556
4557   vec_foreach (ns, nses) vec_free (ns->name);
4558
4559   vec_free (nses);
4560
4561   vec_foreach (sub, vam->sw_if_subif_table)
4562   {
4563     vec_free (sub->interface_name);
4564   }
4565   vec_free (vam->sw_if_subif_table);
4566
4567   /* recreate the interface name hash table */
4568   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4569
4570   /* Get list of ethernets */
4571   M (SW_INTERFACE_DUMP, sw_interface_dump);
4572   mp->name_filter_valid = 1;
4573   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4574   S;
4575
4576   /* and local / loopback interfaces */
4577   M (SW_INTERFACE_DUMP, sw_interface_dump);
4578   mp->name_filter_valid = 1;
4579   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4580   S;
4581
4582   /* and packet-generator interfaces */
4583   M (SW_INTERFACE_DUMP, sw_interface_dump);
4584   mp->name_filter_valid = 1;
4585   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4586   S;
4587
4588   /* and vxlan-gpe tunnel interfaces */
4589   M (SW_INTERFACE_DUMP, sw_interface_dump);
4590   mp->name_filter_valid = 1;
4591   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4592            sizeof (mp->name_filter) - 1);
4593   S;
4594
4595   /* and vxlan tunnel interfaces */
4596   M (SW_INTERFACE_DUMP, sw_interface_dump);
4597   mp->name_filter_valid = 1;
4598   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4599   S;
4600
4601   /* and host (af_packet) interfaces */
4602   M (SW_INTERFACE_DUMP, sw_interface_dump);
4603   mp->name_filter_valid = 1;
4604   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4605   S;
4606
4607   /* and l2tpv3 tunnel interfaces */
4608   M (SW_INTERFACE_DUMP, sw_interface_dump);
4609   mp->name_filter_valid = 1;
4610   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4611            sizeof (mp->name_filter) - 1);
4612   S;
4613
4614   /* and GRE tunnel interfaces */
4615   M (SW_INTERFACE_DUMP, sw_interface_dump);
4616   mp->name_filter_valid = 1;
4617   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4618   S;
4619
4620   /* and LISP-GPE interfaces */
4621   M (SW_INTERFACE_DUMP, sw_interface_dump);
4622   mp->name_filter_valid = 1;
4623   strncpy ((char *) mp->name_filter, "lisp_gpe",
4624            sizeof (mp->name_filter) - 1);
4625   S;
4626
4627   /* and IPSEC tunnel interfaces */
4628   M (SW_INTERFACE_DUMP, sw_interface_dump);
4629   mp->name_filter_valid = 1;
4630   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4631   S;
4632
4633   /* Use a control ping for synchronization */
4634   {
4635     vl_api_control_ping_t *mp;
4636     M (CONTROL_PING, control_ping);
4637     S;
4638   }
4639   W;
4640 }
4641
4642 static int
4643 api_sw_interface_set_flags (vat_main_t * vam)
4644 {
4645   unformat_input_t *i = vam->input;
4646   vl_api_sw_interface_set_flags_t *mp;
4647   f64 timeout;
4648   u32 sw_if_index;
4649   u8 sw_if_index_set = 0;
4650   u8 admin_up = 0, link_up = 0;
4651
4652   /* Parse args required to build the message */
4653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4654     {
4655       if (unformat (i, "admin-up"))
4656         admin_up = 1;
4657       else if (unformat (i, "admin-down"))
4658         admin_up = 0;
4659       else if (unformat (i, "link-up"))
4660         link_up = 1;
4661       else if (unformat (i, "link-down"))
4662         link_up = 0;
4663       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4664         sw_if_index_set = 1;
4665       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4666         sw_if_index_set = 1;
4667       else
4668         break;
4669     }
4670
4671   if (sw_if_index_set == 0)
4672     {
4673       errmsg ("missing interface name or sw_if_index\n");
4674       return -99;
4675     }
4676
4677   /* Construct the API message */
4678   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4679   mp->sw_if_index = ntohl (sw_if_index);
4680   mp->admin_up_down = admin_up;
4681   mp->link_up_down = link_up;
4682
4683   /* send it... */
4684   S;
4685
4686   /* Wait for a reply, return the good/bad news... */
4687   W;
4688 }
4689
4690 static int
4691 api_sw_interface_clear_stats (vat_main_t * vam)
4692 {
4693   unformat_input_t *i = vam->input;
4694   vl_api_sw_interface_clear_stats_t *mp;
4695   f64 timeout;
4696   u32 sw_if_index;
4697   u8 sw_if_index_set = 0;
4698
4699   /* Parse args required to build the message */
4700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4701     {
4702       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4703         sw_if_index_set = 1;
4704       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4705         sw_if_index_set = 1;
4706       else
4707         break;
4708     }
4709
4710   /* Construct the API message */
4711   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4712
4713   if (sw_if_index_set == 1)
4714     mp->sw_if_index = ntohl (sw_if_index);
4715   else
4716     mp->sw_if_index = ~0;
4717
4718   /* send it... */
4719   S;
4720
4721   /* Wait for a reply, return the good/bad news... */
4722   W;
4723 }
4724
4725 static int
4726 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4727 {
4728   unformat_input_t *i = vam->input;
4729   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4730   f64 timeout;
4731   u32 sw_if_index;
4732   u8 sw_if_index_set = 0;
4733   u32 subport;
4734   u8 subport_set = 0;
4735   u32 pipe;
4736   u8 pipe_set = 0;
4737   u32 profile;
4738   u8 profile_set = 0;
4739
4740   /* Parse args required to build the message */
4741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4742     {
4743       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4744         sw_if_index_set = 1;
4745       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4746         sw_if_index_set = 1;
4747       else if (unformat (i, "subport %u", &subport))
4748         subport_set = 1;
4749       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4750         sw_if_index_set = 1;
4751       else if (unformat (i, "pipe %u", &pipe))
4752         pipe_set = 1;
4753       else if (unformat (i, "profile %u", &profile))
4754         profile_set = 1;
4755       else
4756         break;
4757     }
4758
4759   if (sw_if_index_set == 0)
4760     {
4761       errmsg ("missing interface name or sw_if_index\n");
4762       return -99;
4763     }
4764
4765   if (subport_set == 0)
4766     {
4767       errmsg ("missing subport \n");
4768       return -99;
4769     }
4770
4771   if (pipe_set == 0)
4772     {
4773       errmsg ("missing pipe\n");
4774       return -99;
4775     }
4776
4777   if (profile_set == 0)
4778     {
4779       errmsg ("missing profile\n");
4780       return -99;
4781     }
4782
4783   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4784
4785   mp->sw_if_index = ntohl (sw_if_index);
4786   mp->subport = ntohl (subport);
4787   mp->pipe = ntohl (pipe);
4788   mp->profile = ntohl (profile);
4789
4790
4791   S;
4792   W;
4793   /* NOTREACHED */
4794   return 0;
4795 }
4796
4797 static int
4798 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4799 {
4800   unformat_input_t *i = vam->input;
4801   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4802   f64 timeout;
4803   u32 sw_if_index;
4804   u8 sw_if_index_set = 0;
4805   u32 subport;
4806   u8 subport_set = 0;
4807   u32 tb_rate = 1250000000;     /* 10GbE */
4808   u32 tb_size = 1000000;
4809   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4810   u32 tc_period = 10;
4811
4812   /* Parse args required to build the message */
4813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4814     {
4815       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4816         sw_if_index_set = 1;
4817       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4818         sw_if_index_set = 1;
4819       else if (unformat (i, "subport %u", &subport))
4820         subport_set = 1;
4821       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4822         sw_if_index_set = 1;
4823       else if (unformat (i, "rate %u", &tb_rate))
4824         {
4825           u32 tc_id;
4826
4827           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4828                tc_id++)
4829             tc_rate[tc_id] = tb_rate;
4830         }
4831       else if (unformat (i, "bktsize %u", &tb_size))
4832         ;
4833       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4834         ;
4835       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4836         ;
4837       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4838         ;
4839       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4840         ;
4841       else if (unformat (i, "period %u", &tc_period))
4842         ;
4843       else
4844         break;
4845     }
4846
4847   if (sw_if_index_set == 0)
4848     {
4849       errmsg ("missing interface name or sw_if_index\n");
4850       return -99;
4851     }
4852
4853   if (subport_set == 0)
4854     {
4855       errmsg ("missing subport \n");
4856       return -99;
4857     }
4858
4859   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4860
4861   mp->sw_if_index = ntohl (sw_if_index);
4862   mp->subport = ntohl (subport);
4863   mp->tb_rate = ntohl (tb_rate);
4864   mp->tb_size = ntohl (tb_size);
4865   mp->tc_rate[0] = ntohl (tc_rate[0]);
4866   mp->tc_rate[1] = ntohl (tc_rate[1]);
4867   mp->tc_rate[2] = ntohl (tc_rate[2]);
4868   mp->tc_rate[3] = ntohl (tc_rate[3]);
4869   mp->tc_period = ntohl (tc_period);
4870
4871   S;
4872   W;
4873   /* NOTREACHED */
4874   return 0;
4875 }
4876
4877 static int
4878 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4879 {
4880   unformat_input_t *i = vam->input;
4881   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4882   f64 timeout;
4883   u32 sw_if_index;
4884   u8 sw_if_index_set = 0;
4885   u8 entry_set = 0;
4886   u8 tc_set = 0;
4887   u8 queue_set = 0;
4888   u32 entry, tc, queue;
4889
4890   /* Parse args required to build the message */
4891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4892     {
4893       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4894         sw_if_index_set = 1;
4895       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4896         sw_if_index_set = 1;
4897       else if (unformat (i, "entry %d", &entry))
4898         entry_set = 1;
4899       else if (unformat (i, "tc %d", &tc))
4900         tc_set = 1;
4901       else if (unformat (i, "queue %d", &queue))
4902         queue_set = 1;
4903       else
4904         break;
4905     }
4906
4907   if (sw_if_index_set == 0)
4908     {
4909       errmsg ("missing interface name or sw_if_index\n");
4910       return -99;
4911     }
4912
4913   if (entry_set == 0)
4914     {
4915       errmsg ("missing entry \n");
4916       return -99;
4917     }
4918
4919   if (tc_set == 0)
4920     {
4921       errmsg ("missing traffic class \n");
4922       return -99;
4923     }
4924
4925   if (queue_set == 0)
4926     {
4927       errmsg ("missing queue \n");
4928       return -99;
4929     }
4930
4931   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4932
4933   mp->sw_if_index = ntohl (sw_if_index);
4934   mp->entry = ntohl (entry);
4935   mp->tc = ntohl (tc);
4936   mp->queue = ntohl (queue);
4937
4938   S;
4939   W;
4940   /* NOTREACHED */
4941   return 0;
4942 }
4943
4944 static int
4945 api_sw_interface_add_del_address (vat_main_t * vam)
4946 {
4947   unformat_input_t *i = vam->input;
4948   vl_api_sw_interface_add_del_address_t *mp;
4949   f64 timeout;
4950   u32 sw_if_index;
4951   u8 sw_if_index_set = 0;
4952   u8 is_add = 1, del_all = 0;
4953   u32 address_length = 0;
4954   u8 v4_address_set = 0;
4955   u8 v6_address_set = 0;
4956   ip4_address_t v4address;
4957   ip6_address_t v6address;
4958
4959   /* Parse args required to build the message */
4960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4961     {
4962       if (unformat (i, "del-all"))
4963         del_all = 1;
4964       else if (unformat (i, "del"))
4965         is_add = 0;
4966       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4967         sw_if_index_set = 1;
4968       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4969         sw_if_index_set = 1;
4970       else if (unformat (i, "%U/%d",
4971                          unformat_ip4_address, &v4address, &address_length))
4972         v4_address_set = 1;
4973       else if (unformat (i, "%U/%d",
4974                          unformat_ip6_address, &v6address, &address_length))
4975         v6_address_set = 1;
4976       else
4977         break;
4978     }
4979
4980   if (sw_if_index_set == 0)
4981     {
4982       errmsg ("missing interface name or sw_if_index\n");
4983       return -99;
4984     }
4985   if (v4_address_set && v6_address_set)
4986     {
4987       errmsg ("both v4 and v6 addresses set\n");
4988       return -99;
4989     }
4990   if (!v4_address_set && !v6_address_set && !del_all)
4991     {
4992       errmsg ("no addresses set\n");
4993       return -99;
4994     }
4995
4996   /* Construct the API message */
4997   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4998
4999   mp->sw_if_index = ntohl (sw_if_index);
5000   mp->is_add = is_add;
5001   mp->del_all = del_all;
5002   if (v6_address_set)
5003     {
5004       mp->is_ipv6 = 1;
5005       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5006     }
5007   else
5008     {
5009       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5010     }
5011   mp->address_length = address_length;
5012
5013   /* send it... */
5014   S;
5015
5016   /* Wait for a reply, return good/bad news  */
5017   W;
5018 }
5019
5020 static int
5021 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5022 {
5023   unformat_input_t *i = vam->input;
5024   vl_api_sw_interface_set_mpls_enable_t *mp;
5025   f64 timeout;
5026   u32 sw_if_index;
5027   u8 sw_if_index_set = 0;
5028   u8 enable = 1;
5029
5030   /* Parse args required to build the message */
5031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5032     {
5033       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5034         sw_if_index_set = 1;
5035       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5036         sw_if_index_set = 1;
5037       else if (unformat (i, "disable"))
5038         enable = 0;
5039       else if (unformat (i, "dis"))
5040         enable = 0;
5041       else
5042         break;
5043     }
5044
5045   if (sw_if_index_set == 0)
5046     {
5047       errmsg ("missing interface name or sw_if_index\n");
5048       return -99;
5049     }
5050
5051   /* Construct the API message */
5052   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
5053
5054   mp->sw_if_index = ntohl (sw_if_index);
5055   mp->enable = enable;
5056
5057   /* send it... */
5058   S;
5059
5060   /* Wait for a reply... */
5061   W;
5062 }
5063
5064 static int
5065 api_sw_interface_set_table (vat_main_t * vam)
5066 {
5067   unformat_input_t *i = vam->input;
5068   vl_api_sw_interface_set_table_t *mp;
5069   f64 timeout;
5070   u32 sw_if_index, vrf_id = 0;
5071   u8 sw_if_index_set = 0;
5072   u8 is_ipv6 = 0;
5073
5074   /* Parse args required to build the message */
5075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5076     {
5077       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5078         sw_if_index_set = 1;
5079       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5080         sw_if_index_set = 1;
5081       else if (unformat (i, "vrf %d", &vrf_id))
5082         ;
5083       else if (unformat (i, "ipv6"))
5084         is_ipv6 = 1;
5085       else
5086         break;
5087     }
5088
5089   if (sw_if_index_set == 0)
5090     {
5091       errmsg ("missing interface name or sw_if_index\n");
5092       return -99;
5093     }
5094
5095   /* Construct the API message */
5096   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
5097
5098   mp->sw_if_index = ntohl (sw_if_index);
5099   mp->is_ipv6 = is_ipv6;
5100   mp->vrf_id = ntohl (vrf_id);
5101
5102   /* send it... */
5103   S;
5104
5105   /* Wait for a reply... */
5106   W;
5107 }
5108
5109 static void vl_api_sw_interface_get_table_reply_t_handler
5110   (vl_api_sw_interface_get_table_reply_t * mp)
5111 {
5112   vat_main_t *vam = &vat_main;
5113
5114   fformat (vam->ofp, "%d\n", ntohl (mp->vrf_id));
5115
5116   vam->retval = ntohl (mp->retval);
5117   vam->result_ready = 1;
5118
5119 }
5120
5121 static void vl_api_sw_interface_get_table_reply_t_handler_json
5122   (vl_api_sw_interface_get_table_reply_t * mp)
5123 {
5124   vat_main_t *vam = &vat_main;
5125   vat_json_node_t node;
5126
5127   vat_json_init_object (&node);
5128   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5129   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5130
5131   vat_json_print (vam->ofp, &node);
5132   vat_json_free (&node);
5133
5134   vam->retval = ntohl (mp->retval);
5135   vam->result_ready = 1;
5136 }
5137
5138 static int
5139 api_sw_interface_get_table (vat_main_t * vam)
5140 {
5141   unformat_input_t *i = vam->input;
5142   vl_api_sw_interface_get_table_t *mp;
5143   u32 sw_if_index;
5144   u8 sw_if_index_set = 0;
5145   u8 is_ipv6 = 0;
5146   f64 timeout;
5147
5148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5149     {
5150       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5151         sw_if_index_set = 1;
5152       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5153         sw_if_index_set = 1;
5154       else if (unformat (i, "ipv6"))
5155         is_ipv6 = 1;
5156       else
5157         break;
5158     }
5159
5160   if (sw_if_index_set == 0)
5161     {
5162       errmsg ("missing interface name or sw_if_index\n");
5163       return -99;
5164     }
5165
5166   M (SW_INTERFACE_GET_TABLE, sw_interface_get_table);
5167   mp->sw_if_index = htonl (sw_if_index);
5168   mp->is_ipv6 = is_ipv6;
5169
5170   S;
5171   W;
5172 }
5173
5174 static int
5175 api_sw_interface_set_vpath (vat_main_t * vam)
5176 {
5177   unformat_input_t *i = vam->input;
5178   vl_api_sw_interface_set_vpath_t *mp;
5179   f64 timeout;
5180   u32 sw_if_index = 0;
5181   u8 sw_if_index_set = 0;
5182   u8 is_enable = 0;
5183
5184   /* Parse args required to build the message */
5185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5186     {
5187       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5188         sw_if_index_set = 1;
5189       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5190         sw_if_index_set = 1;
5191       else if (unformat (i, "enable"))
5192         is_enable = 1;
5193       else if (unformat (i, "disable"))
5194         is_enable = 0;
5195       else
5196         break;
5197     }
5198
5199   if (sw_if_index_set == 0)
5200     {
5201       errmsg ("missing interface name or sw_if_index\n");
5202       return -99;
5203     }
5204
5205   /* Construct the API message */
5206   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5207
5208   mp->sw_if_index = ntohl (sw_if_index);
5209   mp->enable = is_enable;
5210
5211   /* send it... */
5212   S;
5213
5214   /* Wait for a reply... */
5215   W;
5216 }
5217
5218 static int
5219 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5220 {
5221   unformat_input_t *i = vam->input;
5222   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5223   f64 timeout;
5224   u32 sw_if_index = 0;
5225   u8 sw_if_index_set = 0;
5226   u8 is_enable = 0;
5227   u8 is_ipv6 = 0;
5228
5229   /* Parse args required to build the message */
5230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5231     {
5232       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5233         sw_if_index_set = 1;
5234       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5235         sw_if_index_set = 1;
5236       else if (unformat (i, "enable"))
5237         is_enable = 1;
5238       else if (unformat (i, "disable"))
5239         is_enable = 0;
5240       else if (unformat (i, "ip4"))
5241         is_ipv6 = 0;
5242       else if (unformat (i, "ip6"))
5243         is_ipv6 = 1;
5244       else
5245         break;
5246     }
5247
5248   if (sw_if_index_set == 0)
5249     {
5250       errmsg ("missing interface name or sw_if_index\n");
5251       return -99;
5252     }
5253
5254   /* Construct the API message */
5255   M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5256
5257   mp->sw_if_index = ntohl (sw_if_index);
5258   mp->enable = is_enable;
5259   mp->is_ipv6 = is_ipv6;
5260
5261   /* send it... */
5262   S;
5263
5264   /* Wait for a reply... */
5265   W;
5266 }
5267
5268 static int
5269 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5270 {
5271   unformat_input_t *i = vam->input;
5272   vl_api_sw_interface_set_l2_xconnect_t *mp;
5273   f64 timeout;
5274   u32 rx_sw_if_index;
5275   u8 rx_sw_if_index_set = 0;
5276   u32 tx_sw_if_index;
5277   u8 tx_sw_if_index_set = 0;
5278   u8 enable = 1;
5279
5280   /* Parse args required to build the message */
5281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5282     {
5283       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5284         rx_sw_if_index_set = 1;
5285       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5286         tx_sw_if_index_set = 1;
5287       else if (unformat (i, "rx"))
5288         {
5289           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5290             {
5291               if (unformat (i, "%U", unformat_sw_if_index, vam,
5292                             &rx_sw_if_index))
5293                 rx_sw_if_index_set = 1;
5294             }
5295           else
5296             break;
5297         }
5298       else if (unformat (i, "tx"))
5299         {
5300           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5301             {
5302               if (unformat (i, "%U", unformat_sw_if_index, vam,
5303                             &tx_sw_if_index))
5304                 tx_sw_if_index_set = 1;
5305             }
5306           else
5307             break;
5308         }
5309       else if (unformat (i, "enable"))
5310         enable = 1;
5311       else if (unformat (i, "disable"))
5312         enable = 0;
5313       else
5314         break;
5315     }
5316
5317   if (rx_sw_if_index_set == 0)
5318     {
5319       errmsg ("missing rx interface name or rx_sw_if_index\n");
5320       return -99;
5321     }
5322
5323   if (enable && (tx_sw_if_index_set == 0))
5324     {
5325       errmsg ("missing tx interface name or tx_sw_if_index\n");
5326       return -99;
5327     }
5328
5329   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5330
5331   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5332   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5333   mp->enable = enable;
5334
5335   S;
5336   W;
5337   /* NOTREACHED */
5338   return 0;
5339 }
5340
5341 static int
5342 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5343 {
5344   unformat_input_t *i = vam->input;
5345   vl_api_sw_interface_set_l2_bridge_t *mp;
5346   f64 timeout;
5347   u32 rx_sw_if_index;
5348   u8 rx_sw_if_index_set = 0;
5349   u32 bd_id;
5350   u8 bd_id_set = 0;
5351   u8 bvi = 0;
5352   u32 shg = 0;
5353   u8 enable = 1;
5354
5355   /* Parse args required to build the message */
5356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5357     {
5358       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5359         rx_sw_if_index_set = 1;
5360       else if (unformat (i, "bd_id %d", &bd_id))
5361         bd_id_set = 1;
5362       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5363         rx_sw_if_index_set = 1;
5364       else if (unformat (i, "shg %d", &shg))
5365         ;
5366       else if (unformat (i, "bvi"))
5367         bvi = 1;
5368       else if (unformat (i, "enable"))
5369         enable = 1;
5370       else if (unformat (i, "disable"))
5371         enable = 0;
5372       else
5373         break;
5374     }
5375
5376   if (rx_sw_if_index_set == 0)
5377     {
5378       errmsg ("missing rx interface name or sw_if_index\n");
5379       return -99;
5380     }
5381
5382   if (enable && (bd_id_set == 0))
5383     {
5384       errmsg ("missing bridge domain\n");
5385       return -99;
5386     }
5387
5388   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5389
5390   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5391   mp->bd_id = ntohl (bd_id);
5392   mp->shg = (u8) shg;
5393   mp->bvi = bvi;
5394   mp->enable = enable;
5395
5396   S;
5397   W;
5398   /* NOTREACHED */
5399   return 0;
5400 }
5401
5402 static int
5403 api_bridge_domain_dump (vat_main_t * vam)
5404 {
5405   unformat_input_t *i = vam->input;
5406   vl_api_bridge_domain_dump_t *mp;
5407   f64 timeout;
5408   u32 bd_id = ~0;
5409
5410   /* Parse args required to build the message */
5411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5412     {
5413       if (unformat (i, "bd_id %d", &bd_id))
5414         ;
5415       else
5416         break;
5417     }
5418
5419   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5420   mp->bd_id = ntohl (bd_id);
5421   S;
5422
5423   /* Use a control ping for synchronization */
5424   {
5425     vl_api_control_ping_t *mp;
5426     M (CONTROL_PING, control_ping);
5427     S;
5428   }
5429
5430   W;
5431   /* NOTREACHED */
5432   return 0;
5433 }
5434
5435 static int
5436 api_bridge_domain_add_del (vat_main_t * vam)
5437 {
5438   unformat_input_t *i = vam->input;
5439   vl_api_bridge_domain_add_del_t *mp;
5440   f64 timeout;
5441   u32 bd_id = ~0;
5442   u8 is_add = 1;
5443   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5444   u32 mac_age = 0;
5445
5446   /* Parse args required to build the message */
5447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5448     {
5449       if (unformat (i, "bd_id %d", &bd_id))
5450         ;
5451       else if (unformat (i, "flood %d", &flood))
5452         ;
5453       else if (unformat (i, "uu-flood %d", &uu_flood))
5454         ;
5455       else if (unformat (i, "forward %d", &forward))
5456         ;
5457       else if (unformat (i, "learn %d", &learn))
5458         ;
5459       else if (unformat (i, "arp-term %d", &arp_term))
5460         ;
5461       else if (unformat (i, "mac-age %d", &mac_age))
5462         ;
5463       else if (unformat (i, "del"))
5464         {
5465           is_add = 0;
5466           flood = uu_flood = forward = learn = 0;
5467         }
5468       else
5469         break;
5470     }
5471
5472   if (bd_id == ~0)
5473     {
5474       errmsg ("missing bridge domain\n");
5475       return -99;
5476     }
5477
5478   if (mac_age > 255)
5479     {
5480       errmsg ("mac age must be less than 256 \n");
5481       return -99;
5482     }
5483
5484   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5485
5486   mp->bd_id = ntohl (bd_id);
5487   mp->flood = flood;
5488   mp->uu_flood = uu_flood;
5489   mp->forward = forward;
5490   mp->learn = learn;
5491   mp->arp_term = arp_term;
5492   mp->is_add = is_add;
5493   mp->mac_age = (u8) mac_age;
5494
5495   S;
5496   W;
5497   /* NOTREACHED */
5498   return 0;
5499 }
5500
5501 static int
5502 api_l2fib_add_del (vat_main_t * vam)
5503 {
5504   unformat_input_t *i = vam->input;
5505   vl_api_l2fib_add_del_t *mp;
5506   f64 timeout;
5507   u64 mac = 0;
5508   u8 mac_set = 0;
5509   u32 bd_id;
5510   u8 bd_id_set = 0;
5511   u32 sw_if_index = ~0;
5512   u8 sw_if_index_set = 0;
5513   u8 is_add = 1;
5514   u8 static_mac = 0;
5515   u8 filter_mac = 0;
5516   u8 bvi_mac = 0;
5517   int count = 1;
5518   f64 before = 0;
5519   int j;
5520
5521   /* Parse args required to build the message */
5522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5523     {
5524       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5525         mac_set = 1;
5526       else if (unformat (i, "bd_id %d", &bd_id))
5527         bd_id_set = 1;
5528       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5529         sw_if_index_set = 1;
5530       else if (unformat (i, "sw_if"))
5531         {
5532           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5533             {
5534               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5535                 sw_if_index_set = 1;
5536             }
5537           else
5538             break;
5539         }
5540       else if (unformat (i, "static"))
5541         static_mac = 1;
5542       else if (unformat (i, "filter"))
5543         {
5544           filter_mac = 1;
5545           static_mac = 1;
5546         }
5547       else if (unformat (i, "bvi"))
5548         {
5549           bvi_mac = 1;
5550           static_mac = 1;
5551         }
5552       else if (unformat (i, "del"))
5553         is_add = 0;
5554       else if (unformat (i, "count %d", &count))
5555         ;
5556       else
5557         break;
5558     }
5559
5560   if (mac_set == 0)
5561     {
5562       errmsg ("missing mac address\n");
5563       return -99;
5564     }
5565
5566   if (bd_id_set == 0)
5567     {
5568       errmsg ("missing bridge domain\n");
5569       return -99;
5570     }
5571
5572   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5573     {
5574       errmsg ("missing interface name or sw_if_index\n");
5575       return -99;
5576     }
5577
5578   if (count > 1)
5579     {
5580       /* Turn on async mode */
5581       vam->async_mode = 1;
5582       vam->async_errors = 0;
5583       before = vat_time_now (vam);
5584     }
5585
5586   for (j = 0; j < count; j++)
5587     {
5588       M (L2FIB_ADD_DEL, l2fib_add_del);
5589
5590       mp->mac = mac;
5591       mp->bd_id = ntohl (bd_id);
5592       mp->is_add = is_add;
5593
5594       if (is_add)
5595         {
5596           mp->sw_if_index = ntohl (sw_if_index);
5597           mp->static_mac = static_mac;
5598           mp->filter_mac = filter_mac;
5599           mp->bvi_mac = bvi_mac;
5600         }
5601       increment_mac_address (&mac);
5602       /* send it... */
5603       S;
5604     }
5605
5606   if (count > 1)
5607     {
5608       vl_api_control_ping_t *mp;
5609       f64 after;
5610
5611       /* Shut off async mode */
5612       vam->async_mode = 0;
5613
5614       M (CONTROL_PING, control_ping);
5615       S;
5616
5617       timeout = vat_time_now (vam) + 1.0;
5618       while (vat_time_now (vam) < timeout)
5619         if (vam->result_ready == 1)
5620           goto out;
5621       vam->retval = -99;
5622
5623     out:
5624       if (vam->retval == -99)
5625         errmsg ("timeout\n");
5626
5627       if (vam->async_errors > 0)
5628         {
5629           errmsg ("%d asynchronous errors\n", vam->async_errors);
5630           vam->retval = -98;
5631         }
5632       vam->async_errors = 0;
5633       after = vat_time_now (vam);
5634
5635       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5636                count, after - before, count / (after - before));
5637     }
5638   else
5639     {
5640       /* Wait for a reply... */
5641       W;
5642     }
5643   /* Return the good/bad news */
5644   return (vam->retval);
5645 }
5646
5647 static int
5648 api_l2_flags (vat_main_t * vam)
5649 {
5650   unformat_input_t *i = vam->input;
5651   vl_api_l2_flags_t *mp;
5652   f64 timeout;
5653   u32 sw_if_index;
5654   u32 feature_bitmap = 0;
5655   u8 sw_if_index_set = 0;
5656
5657   /* Parse args required to build the message */
5658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5659     {
5660       if (unformat (i, "sw_if_index %d", &sw_if_index))
5661         sw_if_index_set = 1;
5662       else if (unformat (i, "sw_if"))
5663         {
5664           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5665             {
5666               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5667                 sw_if_index_set = 1;
5668             }
5669           else
5670             break;
5671         }
5672       else if (unformat (i, "learn"))
5673         feature_bitmap |= L2INPUT_FEAT_LEARN;
5674       else if (unformat (i, "forward"))
5675         feature_bitmap |= L2INPUT_FEAT_FWD;
5676       else if (unformat (i, "flood"))
5677         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5678       else if (unformat (i, "uu-flood"))
5679         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5680       else
5681         break;
5682     }
5683
5684   if (sw_if_index_set == 0)
5685     {
5686       errmsg ("missing interface name or sw_if_index\n");
5687       return -99;
5688     }
5689
5690   M (L2_FLAGS, l2_flags);
5691
5692   mp->sw_if_index = ntohl (sw_if_index);
5693   mp->feature_bitmap = ntohl (feature_bitmap);
5694
5695   S;
5696   W;
5697   /* NOTREACHED */
5698   return 0;
5699 }
5700
5701 static int
5702 api_bridge_flags (vat_main_t * vam)
5703 {
5704   unformat_input_t *i = vam->input;
5705   vl_api_bridge_flags_t *mp;
5706   f64 timeout;
5707   u32 bd_id;
5708   u8 bd_id_set = 0;
5709   u8 is_set = 1;
5710   u32 flags = 0;
5711
5712   /* Parse args required to build the message */
5713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5714     {
5715       if (unformat (i, "bd_id %d", &bd_id))
5716         bd_id_set = 1;
5717       else if (unformat (i, "learn"))
5718         flags |= L2_LEARN;
5719       else if (unformat (i, "forward"))
5720         flags |= L2_FWD;
5721       else if (unformat (i, "flood"))
5722         flags |= L2_FLOOD;
5723       else if (unformat (i, "uu-flood"))
5724         flags |= L2_UU_FLOOD;
5725       else if (unformat (i, "arp-term"))
5726         flags |= L2_ARP_TERM;
5727       else if (unformat (i, "off"))
5728         is_set = 0;
5729       else if (unformat (i, "disable"))
5730         is_set = 0;
5731       else
5732         break;
5733     }
5734
5735   if (bd_id_set == 0)
5736     {
5737       errmsg ("missing bridge domain\n");
5738       return -99;
5739     }
5740
5741   M (BRIDGE_FLAGS, bridge_flags);
5742
5743   mp->bd_id = ntohl (bd_id);
5744   mp->feature_bitmap = ntohl (flags);
5745   mp->is_set = is_set;
5746
5747   S;
5748   W;
5749   /* NOTREACHED */
5750   return 0;
5751 }
5752
5753 static int
5754 api_bd_ip_mac_add_del (vat_main_t * vam)
5755 {
5756   unformat_input_t *i = vam->input;
5757   vl_api_bd_ip_mac_add_del_t *mp;
5758   f64 timeout;
5759   u32 bd_id;
5760   u8 is_ipv6 = 0;
5761   u8 is_add = 1;
5762   u8 bd_id_set = 0;
5763   u8 ip_set = 0;
5764   u8 mac_set = 0;
5765   ip4_address_t v4addr;
5766   ip6_address_t v6addr;
5767   u8 macaddr[6];
5768
5769
5770   /* Parse args required to build the message */
5771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5772     {
5773       if (unformat (i, "bd_id %d", &bd_id))
5774         {
5775           bd_id_set++;
5776         }
5777       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5778         {
5779           ip_set++;
5780         }
5781       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5782         {
5783           ip_set++;
5784           is_ipv6++;
5785         }
5786       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5787         {
5788           mac_set++;
5789         }
5790       else if (unformat (i, "del"))
5791         is_add = 0;
5792       else
5793         break;
5794     }
5795
5796   if (bd_id_set == 0)
5797     {
5798       errmsg ("missing bridge domain\n");
5799       return -99;
5800     }
5801   else if (ip_set == 0)
5802     {
5803       errmsg ("missing IP address\n");
5804       return -99;
5805     }
5806   else if (mac_set == 0)
5807     {
5808       errmsg ("missing MAC address\n");
5809       return -99;
5810     }
5811
5812   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5813
5814   mp->bd_id = ntohl (bd_id);
5815   mp->is_ipv6 = is_ipv6;
5816   mp->is_add = is_add;
5817   if (is_ipv6)
5818     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5819   else
5820     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5821   clib_memcpy (mp->mac_address, macaddr, 6);
5822   S;
5823   W;
5824   /* NOTREACHED */
5825   return 0;
5826 }
5827
5828 static int
5829 api_tap_connect (vat_main_t * vam)
5830 {
5831   unformat_input_t *i = vam->input;
5832   vl_api_tap_connect_t *mp;
5833   f64 timeout;
5834   u8 mac_address[6];
5835   u8 random_mac = 1;
5836   u8 name_set = 0;
5837   u8 *tap_name;
5838   u8 *tag = 0;
5839
5840   memset (mac_address, 0, sizeof (mac_address));
5841
5842   /* Parse args required to build the message */
5843   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5844     {
5845       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5846         {
5847           random_mac = 0;
5848         }
5849       else if (unformat (i, "random-mac"))
5850         random_mac = 1;
5851       else if (unformat (i, "tapname %s", &tap_name))
5852         name_set = 1;
5853       else if (unformat (i, "tag %s", &tag))
5854         ;
5855       else
5856         break;
5857     }
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       return -99;
5868     }
5869   vec_add1 (tap_name, 0);
5870
5871   if (vec_len (tag) > 63)
5872     {
5873       errmsg ("tag too long\n");
5874       return -99;
5875     }
5876
5877   /* Construct the API message */
5878   M (TAP_CONNECT, tap_connect);
5879
5880   mp->use_random_mac = random_mac;
5881   clib_memcpy (mp->mac_address, mac_address, 6);
5882   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5883   if (tag)
5884     clib_memcpy (mp->tag, tag, vec_len (tag));
5885
5886   vec_free (tap_name);
5887   vec_free (tag);
5888
5889   /* send it... */
5890   S;
5891
5892   /* Wait for a reply... */
5893   W;
5894 }
5895
5896 static int
5897 api_tap_modify (vat_main_t * vam)
5898 {
5899   unformat_input_t *i = vam->input;
5900   vl_api_tap_modify_t *mp;
5901   f64 timeout;
5902   u8 mac_address[6];
5903   u8 random_mac = 1;
5904   u8 name_set = 0;
5905   u8 *tap_name;
5906   u32 sw_if_index = ~0;
5907   u8 sw_if_index_set = 0;
5908
5909   memset (mac_address, 0, sizeof (mac_address));
5910
5911   /* Parse args required to build the message */
5912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5913     {
5914       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5915         sw_if_index_set = 1;
5916       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5917         sw_if_index_set = 1;
5918       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5919         {
5920           random_mac = 0;
5921         }
5922       else if (unformat (i, "random-mac"))
5923         random_mac = 1;
5924       else if (unformat (i, "tapname %s", &tap_name))
5925         name_set = 1;
5926       else
5927         break;
5928     }
5929
5930   if (sw_if_index_set == 0)
5931     {
5932       errmsg ("missing vpp interface name");
5933       return -99;
5934     }
5935   if (name_set == 0)
5936     {
5937       errmsg ("missing tap name\n");
5938       return -99;
5939     }
5940   if (vec_len (tap_name) > 63)
5941     {
5942       errmsg ("tap name too long\n");
5943     }
5944   vec_add1 (tap_name, 0);
5945
5946   /* Construct the API message */
5947   M (TAP_MODIFY, tap_modify);
5948
5949   mp->use_random_mac = random_mac;
5950   mp->sw_if_index = ntohl (sw_if_index);
5951   clib_memcpy (mp->mac_address, mac_address, 6);
5952   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5953   vec_free (tap_name);
5954
5955   /* send it... */
5956   S;
5957
5958   /* Wait for a reply... */
5959   W;
5960 }
5961
5962 static int
5963 api_tap_delete (vat_main_t * vam)
5964 {
5965   unformat_input_t *i = vam->input;
5966   vl_api_tap_delete_t *mp;
5967   f64 timeout;
5968   u32 sw_if_index = ~0;
5969   u8 sw_if_index_set = 0;
5970
5971   /* Parse args required to build the message */
5972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5973     {
5974       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5975         sw_if_index_set = 1;
5976       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5977         sw_if_index_set = 1;
5978       else
5979         break;
5980     }
5981
5982   if (sw_if_index_set == 0)
5983     {
5984       errmsg ("missing vpp interface name");
5985       return -99;
5986     }
5987
5988   /* Construct the API message */
5989   M (TAP_DELETE, tap_delete);
5990
5991   mp->sw_if_index = ntohl (sw_if_index);
5992
5993   /* send it... */
5994   S;
5995
5996   /* Wait for a reply... */
5997   W;
5998 }
5999
6000 static int
6001 api_ip_add_del_route (vat_main_t * vam)
6002 {
6003   unformat_input_t *i = vam->input;
6004   vl_api_ip_add_del_route_t *mp;
6005   f64 timeout;
6006   u32 sw_if_index = ~0, vrf_id = 0;
6007   u8 is_ipv6 = 0;
6008   u8 is_local = 0, is_drop = 0;
6009   u8 is_unreach = 0, is_prohibit = 0;
6010   u8 create_vrf_if_needed = 0;
6011   u8 is_add = 1;
6012   u32 next_hop_weight = 1;
6013   u8 not_last = 0;
6014   u8 is_multipath = 0;
6015   u8 address_set = 0;
6016   u8 address_length_set = 0;
6017   u32 next_hop_table_id = 0;
6018   u32 resolve_attempts = 0;
6019   u32 dst_address_length = 0;
6020   u8 next_hop_set = 0;
6021   ip4_address_t v4_dst_address, v4_next_hop_address;
6022   ip6_address_t v6_dst_address, v6_next_hop_address;
6023   int count = 1;
6024   int j;
6025   f64 before = 0;
6026   u32 random_add_del = 0;
6027   u32 *random_vector = 0;
6028   uword *random_hash;
6029   u32 random_seed = 0xdeaddabe;
6030   u32 classify_table_index = ~0;
6031   u8 is_classify = 0;
6032   u8 resolve_host = 0, resolve_attached = 0;
6033   mpls_label_t *next_hop_out_label_stack = NULL;
6034   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6035   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6036
6037   /* Parse args required to build the message */
6038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6039     {
6040       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6041         ;
6042       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6043         ;
6044       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6045         {
6046           address_set = 1;
6047           is_ipv6 = 0;
6048         }
6049       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6050         {
6051           address_set = 1;
6052           is_ipv6 = 1;
6053         }
6054       else if (unformat (i, "/%d", &dst_address_length))
6055         {
6056           address_length_set = 1;
6057         }
6058
6059       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6060                                          &v4_next_hop_address))
6061         {
6062           next_hop_set = 1;
6063         }
6064       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6065                                          &v6_next_hop_address))
6066         {
6067           next_hop_set = 1;
6068         }
6069       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6070         ;
6071       else if (unformat (i, "weight %d", &next_hop_weight))
6072         ;
6073       else if (unformat (i, "drop"))
6074         {
6075           is_drop = 1;
6076         }
6077       else if (unformat (i, "null-send-unreach"))
6078         {
6079           is_unreach = 1;
6080         }
6081       else if (unformat (i, "null-send-prohibit"))
6082         {
6083           is_prohibit = 1;
6084         }
6085       else if (unformat (i, "local"))
6086         {
6087           is_local = 1;
6088         }
6089       else if (unformat (i, "classify %d", &classify_table_index))
6090         {
6091           is_classify = 1;
6092         }
6093       else if (unformat (i, "del"))
6094         is_add = 0;
6095       else if (unformat (i, "add"))
6096         is_add = 1;
6097       else if (unformat (i, "not-last"))
6098         not_last = 1;
6099       else if (unformat (i, "resolve-via-host"))
6100         resolve_host = 1;
6101       else if (unformat (i, "resolve-via-attached"))
6102         resolve_attached = 1;
6103       else if (unformat (i, "multipath"))
6104         is_multipath = 1;
6105       else if (unformat (i, "vrf %d", &vrf_id))
6106         ;
6107       else if (unformat (i, "create-vrf"))
6108         create_vrf_if_needed = 1;
6109       else if (unformat (i, "count %d", &count))
6110         ;
6111       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6112         ;
6113       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6114         ;
6115       else if (unformat (i, "out-label %d", &next_hop_out_label))
6116         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6117       else if (unformat (i, "via-label %d", &next_hop_via_label))
6118         ;
6119       else if (unformat (i, "random"))
6120         random_add_del = 1;
6121       else if (unformat (i, "seed %d", &random_seed))
6122         ;
6123       else
6124         {
6125           clib_warning ("parse error '%U'", format_unformat_error, i);
6126           return -99;
6127         }
6128     }
6129
6130   if (!next_hop_set && !is_drop && !is_local &&
6131       !is_classify && !is_unreach && !is_prohibit &&
6132       MPLS_LABEL_INVALID == next_hop_via_label)
6133     {
6134       errmsg
6135         ("next hop / local / drop / unreach / prohibit / classify not set\n");
6136       return -99;
6137     }
6138
6139   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6140     {
6141       errmsg ("next hop and next-hop via label set\n");
6142       return -99;
6143     }
6144   if (address_set == 0)
6145     {
6146       errmsg ("missing addresses\n");
6147       return -99;
6148     }
6149
6150   if (address_length_set == 0)
6151     {
6152       errmsg ("missing address length\n");
6153       return -99;
6154     }
6155
6156   /* Generate a pile of unique, random routes */
6157   if (random_add_del)
6158     {
6159       u32 this_random_address;
6160       random_hash = hash_create (count, sizeof (uword));
6161
6162       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6163       for (j = 0; j <= count; j++)
6164         {
6165           do
6166             {
6167               this_random_address = random_u32 (&random_seed);
6168               this_random_address =
6169                 clib_host_to_net_u32 (this_random_address);
6170             }
6171           while (hash_get (random_hash, this_random_address));
6172           vec_add1 (random_vector, this_random_address);
6173           hash_set (random_hash, this_random_address, 1);
6174         }
6175       hash_free (random_hash);
6176       v4_dst_address.as_u32 = random_vector[0];
6177     }
6178
6179   if (count > 1)
6180     {
6181       /* Turn on async mode */
6182       vam->async_mode = 1;
6183       vam->async_errors = 0;
6184       before = vat_time_now (vam);
6185     }
6186
6187   for (j = 0; j < count; j++)
6188     {
6189       /* Construct the API message */
6190       M2 (IP_ADD_DEL_ROUTE, ip_add_del_route,
6191           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6192
6193       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6194       mp->table_id = ntohl (vrf_id);
6195       mp->create_vrf_if_needed = create_vrf_if_needed;
6196
6197       mp->is_add = is_add;
6198       mp->is_drop = is_drop;
6199       mp->is_unreach = is_unreach;
6200       mp->is_prohibit = is_prohibit;
6201       mp->is_ipv6 = is_ipv6;
6202       mp->is_local = is_local;
6203       mp->is_classify = is_classify;
6204       mp->is_multipath = is_multipath;
6205       mp->is_resolve_host = resolve_host;
6206       mp->is_resolve_attached = resolve_attached;
6207       mp->not_last = not_last;
6208       mp->next_hop_weight = next_hop_weight;
6209       mp->dst_address_length = dst_address_length;
6210       mp->next_hop_table_id = ntohl (next_hop_table_id);
6211       mp->classify_table_index = ntohl (classify_table_index);
6212       mp->next_hop_via_label = ntohl (next_hop_via_label);
6213       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6214       if (0 != mp->next_hop_n_out_labels)
6215         {
6216           memcpy (mp->next_hop_out_label_stack,
6217                   next_hop_out_label_stack,
6218                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6219           vec_free (next_hop_out_label_stack);
6220         }
6221
6222       if (is_ipv6)
6223         {
6224           clib_memcpy (mp->dst_address, &v6_dst_address,
6225                        sizeof (v6_dst_address));
6226           if (next_hop_set)
6227             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6228                          sizeof (v6_next_hop_address));
6229           increment_v6_address (&v6_dst_address);
6230         }
6231       else
6232         {
6233           clib_memcpy (mp->dst_address, &v4_dst_address,
6234                        sizeof (v4_dst_address));
6235           if (next_hop_set)
6236             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6237                          sizeof (v4_next_hop_address));
6238           if (random_add_del)
6239             v4_dst_address.as_u32 = random_vector[j + 1];
6240           else
6241             increment_v4_address (&v4_dst_address);
6242         }
6243       /* send it... */
6244       S;
6245       /* If we receive SIGTERM, stop now... */
6246       if (vam->do_exit)
6247         break;
6248     }
6249
6250   /* When testing multiple add/del ops, use a control-ping to sync */
6251   if (count > 1)
6252     {
6253       vl_api_control_ping_t *mp;
6254       f64 after;
6255
6256       /* Shut off async mode */
6257       vam->async_mode = 0;
6258
6259       M (CONTROL_PING, control_ping);
6260       S;
6261
6262       timeout = vat_time_now (vam) + 1.0;
6263       while (vat_time_now (vam) < timeout)
6264         if (vam->result_ready == 1)
6265           goto out;
6266       vam->retval = -99;
6267
6268     out:
6269       if (vam->retval == -99)
6270         errmsg ("timeout\n");
6271
6272       if (vam->async_errors > 0)
6273         {
6274           errmsg ("%d asynchronous errors\n", vam->async_errors);
6275           vam->retval = -98;
6276         }
6277       vam->async_errors = 0;
6278       after = vat_time_now (vam);
6279
6280       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6281       if (j > 0)
6282         count = j;
6283
6284       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6285                count, after - before, count / (after - before));
6286     }
6287   else
6288     {
6289       /* Wait for a reply... */
6290       W;
6291     }
6292
6293   /* Return the good/bad news */
6294   return (vam->retval);
6295 }
6296
6297 static int
6298 api_mpls_route_add_del (vat_main_t * vam)
6299 {
6300   unformat_input_t *i = vam->input;
6301   vl_api_mpls_route_add_del_t *mp;
6302   f64 timeout;
6303   u32 sw_if_index = ~0, table_id = 0;
6304   u8 create_table_if_needed = 0;
6305   u8 is_add = 1;
6306   u32 next_hop_weight = 1;
6307   u8 is_multipath = 0;
6308   u32 next_hop_table_id = 0;
6309   u8 next_hop_set = 0;
6310   ip4_address_t v4_next_hop_address = {
6311     .as_u32 = 0,
6312   };
6313   ip6_address_t v6_next_hop_address = { {0} };
6314   int count = 1;
6315   int j;
6316   f64 before = 0;
6317   u32 classify_table_index = ~0;
6318   u8 is_classify = 0;
6319   u8 resolve_host = 0, resolve_attached = 0;
6320   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6321   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6322   mpls_label_t *next_hop_out_label_stack = NULL;
6323   mpls_label_t local_label = MPLS_LABEL_INVALID;
6324   u8 is_eos = 0;
6325   u8 next_hop_proto_is_ip4 = 1;
6326
6327   /* Parse args required to build the message */
6328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6329     {
6330       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6331         ;
6332       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6333         ;
6334       else if (unformat (i, "%d", &local_label))
6335         ;
6336       else if (unformat (i, "eos"))
6337         is_eos = 1;
6338       else if (unformat (i, "non-eos"))
6339         is_eos = 0;
6340       else if (unformat (i, "via %U", unformat_ip4_address,
6341                          &v4_next_hop_address))
6342         {
6343           next_hop_set = 1;
6344           next_hop_proto_is_ip4 = 1;
6345         }
6346       else if (unformat (i, "via %U", unformat_ip6_address,
6347                          &v6_next_hop_address))
6348         {
6349           next_hop_set = 1;
6350           next_hop_proto_is_ip4 = 0;
6351         }
6352       else if (unformat (i, "weight %d", &next_hop_weight))
6353         ;
6354       else if (unformat (i, "create-table"))
6355         create_table_if_needed = 1;
6356       else if (unformat (i, "classify %d", &classify_table_index))
6357         {
6358           is_classify = 1;
6359         }
6360       else if (unformat (i, "del"))
6361         is_add = 0;
6362       else if (unformat (i, "add"))
6363         is_add = 1;
6364       else if (unformat (i, "resolve-via-host"))
6365         resolve_host = 1;
6366       else if (unformat (i, "resolve-via-attached"))
6367         resolve_attached = 1;
6368       else if (unformat (i, "multipath"))
6369         is_multipath = 1;
6370       else if (unformat (i, "count %d", &count))
6371         ;
6372       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6373         {
6374           next_hop_set = 1;
6375           next_hop_proto_is_ip4 = 1;
6376         }
6377       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6378         {
6379           next_hop_set = 1;
6380           next_hop_proto_is_ip4 = 0;
6381         }
6382       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6383         ;
6384       else if (unformat (i, "via-label %d", &next_hop_via_label))
6385         ;
6386       else if (unformat (i, "out-label %d", &next_hop_out_label))
6387         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6388       else
6389         {
6390           clib_warning ("parse error '%U'", format_unformat_error, i);
6391           return -99;
6392         }
6393     }
6394
6395   if (!next_hop_set && !is_classify)
6396     {
6397       errmsg ("next hop / classify not set\n");
6398       return -99;
6399     }
6400
6401   if (MPLS_LABEL_INVALID == local_label)
6402     {
6403       errmsg ("missing label\n");
6404       return -99;
6405     }
6406
6407   if (count > 1)
6408     {
6409       /* Turn on async mode */
6410       vam->async_mode = 1;
6411       vam->async_errors = 0;
6412       before = vat_time_now (vam);
6413     }
6414
6415   for (j = 0; j < count; j++)
6416     {
6417       /* Construct the API message */
6418       M2 (MPLS_ROUTE_ADD_DEL, mpls_route_add_del,
6419           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6420
6421       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6422       mp->mr_table_id = ntohl (table_id);
6423       mp->mr_create_table_if_needed = create_table_if_needed;
6424
6425       mp->mr_is_add = is_add;
6426       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6427       mp->mr_is_classify = is_classify;
6428       mp->mr_is_multipath = is_multipath;
6429       mp->mr_is_resolve_host = resolve_host;
6430       mp->mr_is_resolve_attached = resolve_attached;
6431       mp->mr_next_hop_weight = next_hop_weight;
6432       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6433       mp->mr_classify_table_index = ntohl (classify_table_index);
6434       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6435       mp->mr_label = ntohl (local_label);
6436       mp->mr_eos = is_eos;
6437
6438       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6439       if (0 != mp->mr_next_hop_n_out_labels)
6440         {
6441           memcpy (mp->mr_next_hop_out_label_stack,
6442                   next_hop_out_label_stack,
6443                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6444           vec_free (next_hop_out_label_stack);
6445         }
6446
6447       if (next_hop_set)
6448         {
6449           if (next_hop_proto_is_ip4)
6450             {
6451               clib_memcpy (mp->mr_next_hop,
6452                            &v4_next_hop_address,
6453                            sizeof (v4_next_hop_address));
6454             }
6455           else
6456             {
6457               clib_memcpy (mp->mr_next_hop,
6458                            &v6_next_hop_address,
6459                            sizeof (v6_next_hop_address));
6460             }
6461         }
6462       local_label++;
6463
6464       /* send it... */
6465       S;
6466       /* If we receive SIGTERM, stop now... */
6467       if (vam->do_exit)
6468         break;
6469     }
6470
6471   /* When testing multiple add/del ops, use a control-ping to sync */
6472   if (count > 1)
6473     {
6474       vl_api_control_ping_t *mp;
6475       f64 after;
6476
6477       /* Shut off async mode */
6478       vam->async_mode = 0;
6479
6480       M (CONTROL_PING, control_ping);
6481       S;
6482
6483       timeout = vat_time_now (vam) + 1.0;
6484       while (vat_time_now (vam) < timeout)
6485         if (vam->result_ready == 1)
6486           goto out;
6487       vam->retval = -99;
6488
6489     out:
6490       if (vam->retval == -99)
6491         errmsg ("timeout\n");
6492
6493       if (vam->async_errors > 0)
6494         {
6495           errmsg ("%d asynchronous errors\n", vam->async_errors);
6496           vam->retval = -98;
6497         }
6498       vam->async_errors = 0;
6499       after = vat_time_now (vam);
6500
6501       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6502       if (j > 0)
6503         count = j;
6504
6505       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6506                count, after - before, count / (after - before));
6507     }
6508   else
6509     {
6510       /* Wait for a reply... */
6511       W;
6512     }
6513
6514   /* Return the good/bad news */
6515   return (vam->retval);
6516 }
6517
6518 static int
6519 api_mpls_ip_bind_unbind (vat_main_t * vam)
6520 {
6521   unformat_input_t *i = vam->input;
6522   vl_api_mpls_ip_bind_unbind_t *mp;
6523   f64 timeout;
6524   u32 ip_table_id = 0;
6525   u8 create_table_if_needed = 0;
6526   u8 is_bind = 1;
6527   u8 is_ip4 = 1;
6528   ip4_address_t v4_address;
6529   ip6_address_t v6_address;
6530   u32 address_length;
6531   u8 address_set = 0;
6532   mpls_label_t local_label = MPLS_LABEL_INVALID;
6533
6534   /* Parse args required to build the message */
6535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6536     {
6537       if (unformat (i, "%U/%d", unformat_ip4_address,
6538                     &v4_address, &address_length))
6539         {
6540           is_ip4 = 1;
6541           address_set = 1;
6542         }
6543       else if (unformat (i, "%U/%d", unformat_ip6_address,
6544                          &v6_address, &address_length))
6545         {
6546           is_ip4 = 0;
6547           address_set = 1;
6548         }
6549       else if (unformat (i, "%d", &local_label))
6550         ;
6551       else if (unformat (i, "create-table"))
6552         create_table_if_needed = 1;
6553       else if (unformat (i, "table-id %d", &ip_table_id))
6554         ;
6555       else if (unformat (i, "unbind"))
6556         is_bind = 0;
6557       else if (unformat (i, "bind"))
6558         is_bind = 1;
6559       else
6560         {
6561           clib_warning ("parse error '%U'", format_unformat_error, i);
6562           return -99;
6563         }
6564     }
6565
6566   if (!address_set)
6567     {
6568       errmsg ("IP addres not set\n");
6569       return -99;
6570     }
6571
6572   if (MPLS_LABEL_INVALID == local_label)
6573     {
6574       errmsg ("missing label\n");
6575       return -99;
6576     }
6577
6578   /* Construct the API message */
6579   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6580
6581   mp->mb_create_table_if_needed = create_table_if_needed;
6582   mp->mb_is_bind = is_bind;
6583   mp->mb_is_ip4 = is_ip4;
6584   mp->mb_ip_table_id = ntohl (ip_table_id);
6585   mp->mb_mpls_table_id = 0;
6586   mp->mb_label = ntohl (local_label);
6587   mp->mb_address_length = address_length;
6588
6589   if (is_ip4)
6590     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6591   else
6592     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6593
6594   /* send it... */
6595   S;
6596
6597   /* Wait for a reply... */
6598   W;
6599 }
6600
6601 static int
6602 api_proxy_arp_add_del (vat_main_t * vam)
6603 {
6604   unformat_input_t *i = vam->input;
6605   vl_api_proxy_arp_add_del_t *mp;
6606   f64 timeout;
6607   u32 vrf_id = 0;
6608   u8 is_add = 1;
6609   ip4_address_t lo, hi;
6610   u8 range_set = 0;
6611
6612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6613     {
6614       if (unformat (i, "vrf %d", &vrf_id))
6615         ;
6616       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6617                          unformat_ip4_address, &hi))
6618         range_set = 1;
6619       else if (unformat (i, "del"))
6620         is_add = 0;
6621       else
6622         {
6623           clib_warning ("parse error '%U'", format_unformat_error, i);
6624           return -99;
6625         }
6626     }
6627
6628   if (range_set == 0)
6629     {
6630       errmsg ("address range not set\n");
6631       return -99;
6632     }
6633
6634   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6635
6636   mp->vrf_id = ntohl (vrf_id);
6637   mp->is_add = is_add;
6638   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6639   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6640
6641   S;
6642   W;
6643   /* NOTREACHED */
6644   return 0;
6645 }
6646
6647 static int
6648 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6649 {
6650   unformat_input_t *i = vam->input;
6651   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6652   f64 timeout;
6653   u32 sw_if_index;
6654   u8 enable = 1;
6655   u8 sw_if_index_set = 0;
6656
6657   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6658     {
6659       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6660         sw_if_index_set = 1;
6661       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6662         sw_if_index_set = 1;
6663       else if (unformat (i, "enable"))
6664         enable = 1;
6665       else if (unformat (i, "disable"))
6666         enable = 0;
6667       else
6668         {
6669           clib_warning ("parse error '%U'", format_unformat_error, i);
6670           return -99;
6671         }
6672     }
6673
6674   if (sw_if_index_set == 0)
6675     {
6676       errmsg ("missing interface name or sw_if_index\n");
6677       return -99;
6678     }
6679
6680   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6681
6682   mp->sw_if_index = ntohl (sw_if_index);
6683   mp->enable_disable = enable;
6684
6685   S;
6686   W;
6687   /* NOTREACHED */
6688   return 0;
6689 }
6690
6691 static int
6692 api_mpls_tunnel_add_del (vat_main_t * vam)
6693 {
6694   unformat_input_t *i = vam->input;
6695   vl_api_mpls_tunnel_add_del_t *mp;
6696   f64 timeout;
6697
6698   u8 is_add = 1;
6699   u8 l2_only = 0;
6700   u32 sw_if_index = ~0;
6701   u32 next_hop_sw_if_index = ~0;
6702   u32 next_hop_proto_is_ip4 = 1;
6703
6704   u32 next_hop_table_id = 0;
6705   ip4_address_t v4_next_hop_address = {
6706     .as_u32 = 0,
6707   };
6708   ip6_address_t v6_next_hop_address = { {0} };
6709   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
6710
6711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6712     {
6713       if (unformat (i, "add"))
6714         is_add = 1;
6715       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6716         is_add = 0;
6717       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
6718         ;
6719       else if (unformat (i, "via %U",
6720                          unformat_ip4_address, &v4_next_hop_address))
6721         {
6722           next_hop_proto_is_ip4 = 1;
6723         }
6724       else if (unformat (i, "via %U",
6725                          unformat_ip6_address, &v6_next_hop_address))
6726         {
6727           next_hop_proto_is_ip4 = 0;
6728         }
6729       else if (unformat (i, "l2-only"))
6730         l2_only = 1;
6731       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6732         ;
6733       else if (unformat (i, "out-label %d", &next_hop_out_label))
6734         vec_add1 (labels, ntohl (next_hop_out_label));
6735       else
6736         {
6737           clib_warning ("parse error '%U'", format_unformat_error, i);
6738           return -99;
6739         }
6740     }
6741
6742   M2 (MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del,
6743       sizeof (mpls_label_t) * vec_len (labels));
6744
6745   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
6746   mp->mt_sw_if_index = ntohl (sw_if_index);
6747   mp->mt_is_add = is_add;
6748   mp->mt_l2_only = l2_only;
6749   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
6750   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6751
6752   mp->mt_next_hop_n_out_labels = vec_len (labels);
6753
6754   if (0 != mp->mt_next_hop_n_out_labels)
6755     {
6756       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
6757                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
6758       vec_free (labels);
6759     }
6760
6761   if (next_hop_proto_is_ip4)
6762     {
6763       clib_memcpy (mp->mt_next_hop,
6764                    &v4_next_hop_address, sizeof (v4_next_hop_address));
6765     }
6766   else
6767     {
6768       clib_memcpy (mp->mt_next_hop,
6769                    &v6_next_hop_address, sizeof (v6_next_hop_address));
6770     }
6771
6772   S;
6773   W;
6774   /* NOTREACHED */
6775   return 0;
6776 }
6777
6778 static int
6779 api_sw_interface_set_unnumbered (vat_main_t * vam)
6780 {
6781   unformat_input_t *i = vam->input;
6782   vl_api_sw_interface_set_unnumbered_t *mp;
6783   f64 timeout;
6784   u32 sw_if_index;
6785   u32 unnum_sw_index = ~0;
6786   u8 is_add = 1;
6787   u8 sw_if_index_set = 0;
6788
6789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6790     {
6791       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6792         sw_if_index_set = 1;
6793       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6794         sw_if_index_set = 1;
6795       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6796         ;
6797       else if (unformat (i, "del"))
6798         is_add = 0;
6799       else
6800         {
6801           clib_warning ("parse error '%U'", format_unformat_error, i);
6802           return -99;
6803         }
6804     }
6805
6806   if (sw_if_index_set == 0)
6807     {
6808       errmsg ("missing interface name or sw_if_index\n");
6809       return -99;
6810     }
6811
6812   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6813
6814   mp->sw_if_index = ntohl (sw_if_index);
6815   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6816   mp->is_add = is_add;
6817
6818   S;
6819   W;
6820   /* NOTREACHED */
6821   return 0;
6822 }
6823
6824 static int
6825 api_ip_neighbor_add_del (vat_main_t * vam)
6826 {
6827   unformat_input_t *i = vam->input;
6828   vl_api_ip_neighbor_add_del_t *mp;
6829   f64 timeout;
6830   u32 sw_if_index;
6831   u8 sw_if_index_set = 0;
6832   u32 vrf_id = 0;
6833   u8 is_add = 1;
6834   u8 is_static = 0;
6835   u8 mac_address[6];
6836   u8 mac_set = 0;
6837   u8 v4_address_set = 0;
6838   u8 v6_address_set = 0;
6839   ip4_address_t v4address;
6840   ip6_address_t v6address;
6841
6842   memset (mac_address, 0, sizeof (mac_address));
6843
6844   /* Parse args required to build the message */
6845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6846     {
6847       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6848         {
6849           mac_set = 1;
6850         }
6851       else if (unformat (i, "del"))
6852         is_add = 0;
6853       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6854         sw_if_index_set = 1;
6855       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6856         sw_if_index_set = 1;
6857       else if (unformat (i, "is_static"))
6858         is_static = 1;
6859       else if (unformat (i, "vrf %d", &vrf_id))
6860         ;
6861       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6862         v4_address_set = 1;
6863       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6864         v6_address_set = 1;
6865       else
6866         {
6867           clib_warning ("parse error '%U'", format_unformat_error, i);
6868           return -99;
6869         }
6870     }
6871
6872   if (sw_if_index_set == 0)
6873     {
6874       errmsg ("missing interface name or sw_if_index\n");
6875       return -99;
6876     }
6877   if (v4_address_set && v6_address_set)
6878     {
6879       errmsg ("both v4 and v6 addresses set\n");
6880       return -99;
6881     }
6882   if (!v4_address_set && !v6_address_set)
6883     {
6884       errmsg ("no address set\n");
6885       return -99;
6886     }
6887
6888   /* Construct the API message */
6889   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6890
6891   mp->sw_if_index = ntohl (sw_if_index);
6892   mp->is_add = is_add;
6893   mp->vrf_id = ntohl (vrf_id);
6894   mp->is_static = is_static;
6895   if (mac_set)
6896     clib_memcpy (mp->mac_address, mac_address, 6);
6897   if (v6_address_set)
6898     {
6899       mp->is_ipv6 = 1;
6900       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6901     }
6902   else
6903     {
6904       /* mp->is_ipv6 = 0; via memset in M macro above */
6905       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6906     }
6907
6908   /* send it... */
6909   S;
6910
6911   /* Wait for a reply, return good/bad news  */
6912   W;
6913
6914   /* NOTREACHED */
6915   return 0;
6916 }
6917
6918 static int
6919 api_reset_vrf (vat_main_t * vam)
6920 {
6921   unformat_input_t *i = vam->input;
6922   vl_api_reset_vrf_t *mp;
6923   f64 timeout;
6924   u32 vrf_id = 0;
6925   u8 is_ipv6 = 0;
6926   u8 vrf_id_set = 0;
6927
6928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6929     {
6930       if (unformat (i, "vrf %d", &vrf_id))
6931         vrf_id_set = 1;
6932       else if (unformat (i, "ipv6"))
6933         is_ipv6 = 1;
6934       else
6935         {
6936           clib_warning ("parse error '%U'", format_unformat_error, i);
6937           return -99;
6938         }
6939     }
6940
6941   if (vrf_id_set == 0)
6942     {
6943       errmsg ("missing vrf id\n");
6944       return -99;
6945     }
6946
6947   M (RESET_VRF, reset_vrf);
6948
6949   mp->vrf_id = ntohl (vrf_id);
6950   mp->is_ipv6 = is_ipv6;
6951
6952   S;
6953   W;
6954   /* NOTREACHED */
6955   return 0;
6956 }
6957
6958 static int
6959 api_create_vlan_subif (vat_main_t * vam)
6960 {
6961   unformat_input_t *i = vam->input;
6962   vl_api_create_vlan_subif_t *mp;
6963   f64 timeout;
6964   u32 sw_if_index;
6965   u8 sw_if_index_set = 0;
6966   u32 vlan_id;
6967   u8 vlan_id_set = 0;
6968
6969   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6970     {
6971       if (unformat (i, "sw_if_index %d", &sw_if_index))
6972         sw_if_index_set = 1;
6973       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6974         sw_if_index_set = 1;
6975       else if (unformat (i, "vlan %d", &vlan_id))
6976         vlan_id_set = 1;
6977       else
6978         {
6979           clib_warning ("parse error '%U'", format_unformat_error, i);
6980           return -99;
6981         }
6982     }
6983
6984   if (sw_if_index_set == 0)
6985     {
6986       errmsg ("missing interface name or sw_if_index\n");
6987       return -99;
6988     }
6989
6990   if (vlan_id_set == 0)
6991     {
6992       errmsg ("missing vlan_id\n");
6993       return -99;
6994     }
6995   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6996
6997   mp->sw_if_index = ntohl (sw_if_index);
6998   mp->vlan_id = ntohl (vlan_id);
6999
7000   S;
7001   W;
7002   /* NOTREACHED */
7003   return 0;
7004 }
7005
7006 #define foreach_create_subif_bit                \
7007 _(no_tags)                                      \
7008 _(one_tag)                                      \
7009 _(two_tags)                                     \
7010 _(dot1ad)                                       \
7011 _(exact_match)                                  \
7012 _(default_sub)                                  \
7013 _(outer_vlan_id_any)                            \
7014 _(inner_vlan_id_any)
7015
7016 static int
7017 api_create_subif (vat_main_t * vam)
7018 {
7019   unformat_input_t *i = vam->input;
7020   vl_api_create_subif_t *mp;
7021   f64 timeout;
7022   u32 sw_if_index;
7023   u8 sw_if_index_set = 0;
7024   u32 sub_id;
7025   u8 sub_id_set = 0;
7026   u32 no_tags = 0;
7027   u32 one_tag = 0;
7028   u32 two_tags = 0;
7029   u32 dot1ad = 0;
7030   u32 exact_match = 0;
7031   u32 default_sub = 0;
7032   u32 outer_vlan_id_any = 0;
7033   u32 inner_vlan_id_any = 0;
7034   u32 tmp;
7035   u16 outer_vlan_id = 0;
7036   u16 inner_vlan_id = 0;
7037
7038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7039     {
7040       if (unformat (i, "sw_if_index %d", &sw_if_index))
7041         sw_if_index_set = 1;
7042       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7043         sw_if_index_set = 1;
7044       else if (unformat (i, "sub_id %d", &sub_id))
7045         sub_id_set = 1;
7046       else if (unformat (i, "outer_vlan_id %d", &tmp))
7047         outer_vlan_id = tmp;
7048       else if (unformat (i, "inner_vlan_id %d", &tmp))
7049         inner_vlan_id = tmp;
7050
7051 #define _(a) else if (unformat (i, #a)) a = 1 ;
7052       foreach_create_subif_bit
7053 #undef _
7054         else
7055         {
7056           clib_warning ("parse error '%U'", format_unformat_error, i);
7057           return -99;
7058         }
7059     }
7060
7061   if (sw_if_index_set == 0)
7062     {
7063       errmsg ("missing interface name or sw_if_index\n");
7064       return -99;
7065     }
7066
7067   if (sub_id_set == 0)
7068     {
7069       errmsg ("missing sub_id\n");
7070       return -99;
7071     }
7072   M (CREATE_SUBIF, create_subif);
7073
7074   mp->sw_if_index = ntohl (sw_if_index);
7075   mp->sub_id = ntohl (sub_id);
7076
7077 #define _(a) mp->a = a;
7078   foreach_create_subif_bit;
7079 #undef _
7080
7081   mp->outer_vlan_id = ntohs (outer_vlan_id);
7082   mp->inner_vlan_id = ntohs (inner_vlan_id);
7083
7084   S;
7085   W;
7086   /* NOTREACHED */
7087   return 0;
7088 }
7089
7090 static int
7091 api_oam_add_del (vat_main_t * vam)
7092 {
7093   unformat_input_t *i = vam->input;
7094   vl_api_oam_add_del_t *mp;
7095   f64 timeout;
7096   u32 vrf_id = 0;
7097   u8 is_add = 1;
7098   ip4_address_t src, dst;
7099   u8 src_set = 0;
7100   u8 dst_set = 0;
7101
7102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7103     {
7104       if (unformat (i, "vrf %d", &vrf_id))
7105         ;
7106       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7107         src_set = 1;
7108       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7109         dst_set = 1;
7110       else if (unformat (i, "del"))
7111         is_add = 0;
7112       else
7113         {
7114           clib_warning ("parse error '%U'", format_unformat_error, i);
7115           return -99;
7116         }
7117     }
7118
7119   if (src_set == 0)
7120     {
7121       errmsg ("missing src addr\n");
7122       return -99;
7123     }
7124
7125   if (dst_set == 0)
7126     {
7127       errmsg ("missing dst addr\n");
7128       return -99;
7129     }
7130
7131   M (OAM_ADD_DEL, oam_add_del);
7132
7133   mp->vrf_id = ntohl (vrf_id);
7134   mp->is_add = is_add;
7135   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7136   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7137
7138   S;
7139   W;
7140   /* NOTREACHED */
7141   return 0;
7142 }
7143
7144 static int
7145 api_reset_fib (vat_main_t * vam)
7146 {
7147   unformat_input_t *i = vam->input;
7148   vl_api_reset_fib_t *mp;
7149   f64 timeout;
7150   u32 vrf_id = 0;
7151   u8 is_ipv6 = 0;
7152   u8 vrf_id_set = 0;
7153
7154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7155     {
7156       if (unformat (i, "vrf %d", &vrf_id))
7157         vrf_id_set = 1;
7158       else if (unformat (i, "ipv6"))
7159         is_ipv6 = 1;
7160       else
7161         {
7162           clib_warning ("parse error '%U'", format_unformat_error, i);
7163           return -99;
7164         }
7165     }
7166
7167   if (vrf_id_set == 0)
7168     {
7169       errmsg ("missing vrf id\n");
7170       return -99;
7171     }
7172
7173   M (RESET_FIB, reset_fib);
7174
7175   mp->vrf_id = ntohl (vrf_id);
7176   mp->is_ipv6 = is_ipv6;
7177
7178   S;
7179   W;
7180   /* NOTREACHED */
7181   return 0;
7182 }
7183
7184 static int
7185 api_dhcp_proxy_config (vat_main_t * vam)
7186 {
7187   unformat_input_t *i = vam->input;
7188   vl_api_dhcp_proxy_config_t *mp;
7189   f64 timeout;
7190   u32 vrf_id = 0;
7191   u8 is_add = 1;
7192   u8 insert_cid = 1;
7193   u8 v4_address_set = 0;
7194   u8 v6_address_set = 0;
7195   ip4_address_t v4address;
7196   ip6_address_t v6address;
7197   u8 v4_src_address_set = 0;
7198   u8 v6_src_address_set = 0;
7199   ip4_address_t v4srcaddress;
7200   ip6_address_t v6srcaddress;
7201
7202   /* Parse args required to build the message */
7203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7204     {
7205       if (unformat (i, "del"))
7206         is_add = 0;
7207       else if (unformat (i, "vrf %d", &vrf_id))
7208         ;
7209       else if (unformat (i, "insert-cid %d", &insert_cid))
7210         ;
7211       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7212         v4_address_set = 1;
7213       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7214         v6_address_set = 1;
7215       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7216         v4_src_address_set = 1;
7217       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7218         v6_src_address_set = 1;
7219       else
7220         break;
7221     }
7222
7223   if (v4_address_set && v6_address_set)
7224     {
7225       errmsg ("both v4 and v6 server addresses set\n");
7226       return -99;
7227     }
7228   if (!v4_address_set && !v6_address_set)
7229     {
7230       errmsg ("no server addresses set\n");
7231       return -99;
7232     }
7233
7234   if (v4_src_address_set && v6_src_address_set)
7235     {
7236       errmsg ("both v4 and v6  src addresses set\n");
7237       return -99;
7238     }
7239   if (!v4_src_address_set && !v6_src_address_set)
7240     {
7241       errmsg ("no src addresses set\n");
7242       return -99;
7243     }
7244
7245   if (!(v4_src_address_set && v4_address_set) &&
7246       !(v6_src_address_set && v6_address_set))
7247     {
7248       errmsg ("no matching server and src addresses set\n");
7249       return -99;
7250     }
7251
7252   /* Construct the API message */
7253   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7254
7255   mp->insert_circuit_id = insert_cid;
7256   mp->is_add = is_add;
7257   mp->vrf_id = ntohl (vrf_id);
7258   if (v6_address_set)
7259     {
7260       mp->is_ipv6 = 1;
7261       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7262       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7263     }
7264   else
7265     {
7266       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7267       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7268     }
7269
7270   /* send it... */
7271   S;
7272
7273   /* Wait for a reply, return good/bad news  */
7274   W;
7275   /* NOTREACHED */
7276   return 0;
7277 }
7278
7279 static int
7280 api_dhcp_proxy_config_2 (vat_main_t * vam)
7281 {
7282   unformat_input_t *i = vam->input;
7283   vl_api_dhcp_proxy_config_2_t *mp;
7284   f64 timeout;
7285   u32 rx_vrf_id = 0;
7286   u32 server_vrf_id = 0;
7287   u8 is_add = 1;
7288   u8 insert_cid = 1;
7289   u8 v4_address_set = 0;
7290   u8 v6_address_set = 0;
7291   ip4_address_t v4address;
7292   ip6_address_t v6address;
7293   u8 v4_src_address_set = 0;
7294   u8 v6_src_address_set = 0;
7295   ip4_address_t v4srcaddress;
7296   ip6_address_t v6srcaddress;
7297
7298   /* Parse args required to build the message */
7299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7300     {
7301       if (unformat (i, "del"))
7302         is_add = 0;
7303       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7304         ;
7305       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7306         ;
7307       else if (unformat (i, "insert-cid %d", &insert_cid))
7308         ;
7309       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7310         v4_address_set = 1;
7311       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7312         v6_address_set = 1;
7313       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7314         v4_src_address_set = 1;
7315       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7316         v6_src_address_set = 1;
7317       else
7318         break;
7319     }
7320
7321   if (v4_address_set && v6_address_set)
7322     {
7323       errmsg ("both v4 and v6 server addresses set\n");
7324       return -99;
7325     }
7326   if (!v4_address_set && !v6_address_set)
7327     {
7328       errmsg ("no server addresses set\n");
7329       return -99;
7330     }
7331
7332   if (v4_src_address_set && v6_src_address_set)
7333     {
7334       errmsg ("both v4 and v6  src addresses set\n");
7335       return -99;
7336     }
7337   if (!v4_src_address_set && !v6_src_address_set)
7338     {
7339       errmsg ("no src addresses set\n");
7340       return -99;
7341     }
7342
7343   if (!(v4_src_address_set && v4_address_set) &&
7344       !(v6_src_address_set && v6_address_set))
7345     {
7346       errmsg ("no matching server and src addresses set\n");
7347       return -99;
7348     }
7349
7350   /* Construct the API message */
7351   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7352
7353   mp->insert_circuit_id = insert_cid;
7354   mp->is_add = is_add;
7355   mp->rx_vrf_id = ntohl (rx_vrf_id);
7356   mp->server_vrf_id = ntohl (server_vrf_id);
7357   if (v6_address_set)
7358     {
7359       mp->is_ipv6 = 1;
7360       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7361       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7362     }
7363   else
7364     {
7365       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7366       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7367     }
7368
7369   /* send it... */
7370   S;
7371
7372   /* Wait for a reply, return good/bad news  */
7373   W;
7374   /* NOTREACHED */
7375   return 0;
7376 }
7377
7378 static int
7379 api_dhcp_proxy_set_vss (vat_main_t * vam)
7380 {
7381   unformat_input_t *i = vam->input;
7382   vl_api_dhcp_proxy_set_vss_t *mp;
7383   f64 timeout;
7384   u8 is_ipv6 = 0;
7385   u8 is_add = 1;
7386   u32 tbl_id;
7387   u8 tbl_id_set = 0;
7388   u32 oui;
7389   u8 oui_set = 0;
7390   u32 fib_id;
7391   u8 fib_id_set = 0;
7392
7393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7394     {
7395       if (unformat (i, "tbl_id %d", &tbl_id))
7396         tbl_id_set = 1;
7397       if (unformat (i, "fib_id %d", &fib_id))
7398         fib_id_set = 1;
7399       if (unformat (i, "oui %d", &oui))
7400         oui_set = 1;
7401       else if (unformat (i, "ipv6"))
7402         is_ipv6 = 1;
7403       else if (unformat (i, "del"))
7404         is_add = 0;
7405       else
7406         {
7407           clib_warning ("parse error '%U'", format_unformat_error, i);
7408           return -99;
7409         }
7410     }
7411
7412   if (tbl_id_set == 0)
7413     {
7414       errmsg ("missing tbl id\n");
7415       return -99;
7416     }
7417
7418   if (fib_id_set == 0)
7419     {
7420       errmsg ("missing fib id\n");
7421       return -99;
7422     }
7423   if (oui_set == 0)
7424     {
7425       errmsg ("missing oui\n");
7426       return -99;
7427     }
7428
7429   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7430   mp->tbl_id = ntohl (tbl_id);
7431   mp->fib_id = ntohl (fib_id);
7432   mp->oui = ntohl (oui);
7433   mp->is_ipv6 = is_ipv6;
7434   mp->is_add = is_add;
7435
7436   S;
7437   W;
7438   /* NOTREACHED */
7439   return 0;
7440 }
7441
7442 static int
7443 api_dhcp_client_config (vat_main_t * vam)
7444 {
7445   unformat_input_t *i = vam->input;
7446   vl_api_dhcp_client_config_t *mp;
7447   f64 timeout;
7448   u32 sw_if_index;
7449   u8 sw_if_index_set = 0;
7450   u8 is_add = 1;
7451   u8 *hostname = 0;
7452   u8 disable_event = 0;
7453
7454   /* Parse args required to build the message */
7455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7456     {
7457       if (unformat (i, "del"))
7458         is_add = 0;
7459       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7460         sw_if_index_set = 1;
7461       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7462         sw_if_index_set = 1;
7463       else if (unformat (i, "hostname %s", &hostname))
7464         ;
7465       else if (unformat (i, "disable_event"))
7466         disable_event = 1;
7467       else
7468         break;
7469     }
7470
7471   if (sw_if_index_set == 0)
7472     {
7473       errmsg ("missing interface name or sw_if_index\n");
7474       return -99;
7475     }
7476
7477   if (vec_len (hostname) > 63)
7478     {
7479       errmsg ("hostname too long\n");
7480     }
7481   vec_add1 (hostname, 0);
7482
7483   /* Construct the API message */
7484   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7485
7486   mp->sw_if_index = ntohl (sw_if_index);
7487   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7488   vec_free (hostname);
7489   mp->is_add = is_add;
7490   mp->want_dhcp_event = disable_event ? 0 : 1;
7491   mp->pid = getpid ();
7492
7493   /* send it... */
7494   S;
7495
7496   /* Wait for a reply, return good/bad news  */
7497   W;
7498   /* NOTREACHED */
7499   return 0;
7500 }
7501
7502 static int
7503 api_set_ip_flow_hash (vat_main_t * vam)
7504 {
7505   unformat_input_t *i = vam->input;
7506   vl_api_set_ip_flow_hash_t *mp;
7507   f64 timeout;
7508   u32 vrf_id = 0;
7509   u8 is_ipv6 = 0;
7510   u8 vrf_id_set = 0;
7511   u8 src = 0;
7512   u8 dst = 0;
7513   u8 sport = 0;
7514   u8 dport = 0;
7515   u8 proto = 0;
7516   u8 reverse = 0;
7517
7518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7519     {
7520       if (unformat (i, "vrf %d", &vrf_id))
7521         vrf_id_set = 1;
7522       else if (unformat (i, "ipv6"))
7523         is_ipv6 = 1;
7524       else if (unformat (i, "src"))
7525         src = 1;
7526       else if (unformat (i, "dst"))
7527         dst = 1;
7528       else if (unformat (i, "sport"))
7529         sport = 1;
7530       else if (unformat (i, "dport"))
7531         dport = 1;
7532       else if (unformat (i, "proto"))
7533         proto = 1;
7534       else if (unformat (i, "reverse"))
7535         reverse = 1;
7536
7537       else
7538         {
7539           clib_warning ("parse error '%U'", format_unformat_error, i);
7540           return -99;
7541         }
7542     }
7543
7544   if (vrf_id_set == 0)
7545     {
7546       errmsg ("missing vrf id\n");
7547       return -99;
7548     }
7549
7550   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7551   mp->src = src;
7552   mp->dst = dst;
7553   mp->sport = sport;
7554   mp->dport = dport;
7555   mp->proto = proto;
7556   mp->reverse = reverse;
7557   mp->vrf_id = ntohl (vrf_id);
7558   mp->is_ipv6 = is_ipv6;
7559
7560   S;
7561   W;
7562   /* NOTREACHED */
7563   return 0;
7564 }
7565
7566 static int
7567 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7568 {
7569   unformat_input_t *i = vam->input;
7570   vl_api_sw_interface_ip6_enable_disable_t *mp;
7571   f64 timeout;
7572   u32 sw_if_index;
7573   u8 sw_if_index_set = 0;
7574   u8 enable = 0;
7575
7576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7577     {
7578       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7579         sw_if_index_set = 1;
7580       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7581         sw_if_index_set = 1;
7582       else if (unformat (i, "enable"))
7583         enable = 1;
7584       else if (unformat (i, "disable"))
7585         enable = 0;
7586       else
7587         {
7588           clib_warning ("parse error '%U'", format_unformat_error, i);
7589           return -99;
7590         }
7591     }
7592
7593   if (sw_if_index_set == 0)
7594     {
7595       errmsg ("missing interface name or sw_if_index\n");
7596       return -99;
7597     }
7598
7599   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7600
7601   mp->sw_if_index = ntohl (sw_if_index);
7602   mp->enable = enable;
7603
7604   S;
7605   W;
7606   /* NOTREACHED */
7607   return 0;
7608 }
7609
7610 static int
7611 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7612 {
7613   unformat_input_t *i = vam->input;
7614   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7615   f64 timeout;
7616   u32 sw_if_index;
7617   u8 sw_if_index_set = 0;
7618   u32 address_length = 0;
7619   u8 v6_address_set = 0;
7620   ip6_address_t v6address;
7621
7622   /* Parse args required to build the message */
7623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7624     {
7625       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7626         sw_if_index_set = 1;
7627       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7628         sw_if_index_set = 1;
7629       else if (unformat (i, "%U/%d",
7630                          unformat_ip6_address, &v6address, &address_length))
7631         v6_address_set = 1;
7632       else
7633         break;
7634     }
7635
7636   if (sw_if_index_set == 0)
7637     {
7638       errmsg ("missing interface name or sw_if_index\n");
7639       return -99;
7640     }
7641   if (!v6_address_set)
7642     {
7643       errmsg ("no address set\n");
7644       return -99;
7645     }
7646
7647   /* Construct the API message */
7648   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7649      sw_interface_ip6_set_link_local_address);
7650
7651   mp->sw_if_index = ntohl (sw_if_index);
7652   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7653   mp->address_length = address_length;
7654
7655   /* send it... */
7656   S;
7657
7658   /* Wait for a reply, return good/bad news  */
7659   W;
7660
7661   /* NOTREACHED */
7662   return 0;
7663 }
7664
7665
7666 static int
7667 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7668 {
7669   unformat_input_t *i = vam->input;
7670   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7671   f64 timeout;
7672   u32 sw_if_index;
7673   u8 sw_if_index_set = 0;
7674   u32 address_length = 0;
7675   u8 v6_address_set = 0;
7676   ip6_address_t v6address;
7677   u8 use_default = 0;
7678   u8 no_advertise = 0;
7679   u8 off_link = 0;
7680   u8 no_autoconfig = 0;
7681   u8 no_onlink = 0;
7682   u8 is_no = 0;
7683   u32 val_lifetime = 0;
7684   u32 pref_lifetime = 0;
7685
7686   /* Parse args required to build the message */
7687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7688     {
7689       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7690         sw_if_index_set = 1;
7691       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7692         sw_if_index_set = 1;
7693       else if (unformat (i, "%U/%d",
7694                          unformat_ip6_address, &v6address, &address_length))
7695         v6_address_set = 1;
7696       else if (unformat (i, "val_life %d", &val_lifetime))
7697         ;
7698       else if (unformat (i, "pref_life %d", &pref_lifetime))
7699         ;
7700       else if (unformat (i, "def"))
7701         use_default = 1;
7702       else if (unformat (i, "noadv"))
7703         no_advertise = 1;
7704       else if (unformat (i, "offl"))
7705         off_link = 1;
7706       else if (unformat (i, "noauto"))
7707         no_autoconfig = 1;
7708       else if (unformat (i, "nolink"))
7709         no_onlink = 1;
7710       else if (unformat (i, "isno"))
7711         is_no = 1;
7712       else
7713         {
7714           clib_warning ("parse error '%U'", format_unformat_error, i);
7715           return -99;
7716         }
7717     }
7718
7719   if (sw_if_index_set == 0)
7720     {
7721       errmsg ("missing interface name or sw_if_index\n");
7722       return -99;
7723     }
7724   if (!v6_address_set)
7725     {
7726       errmsg ("no address set\n");
7727       return -99;
7728     }
7729
7730   /* Construct the API message */
7731   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7732
7733   mp->sw_if_index = ntohl (sw_if_index);
7734   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7735   mp->address_length = address_length;
7736   mp->use_default = use_default;
7737   mp->no_advertise = no_advertise;
7738   mp->off_link = off_link;
7739   mp->no_autoconfig = no_autoconfig;
7740   mp->no_onlink = no_onlink;
7741   mp->is_no = is_no;
7742   mp->val_lifetime = ntohl (val_lifetime);
7743   mp->pref_lifetime = ntohl (pref_lifetime);
7744
7745   /* send it... */
7746   S;
7747
7748   /* Wait for a reply, return good/bad news  */
7749   W;
7750
7751   /* NOTREACHED */
7752   return 0;
7753 }
7754
7755 static int
7756 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7757 {
7758   unformat_input_t *i = vam->input;
7759   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7760   f64 timeout;
7761   u32 sw_if_index;
7762   u8 sw_if_index_set = 0;
7763   u8 suppress = 0;
7764   u8 managed = 0;
7765   u8 other = 0;
7766   u8 ll_option = 0;
7767   u8 send_unicast = 0;
7768   u8 cease = 0;
7769   u8 is_no = 0;
7770   u8 default_router = 0;
7771   u32 max_interval = 0;
7772   u32 min_interval = 0;
7773   u32 lifetime = 0;
7774   u32 initial_count = 0;
7775   u32 initial_interval = 0;
7776
7777
7778   /* Parse args required to build the message */
7779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7780     {
7781       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7782         sw_if_index_set = 1;
7783       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7784         sw_if_index_set = 1;
7785       else if (unformat (i, "maxint %d", &max_interval))
7786         ;
7787       else if (unformat (i, "minint %d", &min_interval))
7788         ;
7789       else if (unformat (i, "life %d", &lifetime))
7790         ;
7791       else if (unformat (i, "count %d", &initial_count))
7792         ;
7793       else if (unformat (i, "interval %d", &initial_interval))
7794         ;
7795       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7796         suppress = 1;
7797       else if (unformat (i, "managed"))
7798         managed = 1;
7799       else if (unformat (i, "other"))
7800         other = 1;
7801       else if (unformat (i, "ll"))
7802         ll_option = 1;
7803       else if (unformat (i, "send"))
7804         send_unicast = 1;
7805       else if (unformat (i, "cease"))
7806         cease = 1;
7807       else if (unformat (i, "isno"))
7808         is_no = 1;
7809       else if (unformat (i, "def"))
7810         default_router = 1;
7811       else
7812         {
7813           clib_warning ("parse error '%U'", format_unformat_error, i);
7814           return -99;
7815         }
7816     }
7817
7818   if (sw_if_index_set == 0)
7819     {
7820       errmsg ("missing interface name or sw_if_index\n");
7821       return -99;
7822     }
7823
7824   /* Construct the API message */
7825   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7826
7827   mp->sw_if_index = ntohl (sw_if_index);
7828   mp->max_interval = ntohl (max_interval);
7829   mp->min_interval = ntohl (min_interval);
7830   mp->lifetime = ntohl (lifetime);
7831   mp->initial_count = ntohl (initial_count);
7832   mp->initial_interval = ntohl (initial_interval);
7833   mp->suppress = suppress;
7834   mp->managed = managed;
7835   mp->other = other;
7836   mp->ll_option = ll_option;
7837   mp->send_unicast = send_unicast;
7838   mp->cease = cease;
7839   mp->is_no = is_no;
7840   mp->default_router = default_router;
7841
7842   /* send it... */
7843   S;
7844
7845   /* Wait for a reply, return good/bad news  */
7846   W;
7847
7848   /* NOTREACHED */
7849   return 0;
7850 }
7851
7852 static int
7853 api_set_arp_neighbor_limit (vat_main_t * vam)
7854 {
7855   unformat_input_t *i = vam->input;
7856   vl_api_set_arp_neighbor_limit_t *mp;
7857   f64 timeout;
7858   u32 arp_nbr_limit;
7859   u8 limit_set = 0;
7860   u8 is_ipv6 = 0;
7861
7862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7863     {
7864       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7865         limit_set = 1;
7866       else if (unformat (i, "ipv6"))
7867         is_ipv6 = 1;
7868       else
7869         {
7870           clib_warning ("parse error '%U'", format_unformat_error, i);
7871           return -99;
7872         }
7873     }
7874
7875   if (limit_set == 0)
7876     {
7877       errmsg ("missing limit value\n");
7878       return -99;
7879     }
7880
7881   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7882
7883   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7884   mp->is_ipv6 = is_ipv6;
7885
7886   S;
7887   W;
7888   /* NOTREACHED */
7889   return 0;
7890 }
7891
7892 static int
7893 api_l2_patch_add_del (vat_main_t * vam)
7894 {
7895   unformat_input_t *i = vam->input;
7896   vl_api_l2_patch_add_del_t *mp;
7897   f64 timeout;
7898   u32 rx_sw_if_index;
7899   u8 rx_sw_if_index_set = 0;
7900   u32 tx_sw_if_index;
7901   u8 tx_sw_if_index_set = 0;
7902   u8 is_add = 1;
7903
7904   /* Parse args required to build the message */
7905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7906     {
7907       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7908         rx_sw_if_index_set = 1;
7909       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7910         tx_sw_if_index_set = 1;
7911       else if (unformat (i, "rx"))
7912         {
7913           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7914             {
7915               if (unformat (i, "%U", unformat_sw_if_index, vam,
7916                             &rx_sw_if_index))
7917                 rx_sw_if_index_set = 1;
7918             }
7919           else
7920             break;
7921         }
7922       else if (unformat (i, "tx"))
7923         {
7924           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7925             {
7926               if (unformat (i, "%U", unformat_sw_if_index, vam,
7927                             &tx_sw_if_index))
7928                 tx_sw_if_index_set = 1;
7929             }
7930           else
7931             break;
7932         }
7933       else if (unformat (i, "del"))
7934         is_add = 0;
7935       else
7936         break;
7937     }
7938
7939   if (rx_sw_if_index_set == 0)
7940     {
7941       errmsg ("missing rx interface name or rx_sw_if_index\n");
7942       return -99;
7943     }
7944
7945   if (tx_sw_if_index_set == 0)
7946     {
7947       errmsg ("missing tx interface name or tx_sw_if_index\n");
7948       return -99;
7949     }
7950
7951   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7952
7953   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7954   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7955   mp->is_add = is_add;
7956
7957   S;
7958   W;
7959   /* NOTREACHED */
7960   return 0;
7961 }
7962
7963 static int
7964 api_ioam_enable (vat_main_t * vam)
7965 {
7966   unformat_input_t *input = vam->input;
7967   vl_api_ioam_enable_t *mp;
7968   f64 timeout;
7969   u32 id = 0;
7970   int has_trace_option = 0;
7971   int has_pot_option = 0;
7972   int has_seqno_option = 0;
7973   int has_analyse_option = 0;
7974
7975   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7976     {
7977       if (unformat (input, "trace"))
7978         has_trace_option = 1;
7979       else if (unformat (input, "pot"))
7980         has_pot_option = 1;
7981       else if (unformat (input, "seqno"))
7982         has_seqno_option = 1;
7983       else if (unformat (input, "analyse"))
7984         has_analyse_option = 1;
7985       else
7986         break;
7987     }
7988   M (IOAM_ENABLE, ioam_enable);
7989   mp->id = htons (id);
7990   mp->seqno = has_seqno_option;
7991   mp->analyse = has_analyse_option;
7992   mp->pot_enable = has_pot_option;
7993   mp->trace_enable = has_trace_option;
7994
7995   S;
7996   W;
7997
7998   return (0);
7999
8000 }
8001
8002
8003 static int
8004 api_ioam_disable (vat_main_t * vam)
8005 {
8006   vl_api_ioam_disable_t *mp;
8007   f64 timeout;
8008
8009   M (IOAM_DISABLE, ioam_disable);
8010   S;
8011   W;
8012   return 0;
8013 }
8014
8015 static int
8016 api_sr_tunnel_add_del (vat_main_t * vam)
8017 {
8018   unformat_input_t *i = vam->input;
8019   vl_api_sr_tunnel_add_del_t *mp;
8020   f64 timeout;
8021   int is_del = 0;
8022   int pl_index;
8023   ip6_address_t src_address;
8024   int src_address_set = 0;
8025   ip6_address_t dst_address;
8026   u32 dst_mask_width;
8027   int dst_address_set = 0;
8028   u16 flags = 0;
8029   u32 rx_table_id = 0;
8030   u32 tx_table_id = 0;
8031   ip6_address_t *segments = 0;
8032   ip6_address_t *this_seg;
8033   ip6_address_t *tags = 0;
8034   ip6_address_t *this_tag;
8035   ip6_address_t next_address, tag;
8036   u8 *name = 0;
8037   u8 *policy_name = 0;
8038
8039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8040     {
8041       if (unformat (i, "del"))
8042         is_del = 1;
8043       else if (unformat (i, "name %s", &name))
8044         ;
8045       else if (unformat (i, "policy %s", &policy_name))
8046         ;
8047       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8048         ;
8049       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8050         ;
8051       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8052         src_address_set = 1;
8053       else if (unformat (i, "dst %U/%d",
8054                          unformat_ip6_address, &dst_address, &dst_mask_width))
8055         dst_address_set = 1;
8056       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8057         {
8058           vec_add2 (segments, this_seg, 1);
8059           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8060                        sizeof (*this_seg));
8061         }
8062       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8063         {
8064           vec_add2 (tags, this_tag, 1);
8065           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8066         }
8067       else if (unformat (i, "clean"))
8068         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8069       else if (unformat (i, "protected"))
8070         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8071       else if (unformat (i, "InPE %d", &pl_index))
8072         {
8073           if (pl_index <= 0 || pl_index > 4)
8074             {
8075             pl_index_range_error:
8076               errmsg ("pl index %d out of range\n", pl_index);
8077               return -99;
8078             }
8079           flags |=
8080             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8081         }
8082       else if (unformat (i, "EgPE %d", &pl_index))
8083         {
8084           if (pl_index <= 0 || pl_index > 4)
8085             goto pl_index_range_error;
8086           flags |=
8087             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8088         }
8089       else if (unformat (i, "OrgSrc %d", &pl_index))
8090         {
8091           if (pl_index <= 0 || pl_index > 4)
8092             goto pl_index_range_error;
8093           flags |=
8094             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8095         }
8096       else
8097         break;
8098     }
8099
8100   if (!src_address_set)
8101     {
8102       errmsg ("src address required\n");
8103       return -99;
8104     }
8105
8106   if (!dst_address_set)
8107     {
8108       errmsg ("dst address required\n");
8109       return -99;
8110     }
8111
8112   if (!segments)
8113     {
8114       errmsg ("at least one sr segment required\n");
8115       return -99;
8116     }
8117
8118   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
8119       vec_len (segments) * sizeof (ip6_address_t)
8120       + vec_len (tags) * sizeof (ip6_address_t));
8121
8122   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8123   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8124   mp->dst_mask_width = dst_mask_width;
8125   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8126   mp->n_segments = vec_len (segments);
8127   mp->n_tags = vec_len (tags);
8128   mp->is_add = is_del == 0;
8129   clib_memcpy (mp->segs_and_tags, segments,
8130                vec_len (segments) * sizeof (ip6_address_t));
8131   clib_memcpy (mp->segs_and_tags +
8132                vec_len (segments) * sizeof (ip6_address_t), tags,
8133                vec_len (tags) * sizeof (ip6_address_t));
8134
8135   mp->outer_vrf_id = ntohl (rx_table_id);
8136   mp->inner_vrf_id = ntohl (tx_table_id);
8137   memcpy (mp->name, name, vec_len (name));
8138   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8139
8140   vec_free (segments);
8141   vec_free (tags);
8142
8143   S;
8144   W;
8145   /* NOTREACHED */
8146 }
8147
8148 static int
8149 api_sr_policy_add_del (vat_main_t * vam)
8150 {
8151   unformat_input_t *input = vam->input;
8152   vl_api_sr_policy_add_del_t *mp;
8153   f64 timeout;
8154   int is_del = 0;
8155   u8 *name = 0;
8156   u8 *tunnel_name = 0;
8157   u8 **tunnel_names = 0;
8158
8159   int name_set = 0;
8160   int tunnel_set = 0;
8161   int j = 0;
8162   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8163   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8164
8165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8166     {
8167       if (unformat (input, "del"))
8168         is_del = 1;
8169       else if (unformat (input, "name %s", &name))
8170         name_set = 1;
8171       else if (unformat (input, "tunnel %s", &tunnel_name))
8172         {
8173           if (tunnel_name)
8174             {
8175               vec_add1 (tunnel_names, tunnel_name);
8176               /* For serializer:
8177                  - length = #bytes to store in serial vector
8178                  - +1 = byte to store that length
8179                */
8180               tunnel_names_length += (vec_len (tunnel_name) + 1);
8181               tunnel_set = 1;
8182               tunnel_name = 0;
8183             }
8184         }
8185       else
8186         break;
8187     }
8188
8189   if (!name_set)
8190     {
8191       errmsg ("policy name required\n");
8192       return -99;
8193     }
8194
8195   if ((!tunnel_set) && (!is_del))
8196     {
8197       errmsg ("tunnel name required\n");
8198       return -99;
8199     }
8200
8201   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8202
8203
8204
8205   mp->is_add = !is_del;
8206
8207   memcpy (mp->name, name, vec_len (name));
8208   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8209   u8 *serial_orig = 0;
8210   vec_validate (serial_orig, tunnel_names_length);
8211   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8212   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8213
8214   for (j = 0; j < vec_len (tunnel_names); j++)
8215     {
8216       tun_name_len = vec_len (tunnel_names[j]);
8217       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8218       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8219       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8220       serial_orig += tun_name_len;      // Advance past the copy
8221     }
8222   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8223
8224   vec_free (tunnel_names);
8225   vec_free (tunnel_name);
8226
8227   S;
8228   W;
8229   /* NOTREACHED */
8230 }
8231
8232 static int
8233 api_sr_multicast_map_add_del (vat_main_t * vam)
8234 {
8235   unformat_input_t *input = vam->input;
8236   vl_api_sr_multicast_map_add_del_t *mp;
8237   f64 timeout;
8238   int is_del = 0;
8239   ip6_address_t multicast_address;
8240   u8 *policy_name = 0;
8241   int multicast_address_set = 0;
8242
8243   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8244     {
8245       if (unformat (input, "del"))
8246         is_del = 1;
8247       else
8248         if (unformat
8249             (input, "address %U", unformat_ip6_address, &multicast_address))
8250         multicast_address_set = 1;
8251       else if (unformat (input, "sr-policy %s", &policy_name))
8252         ;
8253       else
8254         break;
8255     }
8256
8257   if (!is_del && !policy_name)
8258     {
8259       errmsg ("sr-policy name required\n");
8260       return -99;
8261     }
8262
8263
8264   if (!multicast_address_set)
8265     {
8266       errmsg ("address required\n");
8267       return -99;
8268     }
8269
8270   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8271
8272   mp->is_add = !is_del;
8273   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8274   clib_memcpy (mp->multicast_address, &multicast_address,
8275                sizeof (mp->multicast_address));
8276
8277
8278   vec_free (policy_name);
8279
8280   S;
8281   W;
8282   /* NOTREACHED */
8283 }
8284
8285
8286 #define foreach_tcp_proto_field                 \
8287 _(src_port)                                     \
8288 _(dst_port)
8289
8290 #define foreach_udp_proto_field                 \
8291 _(src_port)                                     \
8292 _(dst_port)
8293
8294 #define foreach_ip4_proto_field                 \
8295 _(src_address)                                  \
8296 _(dst_address)                                  \
8297 _(tos)                                          \
8298 _(length)                                       \
8299 _(fragment_id)                                  \
8300 _(ttl)                                          \
8301 _(protocol)                                     \
8302 _(checksum)
8303
8304 uword
8305 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8306 {
8307   u8 **maskp = va_arg (*args, u8 **);
8308   u8 *mask = 0;
8309   u8 found_something = 0;
8310   tcp_header_t *tcp;
8311
8312 #define _(a) u8 a=0;
8313   foreach_tcp_proto_field;
8314 #undef _
8315
8316   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8317     {
8318       if (0);
8319 #define _(a) else if (unformat (input, #a)) a=1;
8320       foreach_tcp_proto_field
8321 #undef _
8322         else
8323         break;
8324     }
8325
8326 #define _(a) found_something += a;
8327   foreach_tcp_proto_field;
8328 #undef _
8329
8330   if (found_something == 0)
8331     return 0;
8332
8333   vec_validate (mask, sizeof (*tcp) - 1);
8334
8335   tcp = (tcp_header_t *) mask;
8336
8337 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8338   foreach_tcp_proto_field;
8339 #undef _
8340
8341   *maskp = mask;
8342   return 1;
8343 }
8344
8345 uword
8346 unformat_udp_mask (unformat_input_t * input, va_list * args)
8347 {
8348   u8 **maskp = va_arg (*args, u8 **);
8349   u8 *mask = 0;
8350   u8 found_something = 0;
8351   udp_header_t *udp;
8352
8353 #define _(a) u8 a=0;
8354   foreach_udp_proto_field;
8355 #undef _
8356
8357   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8358     {
8359       if (0);
8360 #define _(a) else if (unformat (input, #a)) a=1;
8361       foreach_udp_proto_field
8362 #undef _
8363         else
8364         break;
8365     }
8366
8367 #define _(a) found_something += a;
8368   foreach_udp_proto_field;
8369 #undef _
8370
8371   if (found_something == 0)
8372     return 0;
8373
8374   vec_validate (mask, sizeof (*udp) - 1);
8375
8376   udp = (udp_header_t *) mask;
8377
8378 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8379   foreach_udp_proto_field;
8380 #undef _
8381
8382   *maskp = mask;
8383   return 1;
8384 }
8385
8386 typedef struct
8387 {
8388   u16 src_port, dst_port;
8389 } tcpudp_header_t;
8390
8391 uword
8392 unformat_l4_mask (unformat_input_t * input, va_list * args)
8393 {
8394   u8 **maskp = va_arg (*args, u8 **);
8395   u16 src_port = 0, dst_port = 0;
8396   tcpudp_header_t *tcpudp;
8397
8398   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8399     {
8400       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8401         return 1;
8402       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8403         return 1;
8404       else if (unformat (input, "src_port"))
8405         src_port = 0xFFFF;
8406       else if (unformat (input, "dst_port"))
8407         dst_port = 0xFFFF;
8408       else
8409         return 0;
8410     }
8411
8412   if (!src_port && !dst_port)
8413     return 0;
8414
8415   u8 *mask = 0;
8416   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8417
8418   tcpudp = (tcpudp_header_t *) mask;
8419   tcpudp->src_port = src_port;
8420   tcpudp->dst_port = dst_port;
8421
8422   *maskp = mask;
8423
8424   return 1;
8425 }
8426
8427 uword
8428 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8429 {
8430   u8 **maskp = va_arg (*args, u8 **);
8431   u8 *mask = 0;
8432   u8 found_something = 0;
8433   ip4_header_t *ip;
8434
8435 #define _(a) u8 a=0;
8436   foreach_ip4_proto_field;
8437 #undef _
8438   u8 version = 0;
8439   u8 hdr_length = 0;
8440
8441
8442   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8443     {
8444       if (unformat (input, "version"))
8445         version = 1;
8446       else if (unformat (input, "hdr_length"))
8447         hdr_length = 1;
8448       else if (unformat (input, "src"))
8449         src_address = 1;
8450       else if (unformat (input, "dst"))
8451         dst_address = 1;
8452       else if (unformat (input, "proto"))
8453         protocol = 1;
8454
8455 #define _(a) else if (unformat (input, #a)) a=1;
8456       foreach_ip4_proto_field
8457 #undef _
8458         else
8459         break;
8460     }
8461
8462 #define _(a) found_something += a;
8463   foreach_ip4_proto_field;
8464 #undef _
8465
8466   if (found_something == 0)
8467     return 0;
8468
8469   vec_validate (mask, sizeof (*ip) - 1);
8470
8471   ip = (ip4_header_t *) mask;
8472
8473 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8474   foreach_ip4_proto_field;
8475 #undef _
8476
8477   ip->ip_version_and_header_length = 0;
8478
8479   if (version)
8480     ip->ip_version_and_header_length |= 0xF0;
8481
8482   if (hdr_length)
8483     ip->ip_version_and_header_length |= 0x0F;
8484
8485   *maskp = mask;
8486   return 1;
8487 }
8488
8489 #define foreach_ip6_proto_field                 \
8490 _(src_address)                                  \
8491 _(dst_address)                                  \
8492 _(payload_length)                               \
8493 _(hop_limit)                                    \
8494 _(protocol)
8495
8496 uword
8497 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8498 {
8499   u8 **maskp = va_arg (*args, u8 **);
8500   u8 *mask = 0;
8501   u8 found_something = 0;
8502   ip6_header_t *ip;
8503   u32 ip_version_traffic_class_and_flow_label;
8504
8505 #define _(a) u8 a=0;
8506   foreach_ip6_proto_field;
8507 #undef _
8508   u8 version = 0;
8509   u8 traffic_class = 0;
8510   u8 flow_label = 0;
8511
8512   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8513     {
8514       if (unformat (input, "version"))
8515         version = 1;
8516       else if (unformat (input, "traffic-class"))
8517         traffic_class = 1;
8518       else if (unformat (input, "flow-label"))
8519         flow_label = 1;
8520       else if (unformat (input, "src"))
8521         src_address = 1;
8522       else if (unformat (input, "dst"))
8523         dst_address = 1;
8524       else if (unformat (input, "proto"))
8525         protocol = 1;
8526
8527 #define _(a) else if (unformat (input, #a)) a=1;
8528       foreach_ip6_proto_field
8529 #undef _
8530         else
8531         break;
8532     }
8533
8534 #define _(a) found_something += a;
8535   foreach_ip6_proto_field;
8536 #undef _
8537
8538   if (found_something == 0)
8539     return 0;
8540
8541   vec_validate (mask, sizeof (*ip) - 1);
8542
8543   ip = (ip6_header_t *) mask;
8544
8545 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8546   foreach_ip6_proto_field;
8547 #undef _
8548
8549   ip_version_traffic_class_and_flow_label = 0;
8550
8551   if (version)
8552     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8553
8554   if (traffic_class)
8555     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8556
8557   if (flow_label)
8558     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8559
8560   ip->ip_version_traffic_class_and_flow_label =
8561     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8562
8563   *maskp = mask;
8564   return 1;
8565 }
8566
8567 uword
8568 unformat_l3_mask (unformat_input_t * input, va_list * args)
8569 {
8570   u8 **maskp = va_arg (*args, u8 **);
8571
8572   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8573     {
8574       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8575         return 1;
8576       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8577         return 1;
8578       else
8579         break;
8580     }
8581   return 0;
8582 }
8583
8584 uword
8585 unformat_l2_mask (unformat_input_t * input, va_list * args)
8586 {
8587   u8 **maskp = va_arg (*args, u8 **);
8588   u8 *mask = 0;
8589   u8 src = 0;
8590   u8 dst = 0;
8591   u8 proto = 0;
8592   u8 tag1 = 0;
8593   u8 tag2 = 0;
8594   u8 ignore_tag1 = 0;
8595   u8 ignore_tag2 = 0;
8596   u8 cos1 = 0;
8597   u8 cos2 = 0;
8598   u8 dot1q = 0;
8599   u8 dot1ad = 0;
8600   int len = 14;
8601
8602   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8603     {
8604       if (unformat (input, "src"))
8605         src = 1;
8606       else if (unformat (input, "dst"))
8607         dst = 1;
8608       else if (unformat (input, "proto"))
8609         proto = 1;
8610       else if (unformat (input, "tag1"))
8611         tag1 = 1;
8612       else if (unformat (input, "tag2"))
8613         tag2 = 1;
8614       else if (unformat (input, "ignore-tag1"))
8615         ignore_tag1 = 1;
8616       else if (unformat (input, "ignore-tag2"))
8617         ignore_tag2 = 1;
8618       else if (unformat (input, "cos1"))
8619         cos1 = 1;
8620       else if (unformat (input, "cos2"))
8621         cos2 = 1;
8622       else if (unformat (input, "dot1q"))
8623         dot1q = 1;
8624       else if (unformat (input, "dot1ad"))
8625         dot1ad = 1;
8626       else
8627         break;
8628     }
8629   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8630        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8631     return 0;
8632
8633   if (tag1 || ignore_tag1 || cos1 || dot1q)
8634     len = 18;
8635   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8636     len = 22;
8637
8638   vec_validate (mask, len - 1);
8639
8640   if (dst)
8641     memset (mask, 0xff, 6);
8642
8643   if (src)
8644     memset (mask + 6, 0xff, 6);
8645
8646   if (tag2 || dot1ad)
8647     {
8648       /* inner vlan tag */
8649       if (tag2)
8650         {
8651           mask[19] = 0xff;
8652           mask[18] = 0x0f;
8653         }
8654       if (cos2)
8655         mask[18] |= 0xe0;
8656       if (proto)
8657         mask[21] = mask[20] = 0xff;
8658       if (tag1)
8659         {
8660           mask[15] = 0xff;
8661           mask[14] = 0x0f;
8662         }
8663       if (cos1)
8664         mask[14] |= 0xe0;
8665       *maskp = mask;
8666       return 1;
8667     }
8668   if (tag1 | dot1q)
8669     {
8670       if (tag1)
8671         {
8672           mask[15] = 0xff;
8673           mask[14] = 0x0f;
8674         }
8675       if (cos1)
8676         mask[14] |= 0xe0;
8677       if (proto)
8678         mask[16] = mask[17] = 0xff;
8679
8680       *maskp = mask;
8681       return 1;
8682     }
8683   if (cos2)
8684     mask[18] |= 0xe0;
8685   if (cos1)
8686     mask[14] |= 0xe0;
8687   if (proto)
8688     mask[12] = mask[13] = 0xff;
8689
8690   *maskp = mask;
8691   return 1;
8692 }
8693
8694 uword
8695 unformat_classify_mask (unformat_input_t * input, va_list * args)
8696 {
8697   u8 **maskp = va_arg (*args, u8 **);
8698   u32 *skipp = va_arg (*args, u32 *);
8699   u32 *matchp = va_arg (*args, u32 *);
8700   u32 match;
8701   u8 *mask = 0;
8702   u8 *l2 = 0;
8703   u8 *l3 = 0;
8704   u8 *l4 = 0;
8705   int i;
8706
8707   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8708     {
8709       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8710         ;
8711       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8712         ;
8713       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8714         ;
8715       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8716         ;
8717       else
8718         break;
8719     }
8720
8721   if (l4 && !l3)
8722     {
8723       vec_free (mask);
8724       vec_free (l2);
8725       vec_free (l4);
8726       return 0;
8727     }
8728
8729   if (mask || l2 || l3 || l4)
8730     {
8731       if (l2 || l3 || l4)
8732         {
8733           /* "With a free Ethernet header in every package" */
8734           if (l2 == 0)
8735             vec_validate (l2, 13);
8736           mask = l2;
8737           if (vec_len (l3))
8738             {
8739               vec_append (mask, l3);
8740               vec_free (l3);
8741             }
8742           if (vec_len (l4))
8743             {
8744               vec_append (mask, l4);
8745               vec_free (l4);
8746             }
8747         }
8748
8749       /* Scan forward looking for the first significant mask octet */
8750       for (i = 0; i < vec_len (mask); i++)
8751         if (mask[i])
8752           break;
8753
8754       /* compute (skip, match) params */
8755       *skipp = i / sizeof (u32x4);
8756       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8757
8758       /* Pad mask to an even multiple of the vector size */
8759       while (vec_len (mask) % sizeof (u32x4))
8760         vec_add1 (mask, 0);
8761
8762       match = vec_len (mask) / sizeof (u32x4);
8763
8764       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8765         {
8766           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8767           if (*tmp || *(tmp + 1))
8768             break;
8769           match--;
8770         }
8771       if (match == 0)
8772         clib_warning ("BUG: match 0");
8773
8774       _vec_len (mask) = match * sizeof (u32x4);
8775
8776       *matchp = match;
8777       *maskp = mask;
8778
8779       return 1;
8780     }
8781
8782   return 0;
8783 }
8784
8785 #define foreach_l2_next                         \
8786 _(drop, DROP)                                   \
8787 _(ethernet, ETHERNET_INPUT)                     \
8788 _(ip4, IP4_INPUT)                               \
8789 _(ip6, IP6_INPUT)
8790
8791 uword
8792 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8793 {
8794   u32 *miss_next_indexp = va_arg (*args, u32 *);
8795   u32 next_index = 0;
8796   u32 tmp;
8797
8798 #define _(n,N) \
8799   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8800   foreach_l2_next;
8801 #undef _
8802
8803   if (unformat (input, "%d", &tmp))
8804     {
8805       next_index = tmp;
8806       goto out;
8807     }
8808
8809   return 0;
8810
8811 out:
8812   *miss_next_indexp = next_index;
8813   return 1;
8814 }
8815
8816 #define foreach_ip_next                         \
8817 _(drop, DROP)                                   \
8818 _(local, LOCAL)                                 \
8819 _(rewrite, REWRITE)
8820
8821 uword
8822 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8823 {
8824   u32 *miss_next_indexp = va_arg (*args, u32 *);
8825   u32 next_index = 0;
8826   u32 tmp;
8827
8828 #define _(n,N) \
8829   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8830   foreach_ip_next;
8831 #undef _
8832
8833   if (unformat (input, "%d", &tmp))
8834     {
8835       next_index = tmp;
8836       goto out;
8837     }
8838
8839   return 0;
8840
8841 out:
8842   *miss_next_indexp = next_index;
8843   return 1;
8844 }
8845
8846 #define foreach_acl_next                        \
8847 _(deny, DENY)
8848
8849 uword
8850 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8851 {
8852   u32 *miss_next_indexp = va_arg (*args, u32 *);
8853   u32 next_index = 0;
8854   u32 tmp;
8855
8856 #define _(n,N) \
8857   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8858   foreach_acl_next;
8859 #undef _
8860
8861   if (unformat (input, "permit"))
8862     {
8863       next_index = ~0;
8864       goto out;
8865     }
8866   else if (unformat (input, "%d", &tmp))
8867     {
8868       next_index = tmp;
8869       goto out;
8870     }
8871
8872   return 0;
8873
8874 out:
8875   *miss_next_indexp = next_index;
8876   return 1;
8877 }
8878
8879 uword
8880 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8881 {
8882   u32 *r = va_arg (*args, u32 *);
8883
8884   if (unformat (input, "conform-color"))
8885     *r = POLICE_CONFORM;
8886   else if (unformat (input, "exceed-color"))
8887     *r = POLICE_EXCEED;
8888   else
8889     return 0;
8890
8891   return 1;
8892 }
8893
8894 static int
8895 api_classify_add_del_table (vat_main_t * vam)
8896 {
8897   unformat_input_t *i = vam->input;
8898   vl_api_classify_add_del_table_t *mp;
8899
8900   u32 nbuckets = 2;
8901   u32 skip = ~0;
8902   u32 match = ~0;
8903   int is_add = 1;
8904   int del_chain = 0;
8905   u32 table_index = ~0;
8906   u32 next_table_index = ~0;
8907   u32 miss_next_index = ~0;
8908   u32 memory_size = 32 << 20;
8909   u8 *mask = 0;
8910   f64 timeout;
8911   u32 current_data_flag = 0;
8912   int current_data_offset = 0;
8913
8914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8915     {
8916       if (unformat (i, "del"))
8917         is_add = 0;
8918       else if (unformat (i, "del-chain"))
8919         {
8920           is_add = 0;
8921           del_chain = 1;
8922         }
8923       else if (unformat (i, "buckets %d", &nbuckets))
8924         ;
8925       else if (unformat (i, "memory_size %d", &memory_size))
8926         ;
8927       else if (unformat (i, "skip %d", &skip))
8928         ;
8929       else if (unformat (i, "match %d", &match))
8930         ;
8931       else if (unformat (i, "table %d", &table_index))
8932         ;
8933       else if (unformat (i, "mask %U", unformat_classify_mask,
8934                          &mask, &skip, &match))
8935         ;
8936       else if (unformat (i, "next-table %d", &next_table_index))
8937         ;
8938       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8939                          &miss_next_index))
8940         ;
8941       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8942                          &miss_next_index))
8943         ;
8944       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8945                          &miss_next_index))
8946         ;
8947       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8948         ;
8949       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8950         ;
8951       else
8952         break;
8953     }
8954
8955   if (is_add && mask == 0)
8956     {
8957       errmsg ("Mask required\n");
8958       return -99;
8959     }
8960
8961   if (is_add && skip == ~0)
8962     {
8963       errmsg ("skip count required\n");
8964       return -99;
8965     }
8966
8967   if (is_add && match == ~0)
8968     {
8969       errmsg ("match count required\n");
8970       return -99;
8971     }
8972
8973   if (!is_add && table_index == ~0)
8974     {
8975       errmsg ("table index required for delete\n");
8976       return -99;
8977     }
8978
8979   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8980
8981   mp->is_add = is_add;
8982   mp->del_chain = del_chain;
8983   mp->table_index = ntohl (table_index);
8984   mp->nbuckets = ntohl (nbuckets);
8985   mp->memory_size = ntohl (memory_size);
8986   mp->skip_n_vectors = ntohl (skip);
8987   mp->match_n_vectors = ntohl (match);
8988   mp->next_table_index = ntohl (next_table_index);
8989   mp->miss_next_index = ntohl (miss_next_index);
8990   mp->current_data_flag = ntohl (current_data_flag);
8991   mp->current_data_offset = ntohl (current_data_offset);
8992   clib_memcpy (mp->mask, mask, vec_len (mask));
8993
8994   vec_free (mask);
8995
8996   S;
8997   W;
8998   /* NOTREACHED */
8999 }
9000
9001 uword
9002 unformat_l4_match (unformat_input_t * input, va_list * args)
9003 {
9004   u8 **matchp = va_arg (*args, u8 **);
9005
9006   u8 *proto_header = 0;
9007   int src_port = 0;
9008   int dst_port = 0;
9009
9010   tcpudp_header_t h;
9011
9012   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9013     {
9014       if (unformat (input, "src_port %d", &src_port))
9015         ;
9016       else if (unformat (input, "dst_port %d", &dst_port))
9017         ;
9018       else
9019         return 0;
9020     }
9021
9022   h.src_port = clib_host_to_net_u16 (src_port);
9023   h.dst_port = clib_host_to_net_u16 (dst_port);
9024   vec_validate (proto_header, sizeof (h) - 1);
9025   memcpy (proto_header, &h, sizeof (h));
9026
9027   *matchp = proto_header;
9028
9029   return 1;
9030 }
9031
9032 uword
9033 unformat_ip4_match (unformat_input_t * input, va_list * args)
9034 {
9035   u8 **matchp = va_arg (*args, u8 **);
9036   u8 *match = 0;
9037   ip4_header_t *ip;
9038   int version = 0;
9039   u32 version_val;
9040   int hdr_length = 0;
9041   u32 hdr_length_val;
9042   int src = 0, dst = 0;
9043   ip4_address_t src_val, dst_val;
9044   int proto = 0;
9045   u32 proto_val;
9046   int tos = 0;
9047   u32 tos_val;
9048   int length = 0;
9049   u32 length_val;
9050   int fragment_id = 0;
9051   u32 fragment_id_val;
9052   int ttl = 0;
9053   int ttl_val;
9054   int checksum = 0;
9055   u32 checksum_val;
9056
9057   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9058     {
9059       if (unformat (input, "version %d", &version_val))
9060         version = 1;
9061       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9062         hdr_length = 1;
9063       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9064         src = 1;
9065       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9066         dst = 1;
9067       else if (unformat (input, "proto %d", &proto_val))
9068         proto = 1;
9069       else if (unformat (input, "tos %d", &tos_val))
9070         tos = 1;
9071       else if (unformat (input, "length %d", &length_val))
9072         length = 1;
9073       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9074         fragment_id = 1;
9075       else if (unformat (input, "ttl %d", &ttl_val))
9076         ttl = 1;
9077       else if (unformat (input, "checksum %d", &checksum_val))
9078         checksum = 1;
9079       else
9080         break;
9081     }
9082
9083   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9084       + ttl + checksum == 0)
9085     return 0;
9086
9087   /*
9088    * Aligned because we use the real comparison functions
9089    */
9090   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9091
9092   ip = (ip4_header_t *) match;
9093
9094   /* These are realistically matched in practice */
9095   if (src)
9096     ip->src_address.as_u32 = src_val.as_u32;
9097
9098   if (dst)
9099     ip->dst_address.as_u32 = dst_val.as_u32;
9100
9101   if (proto)
9102     ip->protocol = proto_val;
9103
9104
9105   /* These are not, but they're included for completeness */
9106   if (version)
9107     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9108
9109   if (hdr_length)
9110     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9111
9112   if (tos)
9113     ip->tos = tos_val;
9114
9115   if (length)
9116     ip->length = clib_host_to_net_u16 (length_val);
9117
9118   if (ttl)
9119     ip->ttl = ttl_val;
9120
9121   if (checksum)
9122     ip->checksum = clib_host_to_net_u16 (checksum_val);
9123
9124   *matchp = match;
9125   return 1;
9126 }
9127
9128 uword
9129 unformat_ip6_match (unformat_input_t * input, va_list * args)
9130 {
9131   u8 **matchp = va_arg (*args, u8 **);
9132   u8 *match = 0;
9133   ip6_header_t *ip;
9134   int version = 0;
9135   u32 version_val;
9136   u8 traffic_class = 0;
9137   u32 traffic_class_val = 0;
9138   u8 flow_label = 0;
9139   u8 flow_label_val;
9140   int src = 0, dst = 0;
9141   ip6_address_t src_val, dst_val;
9142   int proto = 0;
9143   u32 proto_val;
9144   int payload_length = 0;
9145   u32 payload_length_val;
9146   int hop_limit = 0;
9147   int hop_limit_val;
9148   u32 ip_version_traffic_class_and_flow_label;
9149
9150   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9151     {
9152       if (unformat (input, "version %d", &version_val))
9153         version = 1;
9154       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9155         traffic_class = 1;
9156       else if (unformat (input, "flow_label %d", &flow_label_val))
9157         flow_label = 1;
9158       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9159         src = 1;
9160       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9161         dst = 1;
9162       else if (unformat (input, "proto %d", &proto_val))
9163         proto = 1;
9164       else if (unformat (input, "payload_length %d", &payload_length_val))
9165         payload_length = 1;
9166       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9167         hop_limit = 1;
9168       else
9169         break;
9170     }
9171
9172   if (version + traffic_class + flow_label + src + dst + proto +
9173       payload_length + hop_limit == 0)
9174     return 0;
9175
9176   /*
9177    * Aligned because we use the real comparison functions
9178    */
9179   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9180
9181   ip = (ip6_header_t *) match;
9182
9183   if (src)
9184     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9185
9186   if (dst)
9187     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9188
9189   if (proto)
9190     ip->protocol = proto_val;
9191
9192   ip_version_traffic_class_and_flow_label = 0;
9193
9194   if (version)
9195     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9196
9197   if (traffic_class)
9198     ip_version_traffic_class_and_flow_label |=
9199       (traffic_class_val & 0xFF) << 20;
9200
9201   if (flow_label)
9202     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9203
9204   ip->ip_version_traffic_class_and_flow_label =
9205     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9206
9207   if (payload_length)
9208     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9209
9210   if (hop_limit)
9211     ip->hop_limit = hop_limit_val;
9212
9213   *matchp = match;
9214   return 1;
9215 }
9216
9217 uword
9218 unformat_l3_match (unformat_input_t * input, va_list * args)
9219 {
9220   u8 **matchp = va_arg (*args, u8 **);
9221
9222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9223     {
9224       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9225         return 1;
9226       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9227         return 1;
9228       else
9229         break;
9230     }
9231   return 0;
9232 }
9233
9234 uword
9235 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9236 {
9237   u8 *tagp = va_arg (*args, u8 *);
9238   u32 tag;
9239
9240   if (unformat (input, "%d", &tag))
9241     {
9242       tagp[0] = (tag >> 8) & 0x0F;
9243       tagp[1] = tag & 0xFF;
9244       return 1;
9245     }
9246
9247   return 0;
9248 }
9249
9250 uword
9251 unformat_l2_match (unformat_input_t * input, va_list * args)
9252 {
9253   u8 **matchp = va_arg (*args, u8 **);
9254   u8 *match = 0;
9255   u8 src = 0;
9256   u8 src_val[6];
9257   u8 dst = 0;
9258   u8 dst_val[6];
9259   u8 proto = 0;
9260   u16 proto_val;
9261   u8 tag1 = 0;
9262   u8 tag1_val[2];
9263   u8 tag2 = 0;
9264   u8 tag2_val[2];
9265   int len = 14;
9266   u8 ignore_tag1 = 0;
9267   u8 ignore_tag2 = 0;
9268   u8 cos1 = 0;
9269   u8 cos2 = 0;
9270   u32 cos1_val = 0;
9271   u32 cos2_val = 0;
9272
9273   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9274     {
9275       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9276         src = 1;
9277       else
9278         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9279         dst = 1;
9280       else if (unformat (input, "proto %U",
9281                          unformat_ethernet_type_host_byte_order, &proto_val))
9282         proto = 1;
9283       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9284         tag1 = 1;
9285       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9286         tag2 = 1;
9287       else if (unformat (input, "ignore-tag1"))
9288         ignore_tag1 = 1;
9289       else if (unformat (input, "ignore-tag2"))
9290         ignore_tag2 = 1;
9291       else if (unformat (input, "cos1 %d", &cos1_val))
9292         cos1 = 1;
9293       else if (unformat (input, "cos2 %d", &cos2_val))
9294         cos2 = 1;
9295       else
9296         break;
9297     }
9298   if ((src + dst + proto + tag1 + tag2 +
9299        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9300     return 0;
9301
9302   if (tag1 || ignore_tag1 || cos1)
9303     len = 18;
9304   if (tag2 || ignore_tag2 || cos2)
9305     len = 22;
9306
9307   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9308
9309   if (dst)
9310     clib_memcpy (match, dst_val, 6);
9311
9312   if (src)
9313     clib_memcpy (match + 6, src_val, 6);
9314
9315   if (tag2)
9316     {
9317       /* inner vlan tag */
9318       match[19] = tag2_val[1];
9319       match[18] = tag2_val[0];
9320       if (cos2)
9321         match[18] |= (cos2_val & 0x7) << 5;
9322       if (proto)
9323         {
9324           match[21] = proto_val & 0xff;
9325           match[20] = proto_val >> 8;
9326         }
9327       if (tag1)
9328         {
9329           match[15] = tag1_val[1];
9330           match[14] = tag1_val[0];
9331         }
9332       if (cos1)
9333         match[14] |= (cos1_val & 0x7) << 5;
9334       *matchp = match;
9335       return 1;
9336     }
9337   if (tag1)
9338     {
9339       match[15] = tag1_val[1];
9340       match[14] = tag1_val[0];
9341       if (proto)
9342         {
9343           match[17] = proto_val & 0xff;
9344           match[16] = proto_val >> 8;
9345         }
9346       if (cos1)
9347         match[14] |= (cos1_val & 0x7) << 5;
9348
9349       *matchp = match;
9350       return 1;
9351     }
9352   if (cos2)
9353     match[18] |= (cos2_val & 0x7) << 5;
9354   if (cos1)
9355     match[14] |= (cos1_val & 0x7) << 5;
9356   if (proto)
9357     {
9358       match[13] = proto_val & 0xff;
9359       match[12] = proto_val >> 8;
9360     }
9361
9362   *matchp = match;
9363   return 1;
9364 }
9365
9366
9367 uword
9368 unformat_classify_match (unformat_input_t * input, va_list * args)
9369 {
9370   u8 **matchp = va_arg (*args, u8 **);
9371   u32 skip_n_vectors = va_arg (*args, u32);
9372   u32 match_n_vectors = va_arg (*args, u32);
9373
9374   u8 *match = 0;
9375   u8 *l2 = 0;
9376   u8 *l3 = 0;
9377   u8 *l4 = 0;
9378
9379   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9380     {
9381       if (unformat (input, "hex %U", unformat_hex_string, &match))
9382         ;
9383       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9384         ;
9385       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9386         ;
9387       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9388         ;
9389       else
9390         break;
9391     }
9392
9393   if (l4 && !l3)
9394     {
9395       vec_free (match);
9396       vec_free (l2);
9397       vec_free (l4);
9398       return 0;
9399     }
9400
9401   if (match || l2 || l3 || l4)
9402     {
9403       if (l2 || l3 || l4)
9404         {
9405           /* "Win a free Ethernet header in every packet" */
9406           if (l2 == 0)
9407             vec_validate_aligned (l2, 13, sizeof (u32x4));
9408           match = l2;
9409           if (vec_len (l3))
9410             {
9411               vec_append_aligned (match, l3, sizeof (u32x4));
9412               vec_free (l3);
9413             }
9414           if (vec_len (l4))
9415             {
9416               vec_append_aligned (match, l4, sizeof (u32x4));
9417               vec_free (l4);
9418             }
9419         }
9420
9421       /* Make sure the vector is big enough even if key is all 0's */
9422       vec_validate_aligned
9423         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9424          sizeof (u32x4));
9425
9426       /* Set size, include skipped vectors */
9427       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9428
9429       *matchp = match;
9430
9431       return 1;
9432     }
9433
9434   return 0;
9435 }
9436
9437 static int
9438 api_classify_add_del_session (vat_main_t * vam)
9439 {
9440   unformat_input_t *i = vam->input;
9441   vl_api_classify_add_del_session_t *mp;
9442   int is_add = 1;
9443   u32 table_index = ~0;
9444   u32 hit_next_index = ~0;
9445   u32 opaque_index = ~0;
9446   u8 *match = 0;
9447   i32 advance = 0;
9448   f64 timeout;
9449   u32 skip_n_vectors = 0;
9450   u32 match_n_vectors = 0;
9451   u32 action = 0;
9452   u32 metadata = 0;
9453
9454   /*
9455    * Warning: you have to supply skip_n and match_n
9456    * because the API client cant simply look at the classify
9457    * table object.
9458    */
9459
9460   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9461     {
9462       if (unformat (i, "del"))
9463         is_add = 0;
9464       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9465                          &hit_next_index))
9466         ;
9467       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9468                          &hit_next_index))
9469         ;
9470       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9471                          &hit_next_index))
9472         ;
9473       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9474         ;
9475       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9476         ;
9477       else if (unformat (i, "opaque-index %d", &opaque_index))
9478         ;
9479       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9480         ;
9481       else if (unformat (i, "match_n %d", &match_n_vectors))
9482         ;
9483       else if (unformat (i, "match %U", unformat_classify_match,
9484                          &match, skip_n_vectors, match_n_vectors))
9485         ;
9486       else if (unformat (i, "advance %d", &advance))
9487         ;
9488       else if (unformat (i, "table-index %d", &table_index))
9489         ;
9490       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9491         action = 1;
9492       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9493         action = 2;
9494       else if (unformat (i, "action %d", &action))
9495         ;
9496       else if (unformat (i, "metadata %d", &metadata))
9497         ;
9498       else
9499         break;
9500     }
9501
9502   if (table_index == ~0)
9503     {
9504       errmsg ("Table index required\n");
9505       return -99;
9506     }
9507
9508   if (is_add && match == 0)
9509     {
9510       errmsg ("Match value required\n");
9511       return -99;
9512     }
9513
9514   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9515
9516   mp->is_add = is_add;
9517   mp->table_index = ntohl (table_index);
9518   mp->hit_next_index = ntohl (hit_next_index);
9519   mp->opaque_index = ntohl (opaque_index);
9520   mp->advance = ntohl (advance);
9521   mp->action = action;
9522   mp->metadata = ntohl (metadata);
9523   clib_memcpy (mp->match, match, vec_len (match));
9524   vec_free (match);
9525
9526   S;
9527   W;
9528   /* NOTREACHED */
9529 }
9530
9531 static int
9532 api_classify_set_interface_ip_table (vat_main_t * vam)
9533 {
9534   unformat_input_t *i = vam->input;
9535   vl_api_classify_set_interface_ip_table_t *mp;
9536   f64 timeout;
9537   u32 sw_if_index;
9538   int sw_if_index_set;
9539   u32 table_index = ~0;
9540   u8 is_ipv6 = 0;
9541
9542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9543     {
9544       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9545         sw_if_index_set = 1;
9546       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9547         sw_if_index_set = 1;
9548       else if (unformat (i, "table %d", &table_index))
9549         ;
9550       else
9551         {
9552           clib_warning ("parse error '%U'", format_unformat_error, i);
9553           return -99;
9554         }
9555     }
9556
9557   if (sw_if_index_set == 0)
9558     {
9559       errmsg ("missing interface name or sw_if_index\n");
9560       return -99;
9561     }
9562
9563
9564   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9565
9566   mp->sw_if_index = ntohl (sw_if_index);
9567   mp->table_index = ntohl (table_index);
9568   mp->is_ipv6 = is_ipv6;
9569
9570   S;
9571   W;
9572   /* NOTREACHED */
9573   return 0;
9574 }
9575
9576 static int
9577 api_classify_set_interface_l2_tables (vat_main_t * vam)
9578 {
9579   unformat_input_t *i = vam->input;
9580   vl_api_classify_set_interface_l2_tables_t *mp;
9581   f64 timeout;
9582   u32 sw_if_index;
9583   int sw_if_index_set;
9584   u32 ip4_table_index = ~0;
9585   u32 ip6_table_index = ~0;
9586   u32 other_table_index = ~0;
9587   u32 is_input = 1;
9588
9589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9590     {
9591       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9592         sw_if_index_set = 1;
9593       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9594         sw_if_index_set = 1;
9595       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9596         ;
9597       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9598         ;
9599       else if (unformat (i, "other-table %d", &other_table_index))
9600         ;
9601       else if (unformat (i, "is-input %d", &is_input))
9602         ;
9603       else
9604         {
9605           clib_warning ("parse error '%U'", format_unformat_error, i);
9606           return -99;
9607         }
9608     }
9609
9610   if (sw_if_index_set == 0)
9611     {
9612       errmsg ("missing interface name or sw_if_index\n");
9613       return -99;
9614     }
9615
9616
9617   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9618
9619   mp->sw_if_index = ntohl (sw_if_index);
9620   mp->ip4_table_index = ntohl (ip4_table_index);
9621   mp->ip6_table_index = ntohl (ip6_table_index);
9622   mp->other_table_index = ntohl (other_table_index);
9623   mp->is_input = (u8) is_input;
9624
9625   S;
9626   W;
9627   /* NOTREACHED */
9628   return 0;
9629 }
9630
9631 static int
9632 api_set_ipfix_exporter (vat_main_t * vam)
9633 {
9634   unformat_input_t *i = vam->input;
9635   vl_api_set_ipfix_exporter_t *mp;
9636   ip4_address_t collector_address;
9637   u8 collector_address_set = 0;
9638   u32 collector_port = ~0;
9639   ip4_address_t src_address;
9640   u8 src_address_set = 0;
9641   u32 vrf_id = ~0;
9642   u32 path_mtu = ~0;
9643   u32 template_interval = ~0;
9644   u8 udp_checksum = 0;
9645   f64 timeout;
9646
9647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9648     {
9649       if (unformat (i, "collector_address %U", unformat_ip4_address,
9650                     &collector_address))
9651         collector_address_set = 1;
9652       else if (unformat (i, "collector_port %d", &collector_port))
9653         ;
9654       else if (unformat (i, "src_address %U", unformat_ip4_address,
9655                          &src_address))
9656         src_address_set = 1;
9657       else if (unformat (i, "vrf_id %d", &vrf_id))
9658         ;
9659       else if (unformat (i, "path_mtu %d", &path_mtu))
9660         ;
9661       else if (unformat (i, "template_interval %d", &template_interval))
9662         ;
9663       else if (unformat (i, "udp_checksum"))
9664         udp_checksum = 1;
9665       else
9666         break;
9667     }
9668
9669   if (collector_address_set == 0)
9670     {
9671       errmsg ("collector_address required\n");
9672       return -99;
9673     }
9674
9675   if (src_address_set == 0)
9676     {
9677       errmsg ("src_address required\n");
9678       return -99;
9679     }
9680
9681   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9682
9683   memcpy (mp->collector_address, collector_address.data,
9684           sizeof (collector_address.data));
9685   mp->collector_port = htons ((u16) collector_port);
9686   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9687   mp->vrf_id = htonl (vrf_id);
9688   mp->path_mtu = htonl (path_mtu);
9689   mp->template_interval = htonl (template_interval);
9690   mp->udp_checksum = udp_checksum;
9691
9692   S;
9693   W;
9694   /* NOTREACHED */
9695 }
9696
9697 static int
9698 api_set_ipfix_classify_stream (vat_main_t * vam)
9699 {
9700   unformat_input_t *i = vam->input;
9701   vl_api_set_ipfix_classify_stream_t *mp;
9702   u32 domain_id = 0;
9703   u32 src_port = UDP_DST_PORT_ipfix;
9704   f64 timeout;
9705
9706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9707     {
9708       if (unformat (i, "domain %d", &domain_id))
9709         ;
9710       else if (unformat (i, "src_port %d", &src_port))
9711         ;
9712       else
9713         {
9714           errmsg ("unknown input `%U'", format_unformat_error, i);
9715           return -99;
9716         }
9717     }
9718
9719   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9720
9721   mp->domain_id = htonl (domain_id);
9722   mp->src_port = htons ((u16) src_port);
9723
9724   S;
9725   W;
9726   /* NOTREACHED */
9727 }
9728
9729 static int
9730 api_ipfix_classify_table_add_del (vat_main_t * vam)
9731 {
9732   unformat_input_t *i = vam->input;
9733   vl_api_ipfix_classify_table_add_del_t *mp;
9734   int is_add = -1;
9735   u32 classify_table_index = ~0;
9736   u8 ip_version = 0;
9737   u8 transport_protocol = 255;
9738   f64 timeout;
9739
9740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9741     {
9742       if (unformat (i, "add"))
9743         is_add = 1;
9744       else if (unformat (i, "del"))
9745         is_add = 0;
9746       else if (unformat (i, "table %d", &classify_table_index))
9747         ;
9748       else if (unformat (i, "ip4"))
9749         ip_version = 4;
9750       else if (unformat (i, "ip6"))
9751         ip_version = 6;
9752       else if (unformat (i, "tcp"))
9753         transport_protocol = 6;
9754       else if (unformat (i, "udp"))
9755         transport_protocol = 17;
9756       else
9757         {
9758           errmsg ("unknown input `%U'", format_unformat_error, i);
9759           return -99;
9760         }
9761     }
9762
9763   if (is_add == -1)
9764     {
9765       errmsg ("expecting: add|del");
9766       return -99;
9767     }
9768   if (classify_table_index == ~0)
9769     {
9770       errmsg ("classifier table not specified");
9771       return -99;
9772     }
9773   if (ip_version == 0)
9774     {
9775       errmsg ("IP version not specified");
9776       return -99;
9777     }
9778
9779   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9780
9781   mp->is_add = is_add;
9782   mp->table_id = htonl (classify_table_index);
9783   mp->ip_version = ip_version;
9784   mp->transport_protocol = transport_protocol;
9785
9786   S;
9787   W;
9788   /* NOTREACHED */
9789 }
9790
9791 static int
9792 api_get_node_index (vat_main_t * vam)
9793 {
9794   unformat_input_t *i = vam->input;
9795   vl_api_get_node_index_t *mp;
9796   f64 timeout;
9797   u8 *name = 0;
9798
9799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9800     {
9801       if (unformat (i, "node %s", &name))
9802         ;
9803       else
9804         break;
9805     }
9806   if (name == 0)
9807     {
9808       errmsg ("node name required\n");
9809       return -99;
9810     }
9811   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9812     {
9813       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9814       return -99;
9815     }
9816
9817   M (GET_NODE_INDEX, get_node_index);
9818   clib_memcpy (mp->node_name, name, vec_len (name));
9819   vec_free (name);
9820
9821   S;
9822   W;
9823   /* NOTREACHED */
9824   return 0;
9825 }
9826
9827 static int
9828 api_get_next_index (vat_main_t * vam)
9829 {
9830   unformat_input_t *i = vam->input;
9831   vl_api_get_next_index_t *mp;
9832   f64 timeout;
9833   u8 *node_name = 0, *next_node_name = 0;
9834
9835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9836     {
9837       if (unformat (i, "node-name %s", &node_name))
9838         ;
9839       else if (unformat (i, "next-node-name %s", &next_node_name))
9840         break;
9841     }
9842
9843   if (node_name == 0)
9844     {
9845       errmsg ("node name required\n");
9846       return -99;
9847     }
9848   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9849     {
9850       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9851       return -99;
9852     }
9853
9854   if (next_node_name == 0)
9855     {
9856       errmsg ("next node name required\n");
9857       return -99;
9858     }
9859   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9860     {
9861       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9862       return -99;
9863     }
9864
9865   M (GET_NEXT_INDEX, get_next_index);
9866   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9867   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9868   vec_free (node_name);
9869   vec_free (next_node_name);
9870
9871   S;
9872   W;
9873   /* NOTREACHED */
9874   return 0;
9875 }
9876
9877 static int
9878 api_add_node_next (vat_main_t * vam)
9879 {
9880   unformat_input_t *i = vam->input;
9881   vl_api_add_node_next_t *mp;
9882   f64 timeout;
9883   u8 *name = 0;
9884   u8 *next = 0;
9885
9886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9887     {
9888       if (unformat (i, "node %s", &name))
9889         ;
9890       else if (unformat (i, "next %s", &next))
9891         ;
9892       else
9893         break;
9894     }
9895   if (name == 0)
9896     {
9897       errmsg ("node name required\n");
9898       return -99;
9899     }
9900   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9901     {
9902       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9903       return -99;
9904     }
9905   if (next == 0)
9906     {
9907       errmsg ("next node required\n");
9908       return -99;
9909     }
9910   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9911     {
9912       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9913       return -99;
9914     }
9915
9916   M (ADD_NODE_NEXT, add_node_next);
9917   clib_memcpy (mp->node_name, name, vec_len (name));
9918   clib_memcpy (mp->next_name, next, vec_len (next));
9919   vec_free (name);
9920   vec_free (next);
9921
9922   S;
9923   W;
9924   /* NOTREACHED */
9925   return 0;
9926 }
9927
9928 static int
9929 api_l2tpv3_create_tunnel (vat_main_t * vam)
9930 {
9931   unformat_input_t *i = vam->input;
9932   ip6_address_t client_address, our_address;
9933   int client_address_set = 0;
9934   int our_address_set = 0;
9935   u32 local_session_id = 0;
9936   u32 remote_session_id = 0;
9937   u64 local_cookie = 0;
9938   u64 remote_cookie = 0;
9939   u8 l2_sublayer_present = 0;
9940   vl_api_l2tpv3_create_tunnel_t *mp;
9941   f64 timeout;
9942
9943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9944     {
9945       if (unformat (i, "client_address %U", unformat_ip6_address,
9946                     &client_address))
9947         client_address_set = 1;
9948       else if (unformat (i, "our_address %U", unformat_ip6_address,
9949                          &our_address))
9950         our_address_set = 1;
9951       else if (unformat (i, "local_session_id %d", &local_session_id))
9952         ;
9953       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9954         ;
9955       else if (unformat (i, "local_cookie %lld", &local_cookie))
9956         ;
9957       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9958         ;
9959       else if (unformat (i, "l2-sublayer-present"))
9960         l2_sublayer_present = 1;
9961       else
9962         break;
9963     }
9964
9965   if (client_address_set == 0)
9966     {
9967       errmsg ("client_address required\n");
9968       return -99;
9969     }
9970
9971   if (our_address_set == 0)
9972     {
9973       errmsg ("our_address required\n");
9974       return -99;
9975     }
9976
9977   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9978
9979   clib_memcpy (mp->client_address, client_address.as_u8,
9980                sizeof (mp->client_address));
9981
9982   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9983
9984   mp->local_session_id = ntohl (local_session_id);
9985   mp->remote_session_id = ntohl (remote_session_id);
9986   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9987   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9988   mp->l2_sublayer_present = l2_sublayer_present;
9989   mp->is_ipv6 = 1;
9990
9991   S;
9992   W;
9993   /* NOTREACHED */
9994   return 0;
9995 }
9996
9997 static int
9998 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9999 {
10000   unformat_input_t *i = vam->input;
10001   u32 sw_if_index;
10002   u8 sw_if_index_set = 0;
10003   u64 new_local_cookie = 0;
10004   u64 new_remote_cookie = 0;
10005   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10006   f64 timeout;
10007
10008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10009     {
10010       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10011         sw_if_index_set = 1;
10012       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10013         sw_if_index_set = 1;
10014       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10015         ;
10016       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10017         ;
10018       else
10019         break;
10020     }
10021
10022   if (sw_if_index_set == 0)
10023     {
10024       errmsg ("missing interface name or sw_if_index\n");
10025       return -99;
10026     }
10027
10028   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
10029
10030   mp->sw_if_index = ntohl (sw_if_index);
10031   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10032   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10033
10034   S;
10035   W;
10036   /* NOTREACHED */
10037   return 0;
10038 }
10039
10040 static int
10041 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10042 {
10043   unformat_input_t *i = vam->input;
10044   vl_api_l2tpv3_interface_enable_disable_t *mp;
10045   f64 timeout;
10046   u32 sw_if_index;
10047   u8 sw_if_index_set = 0;
10048   u8 enable_disable = 1;
10049
10050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10051     {
10052       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10053         sw_if_index_set = 1;
10054       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10055         sw_if_index_set = 1;
10056       else if (unformat (i, "enable"))
10057         enable_disable = 1;
10058       else if (unformat (i, "disable"))
10059         enable_disable = 0;
10060       else
10061         break;
10062     }
10063
10064   if (sw_if_index_set == 0)
10065     {
10066       errmsg ("missing interface name or sw_if_index\n");
10067       return -99;
10068     }
10069
10070   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
10071
10072   mp->sw_if_index = ntohl (sw_if_index);
10073   mp->enable_disable = enable_disable;
10074
10075   S;
10076   W;
10077   /* NOTREACHED */
10078   return 0;
10079 }
10080
10081 static int
10082 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10083 {
10084   unformat_input_t *i = vam->input;
10085   vl_api_l2tpv3_set_lookup_key_t *mp;
10086   f64 timeout;
10087   u8 key = ~0;
10088
10089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10090     {
10091       if (unformat (i, "lookup_v6_src"))
10092         key = L2T_LOOKUP_SRC_ADDRESS;
10093       else if (unformat (i, "lookup_v6_dst"))
10094         key = L2T_LOOKUP_DST_ADDRESS;
10095       else if (unformat (i, "lookup_session_id"))
10096         key = L2T_LOOKUP_SESSION_ID;
10097       else
10098         break;
10099     }
10100
10101   if (key == (u8) ~ 0)
10102     {
10103       errmsg ("l2tp session lookup key unset\n");
10104       return -99;
10105     }
10106
10107   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
10108
10109   mp->key = key;
10110
10111   S;
10112   W;
10113   /* NOTREACHED */
10114   return 0;
10115 }
10116
10117 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10118   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10119 {
10120   vat_main_t *vam = &vat_main;
10121
10122   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
10123            format_ip6_address, mp->our_address,
10124            format_ip6_address, mp->client_address,
10125            clib_net_to_host_u32 (mp->sw_if_index));
10126
10127   fformat (vam->ofp,
10128            "   local cookies %016llx %016llx remote cookie %016llx\n",
10129            clib_net_to_host_u64 (mp->local_cookie[0]),
10130            clib_net_to_host_u64 (mp->local_cookie[1]),
10131            clib_net_to_host_u64 (mp->remote_cookie));
10132
10133   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
10134            clib_net_to_host_u32 (mp->local_session_id),
10135            clib_net_to_host_u32 (mp->remote_session_id));
10136
10137   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
10138            mp->l2_sublayer_present ? "preset" : "absent");
10139
10140 }
10141
10142 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10143   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10144 {
10145   vat_main_t *vam = &vat_main;
10146   vat_json_node_t *node = NULL;
10147   struct in6_addr addr;
10148
10149   if (VAT_JSON_ARRAY != vam->json_tree.type)
10150     {
10151       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10152       vat_json_init_array (&vam->json_tree);
10153     }
10154   node = vat_json_array_add (&vam->json_tree);
10155
10156   vat_json_init_object (node);
10157
10158   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10159   vat_json_object_add_ip6 (node, "our_address", addr);
10160   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10161   vat_json_object_add_ip6 (node, "client_address", addr);
10162
10163   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10164   vat_json_init_array (lc);
10165   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10166   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10167   vat_json_object_add_uint (node, "remote_cookie",
10168                             clib_net_to_host_u64 (mp->remote_cookie));
10169
10170   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10171   vat_json_object_add_uint (node, "local_session_id",
10172                             clib_net_to_host_u32 (mp->local_session_id));
10173   vat_json_object_add_uint (node, "remote_session_id",
10174                             clib_net_to_host_u32 (mp->remote_session_id));
10175   vat_json_object_add_string_copy (node, "l2_sublayer",
10176                                    mp->l2_sublayer_present ? (u8 *) "present"
10177                                    : (u8 *) "absent");
10178 }
10179
10180 static int
10181 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10182 {
10183   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10184   f64 timeout;
10185
10186   /* Get list of l2tpv3-tunnel interfaces */
10187   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10188   S;
10189
10190   /* Use a control ping for synchronization */
10191   {
10192     vl_api_control_ping_t *mp;
10193     M (CONTROL_PING, control_ping);
10194     S;
10195   }
10196   W;
10197 }
10198
10199
10200 static void vl_api_sw_interface_tap_details_t_handler
10201   (vl_api_sw_interface_tap_details_t * mp)
10202 {
10203   vat_main_t *vam = &vat_main;
10204
10205   fformat (vam->ofp, "%-16s %d\n",
10206            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10207 }
10208
10209 static void vl_api_sw_interface_tap_details_t_handler_json
10210   (vl_api_sw_interface_tap_details_t * mp)
10211 {
10212   vat_main_t *vam = &vat_main;
10213   vat_json_node_t *node = NULL;
10214
10215   if (VAT_JSON_ARRAY != vam->json_tree.type)
10216     {
10217       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10218       vat_json_init_array (&vam->json_tree);
10219     }
10220   node = vat_json_array_add (&vam->json_tree);
10221
10222   vat_json_init_object (node);
10223   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10224   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10225 }
10226
10227 static int
10228 api_sw_interface_tap_dump (vat_main_t * vam)
10229 {
10230   vl_api_sw_interface_tap_dump_t *mp;
10231   f64 timeout;
10232
10233   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10234   /* Get list of tap interfaces */
10235   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10236   S;
10237
10238   /* Use a control ping for synchronization */
10239   {
10240     vl_api_control_ping_t *mp;
10241     M (CONTROL_PING, control_ping);
10242     S;
10243   }
10244   W;
10245 }
10246
10247 static uword unformat_vxlan_decap_next
10248   (unformat_input_t * input, va_list * args)
10249 {
10250   u32 *result = va_arg (*args, u32 *);
10251   u32 tmp;
10252
10253   if (unformat (input, "l2"))
10254     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10255   else if (unformat (input, "%d", &tmp))
10256     *result = tmp;
10257   else
10258     return 0;
10259   return 1;
10260 }
10261
10262 static int
10263 api_vxlan_add_del_tunnel (vat_main_t * vam)
10264 {
10265   unformat_input_t *line_input = vam->input;
10266   vl_api_vxlan_add_del_tunnel_t *mp;
10267   f64 timeout;
10268   ip46_address_t src, dst;
10269   u8 is_add = 1;
10270   u8 ipv4_set = 0, ipv6_set = 0;
10271   u8 src_set = 0;
10272   u8 dst_set = 0;
10273   u8 grp_set = 0;
10274   u32 mcast_sw_if_index = ~0;
10275   u32 encap_vrf_id = 0;
10276   u32 decap_next_index = ~0;
10277   u32 vni = 0;
10278
10279   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10280   memset (&src, 0, sizeof src);
10281   memset (&dst, 0, sizeof dst);
10282
10283   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10284     {
10285       if (unformat (line_input, "del"))
10286         is_add = 0;
10287       else
10288         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10289         {
10290           ipv4_set = 1;
10291           src_set = 1;
10292         }
10293       else
10294         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10295         {
10296           ipv4_set = 1;
10297           dst_set = 1;
10298         }
10299       else
10300         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10301         {
10302           ipv6_set = 1;
10303           src_set = 1;
10304         }
10305       else
10306         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10307         {
10308           ipv6_set = 1;
10309           dst_set = 1;
10310         }
10311       else if (unformat (line_input, "group %U %U",
10312                          unformat_ip4_address, &dst.ip4,
10313                          unformat_sw_if_index, vam, &mcast_sw_if_index))
10314         {
10315           grp_set = dst_set = 1;
10316           ipv4_set = 1;
10317         }
10318       else if (unformat (line_input, "group %U",
10319                          unformat_ip4_address, &dst.ip4))
10320         {
10321           grp_set = dst_set = 1;
10322           ipv4_set = 1;
10323         }
10324       else if (unformat (line_input, "group %U %U",
10325                          unformat_ip6_address, &dst.ip6,
10326                          unformat_sw_if_index, vam, &mcast_sw_if_index))
10327         {
10328           grp_set = dst_set = 1;
10329           ipv6_set = 1;
10330         }
10331       else if (unformat (line_input, "group %U",
10332                          unformat_ip6_address, &dst.ip6))
10333         {
10334           grp_set = dst_set = 1;
10335           ipv6_set = 1;
10336         }
10337       else
10338         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10339         ;
10340       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10341         ;
10342       else if (unformat (line_input, "decap-next %U",
10343                          unformat_vxlan_decap_next, &decap_next_index))
10344         ;
10345       else if (unformat (line_input, "vni %d", &vni))
10346         ;
10347       else
10348         {
10349           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10350           return -99;
10351         }
10352     }
10353
10354   if (src_set == 0)
10355     {
10356       errmsg ("tunnel src address not specified\n");
10357       return -99;
10358     }
10359   if (dst_set == 0)
10360     {
10361       errmsg ("tunnel dst address not specified\n");
10362       return -99;
10363     }
10364
10365   if (grp_set && !ip46_address_is_multicast (&dst))
10366     {
10367       errmsg ("tunnel group address not multicast\n");
10368       return -99;
10369     }
10370   if (grp_set && mcast_sw_if_index == ~0)
10371     {
10372       errmsg ("tunnel nonexistent multicast device\n");
10373       return -99;
10374     }
10375   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10376     {
10377       errmsg ("tunnel dst address must be unicast\n");
10378       return -99;
10379     }
10380
10381
10382   if (ipv4_set && ipv6_set)
10383     {
10384       errmsg ("both IPv4 and IPv6 addresses specified");
10385       return -99;
10386     }
10387
10388   if ((vni == 0) || (vni >> 24))
10389     {
10390       errmsg ("vni not specified or out of range\n");
10391       return -99;
10392     }
10393
10394   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10395
10396   if (ipv6_set)
10397     {
10398       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10399       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10400     }
10401   else
10402     {
10403       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10404       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10405     }
10406   mp->encap_vrf_id = ntohl (encap_vrf_id);
10407   mp->decap_next_index = ntohl (decap_next_index);
10408   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10409   mp->vni = ntohl (vni);
10410   mp->is_add = is_add;
10411   mp->is_ipv6 = ipv6_set;
10412
10413   S;
10414   W;
10415   /* NOTREACHED */
10416   return 0;
10417 }
10418
10419 static void vl_api_vxlan_tunnel_details_t_handler
10420   (vl_api_vxlan_tunnel_details_t * mp)
10421 {
10422   vat_main_t *vam = &vat_main;
10423   ip46_address_t src, dst;
10424
10425   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10426   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10427
10428   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d\n",
10429            ntohl (mp->sw_if_index),
10430            format_ip46_address, &src, IP46_TYPE_ANY,
10431            format_ip46_address, &dst, IP46_TYPE_ANY,
10432            ntohl (mp->encap_vrf_id),
10433            ntohl (mp->decap_next_index), ntohl (mp->vni),
10434            ntohl (mp->mcast_sw_if_index));
10435 }
10436
10437 static void vl_api_vxlan_tunnel_details_t_handler_json
10438   (vl_api_vxlan_tunnel_details_t * mp)
10439 {
10440   vat_main_t *vam = &vat_main;
10441   vat_json_node_t *node = NULL;
10442
10443   if (VAT_JSON_ARRAY != vam->json_tree.type)
10444     {
10445       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10446       vat_json_init_array (&vam->json_tree);
10447     }
10448   node = vat_json_array_add (&vam->json_tree);
10449
10450   vat_json_init_object (node);
10451   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10452   if (mp->is_ipv6)
10453     {
10454       struct in6_addr ip6;
10455
10456       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10457       vat_json_object_add_ip6 (node, "src_address", ip6);
10458       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10459       vat_json_object_add_ip6 (node, "dst_address", ip6);
10460     }
10461   else
10462     {
10463       struct in_addr ip4;
10464
10465       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10466       vat_json_object_add_ip4 (node, "src_address", ip4);
10467       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10468       vat_json_object_add_ip4 (node, "dst_address", ip4);
10469     }
10470   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10471   vat_json_object_add_uint (node, "decap_next_index",
10472                             ntohl (mp->decap_next_index));
10473   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10474   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10475   vat_json_object_add_uint (node, "mcast_sw_if_index",
10476                             ntohl (mp->mcast_sw_if_index));
10477 }
10478
10479 static int
10480 api_vxlan_tunnel_dump (vat_main_t * vam)
10481 {
10482   unformat_input_t *i = vam->input;
10483   vl_api_vxlan_tunnel_dump_t *mp;
10484   f64 timeout;
10485   u32 sw_if_index;
10486   u8 sw_if_index_set = 0;
10487
10488   /* Parse args required to build the message */
10489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10490     {
10491       if (unformat (i, "sw_if_index %d", &sw_if_index))
10492         sw_if_index_set = 1;
10493       else
10494         break;
10495     }
10496
10497   if (sw_if_index_set == 0)
10498     {
10499       sw_if_index = ~0;
10500     }
10501
10502   if (!vam->json_output)
10503     {
10504       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s\n",
10505                "sw_if_index", "src_address", "dst_address",
10506                "encap_vrf_id", "decap_next_index", "vni",
10507                "mcast_sw_if_index");
10508     }
10509
10510   /* Get list of vxlan-tunnel interfaces */
10511   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10512
10513   mp->sw_if_index = htonl (sw_if_index);
10514
10515   S;
10516
10517   /* Use a control ping for synchronization */
10518   {
10519     vl_api_control_ping_t *mp;
10520     M (CONTROL_PING, control_ping);
10521     S;
10522   }
10523   W;
10524 }
10525
10526 static int
10527 api_gre_add_del_tunnel (vat_main_t * vam)
10528 {
10529   unformat_input_t *line_input = vam->input;
10530   vl_api_gre_add_del_tunnel_t *mp;
10531   f64 timeout;
10532   ip4_address_t src4, dst4;
10533   u8 is_add = 1;
10534   u8 teb = 0;
10535   u8 src_set = 0;
10536   u8 dst_set = 0;
10537   u32 outer_fib_id = 0;
10538
10539   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10540     {
10541       if (unformat (line_input, "del"))
10542         is_add = 0;
10543       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10544         src_set = 1;
10545       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10546         dst_set = 1;
10547       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10548         ;
10549       else if (unformat (line_input, "teb"))
10550         teb = 1;
10551       else
10552         {
10553           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10554           return -99;
10555         }
10556     }
10557
10558   if (src_set == 0)
10559     {
10560       errmsg ("tunnel src address not specified\n");
10561       return -99;
10562     }
10563   if (dst_set == 0)
10564     {
10565       errmsg ("tunnel dst address not specified\n");
10566       return -99;
10567     }
10568
10569
10570   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10571
10572   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10573   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10574   mp->outer_fib_id = ntohl (outer_fib_id);
10575   mp->is_add = is_add;
10576   mp->teb = teb;
10577
10578   S;
10579   W;
10580   /* NOTREACHED */
10581   return 0;
10582 }
10583
10584 static void vl_api_gre_tunnel_details_t_handler
10585   (vl_api_gre_tunnel_details_t * mp)
10586 {
10587   vat_main_t *vam = &vat_main;
10588
10589   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10590            ntohl (mp->sw_if_index),
10591            format_ip4_address, &mp->src_address,
10592            format_ip4_address, &mp->dst_address,
10593            mp->teb, ntohl (mp->outer_fib_id));
10594 }
10595
10596 static void vl_api_gre_tunnel_details_t_handler_json
10597   (vl_api_gre_tunnel_details_t * mp)
10598 {
10599   vat_main_t *vam = &vat_main;
10600   vat_json_node_t *node = NULL;
10601   struct in_addr ip4;
10602
10603   if (VAT_JSON_ARRAY != vam->json_tree.type)
10604     {
10605       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10606       vat_json_init_array (&vam->json_tree);
10607     }
10608   node = vat_json_array_add (&vam->json_tree);
10609
10610   vat_json_init_object (node);
10611   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10612   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10613   vat_json_object_add_ip4 (node, "src_address", ip4);
10614   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10615   vat_json_object_add_ip4 (node, "dst_address", ip4);
10616   vat_json_object_add_uint (node, "teb", mp->teb);
10617   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10618 }
10619
10620 static int
10621 api_gre_tunnel_dump (vat_main_t * vam)
10622 {
10623   unformat_input_t *i = vam->input;
10624   vl_api_gre_tunnel_dump_t *mp;
10625   f64 timeout;
10626   u32 sw_if_index;
10627   u8 sw_if_index_set = 0;
10628
10629   /* Parse args required to build the message */
10630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10631     {
10632       if (unformat (i, "sw_if_index %d", &sw_if_index))
10633         sw_if_index_set = 1;
10634       else
10635         break;
10636     }
10637
10638   if (sw_if_index_set == 0)
10639     {
10640       sw_if_index = ~0;
10641     }
10642
10643   if (!vam->json_output)
10644     {
10645       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10646                "sw_if_index", "src_address", "dst_address", "teb",
10647                "outer_fib_id");
10648     }
10649
10650   /* Get list of gre-tunnel interfaces */
10651   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10652
10653   mp->sw_if_index = htonl (sw_if_index);
10654
10655   S;
10656
10657   /* Use a control ping for synchronization */
10658   {
10659     vl_api_control_ping_t *mp;
10660     M (CONTROL_PING, control_ping);
10661     S;
10662   }
10663   W;
10664 }
10665
10666 static int
10667 api_l2_fib_clear_table (vat_main_t * vam)
10668 {
10669 //  unformat_input_t * i = vam->input;
10670   vl_api_l2_fib_clear_table_t *mp;
10671   f64 timeout;
10672
10673   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10674
10675   S;
10676   W;
10677   /* NOTREACHED */
10678   return 0;
10679 }
10680
10681 static int
10682 api_l2_interface_efp_filter (vat_main_t * vam)
10683 {
10684   unformat_input_t *i = vam->input;
10685   vl_api_l2_interface_efp_filter_t *mp;
10686   f64 timeout;
10687   u32 sw_if_index;
10688   u8 enable = 1;
10689   u8 sw_if_index_set = 0;
10690
10691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10692     {
10693       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10694         sw_if_index_set = 1;
10695       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10696         sw_if_index_set = 1;
10697       else if (unformat (i, "enable"))
10698         enable = 1;
10699       else if (unformat (i, "disable"))
10700         enable = 0;
10701       else
10702         {
10703           clib_warning ("parse error '%U'", format_unformat_error, i);
10704           return -99;
10705         }
10706     }
10707
10708   if (sw_if_index_set == 0)
10709     {
10710       errmsg ("missing sw_if_index\n");
10711       return -99;
10712     }
10713
10714   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10715
10716   mp->sw_if_index = ntohl (sw_if_index);
10717   mp->enable_disable = enable;
10718
10719   S;
10720   W;
10721   /* NOTREACHED */
10722   return 0;
10723 }
10724
10725 #define foreach_vtr_op                          \
10726 _("disable",  L2_VTR_DISABLED)                  \
10727 _("push-1",  L2_VTR_PUSH_1)                     \
10728 _("push-2",  L2_VTR_PUSH_2)                     \
10729 _("pop-1",  L2_VTR_POP_1)                       \
10730 _("pop-2",  L2_VTR_POP_2)                       \
10731 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10732 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10733 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10734 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10735
10736 static int
10737 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10738 {
10739   unformat_input_t *i = vam->input;
10740   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10741   f64 timeout;
10742   u32 sw_if_index;
10743   u8 sw_if_index_set = 0;
10744   u8 vtr_op_set = 0;
10745   u32 vtr_op = 0;
10746   u32 push_dot1q = 1;
10747   u32 tag1 = ~0;
10748   u32 tag2 = ~0;
10749
10750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10751     {
10752       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10753         sw_if_index_set = 1;
10754       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10755         sw_if_index_set = 1;
10756       else if (unformat (i, "vtr_op %d", &vtr_op))
10757         vtr_op_set = 1;
10758 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10759       foreach_vtr_op
10760 #undef _
10761         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10762         ;
10763       else if (unformat (i, "tag1 %d", &tag1))
10764         ;
10765       else if (unformat (i, "tag2 %d", &tag2))
10766         ;
10767       else
10768         {
10769           clib_warning ("parse error '%U'", format_unformat_error, i);
10770           return -99;
10771         }
10772     }
10773
10774   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10775     {
10776       errmsg ("missing vtr operation or sw_if_index\n");
10777       return -99;
10778     }
10779
10780   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10781     mp->sw_if_index = ntohl (sw_if_index);
10782   mp->vtr_op = ntohl (vtr_op);
10783   mp->push_dot1q = ntohl (push_dot1q);
10784   mp->tag1 = ntohl (tag1);
10785   mp->tag2 = ntohl (tag2);
10786
10787   S;
10788   W;
10789   /* NOTREACHED */
10790   return 0;
10791 }
10792
10793 static int
10794 api_create_vhost_user_if (vat_main_t * vam)
10795 {
10796   unformat_input_t *i = vam->input;
10797   vl_api_create_vhost_user_if_t *mp;
10798   f64 timeout;
10799   u8 *file_name;
10800   u8 is_server = 0;
10801   u8 file_name_set = 0;
10802   u32 custom_dev_instance = ~0;
10803   u8 hwaddr[6];
10804   u8 use_custom_mac = 0;
10805   u8 *tag = 0;
10806
10807   /* Shut up coverity */
10808   memset (hwaddr, 0, sizeof (hwaddr));
10809
10810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10811     {
10812       if (unformat (i, "socket %s", &file_name))
10813         {
10814           file_name_set = 1;
10815         }
10816       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10817         ;
10818       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10819         use_custom_mac = 1;
10820       else if (unformat (i, "server"))
10821         is_server = 1;
10822       else if (unformat (i, "tag %s", &tag))
10823         ;
10824       else
10825         break;
10826     }
10827
10828   if (file_name_set == 0)
10829     {
10830       errmsg ("missing socket file name\n");
10831       return -99;
10832     }
10833
10834   if (vec_len (file_name) > 255)
10835     {
10836       errmsg ("socket file name too long\n");
10837       return -99;
10838     }
10839   vec_add1 (file_name, 0);
10840
10841   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10842
10843   mp->is_server = is_server;
10844   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10845   vec_free (file_name);
10846   if (custom_dev_instance != ~0)
10847     {
10848       mp->renumber = 1;
10849       mp->custom_dev_instance = ntohl (custom_dev_instance);
10850     }
10851   mp->use_custom_mac = use_custom_mac;
10852   clib_memcpy (mp->mac_address, hwaddr, 6);
10853   if (tag)
10854     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10855   vec_free (tag);
10856
10857   S;
10858   W;
10859   /* NOTREACHED */
10860   return 0;
10861 }
10862
10863 static int
10864 api_modify_vhost_user_if (vat_main_t * vam)
10865 {
10866   unformat_input_t *i = vam->input;
10867   vl_api_modify_vhost_user_if_t *mp;
10868   f64 timeout;
10869   u8 *file_name;
10870   u8 is_server = 0;
10871   u8 file_name_set = 0;
10872   u32 custom_dev_instance = ~0;
10873   u8 sw_if_index_set = 0;
10874   u32 sw_if_index = (u32) ~ 0;
10875
10876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10877     {
10878       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10879         sw_if_index_set = 1;
10880       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10881         sw_if_index_set = 1;
10882       else if (unformat (i, "socket %s", &file_name))
10883         {
10884           file_name_set = 1;
10885         }
10886       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10887         ;
10888       else if (unformat (i, "server"))
10889         is_server = 1;
10890       else
10891         break;
10892     }
10893
10894   if (sw_if_index_set == 0)
10895     {
10896       errmsg ("missing sw_if_index or interface name\n");
10897       return -99;
10898     }
10899
10900   if (file_name_set == 0)
10901     {
10902       errmsg ("missing socket file name\n");
10903       return -99;
10904     }
10905
10906   if (vec_len (file_name) > 255)
10907     {
10908       errmsg ("socket file name too long\n");
10909       return -99;
10910     }
10911   vec_add1 (file_name, 0);
10912
10913   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10914
10915   mp->sw_if_index = ntohl (sw_if_index);
10916   mp->is_server = is_server;
10917   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10918   vec_free (file_name);
10919   if (custom_dev_instance != ~0)
10920     {
10921       mp->renumber = 1;
10922       mp->custom_dev_instance = ntohl (custom_dev_instance);
10923     }
10924
10925   S;
10926   W;
10927   /* NOTREACHED */
10928   return 0;
10929 }
10930
10931 static int
10932 api_delete_vhost_user_if (vat_main_t * vam)
10933 {
10934   unformat_input_t *i = vam->input;
10935   vl_api_delete_vhost_user_if_t *mp;
10936   f64 timeout;
10937   u32 sw_if_index = ~0;
10938   u8 sw_if_index_set = 0;
10939
10940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10941     {
10942       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10943         sw_if_index_set = 1;
10944       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10945         sw_if_index_set = 1;
10946       else
10947         break;
10948     }
10949
10950   if (sw_if_index_set == 0)
10951     {
10952       errmsg ("missing sw_if_index or interface name\n");
10953       return -99;
10954     }
10955
10956
10957   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10958
10959   mp->sw_if_index = ntohl (sw_if_index);
10960
10961   S;
10962   W;
10963   /* NOTREACHED */
10964   return 0;
10965 }
10966
10967 static void vl_api_sw_interface_vhost_user_details_t_handler
10968   (vl_api_sw_interface_vhost_user_details_t * mp)
10969 {
10970   vat_main_t *vam = &vat_main;
10971
10972   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10973            (char *) mp->interface_name,
10974            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10975            clib_net_to_host_u64 (mp->features), mp->is_server,
10976            ntohl (mp->num_regions), (char *) mp->sock_filename);
10977   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10978 }
10979
10980 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10981   (vl_api_sw_interface_vhost_user_details_t * mp)
10982 {
10983   vat_main_t *vam = &vat_main;
10984   vat_json_node_t *node = NULL;
10985
10986   if (VAT_JSON_ARRAY != vam->json_tree.type)
10987     {
10988       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10989       vat_json_init_array (&vam->json_tree);
10990     }
10991   node = vat_json_array_add (&vam->json_tree);
10992
10993   vat_json_init_object (node);
10994   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10995   vat_json_object_add_string_copy (node, "interface_name",
10996                                    mp->interface_name);
10997   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10998                             ntohl (mp->virtio_net_hdr_sz));
10999   vat_json_object_add_uint (node, "features",
11000                             clib_net_to_host_u64 (mp->features));
11001   vat_json_object_add_uint (node, "is_server", mp->is_server);
11002   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11003   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11004   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11005 }
11006
11007 static int
11008 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11009 {
11010   vl_api_sw_interface_vhost_user_dump_t *mp;
11011   f64 timeout;
11012   fformat (vam->ofp,
11013            "Interface name           idx hdr_sz features server regions filename\n");
11014
11015   /* Get list of vhost-user interfaces */
11016   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
11017   S;
11018
11019   /* Use a control ping for synchronization */
11020   {
11021     vl_api_control_ping_t *mp;
11022     M (CONTROL_PING, control_ping);
11023     S;
11024   }
11025   W;
11026 }
11027
11028 static int
11029 api_show_version (vat_main_t * vam)
11030 {
11031   vl_api_show_version_t *mp;
11032   f64 timeout;
11033
11034   M (SHOW_VERSION, show_version);
11035
11036   S;
11037   W;
11038   /* NOTREACHED */
11039   return 0;
11040 }
11041
11042
11043 static int
11044 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11045 {
11046   unformat_input_t *line_input = vam->input;
11047   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11048   f64 timeout;
11049   ip4_address_t local4, remote4;
11050   ip6_address_t local6, remote6;
11051   u8 is_add = 1;
11052   u8 ipv4_set = 0, ipv6_set = 0;
11053   u8 local_set = 0;
11054   u8 remote_set = 0;
11055   u32 encap_vrf_id = 0;
11056   u32 decap_vrf_id = 0;
11057   u8 protocol = ~0;
11058   u32 vni;
11059   u8 vni_set = 0;
11060
11061   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11062     {
11063       if (unformat (line_input, "del"))
11064         is_add = 0;
11065       else if (unformat (line_input, "local %U",
11066                          unformat_ip4_address, &local4))
11067         {
11068           local_set = 1;
11069           ipv4_set = 1;
11070         }
11071       else if (unformat (line_input, "remote %U",
11072                          unformat_ip4_address, &remote4))
11073         {
11074           remote_set = 1;
11075           ipv4_set = 1;
11076         }
11077       else if (unformat (line_input, "local %U",
11078                          unformat_ip6_address, &local6))
11079         {
11080           local_set = 1;
11081           ipv6_set = 1;
11082         }
11083       else if (unformat (line_input, "remote %U",
11084                          unformat_ip6_address, &remote6))
11085         {
11086           remote_set = 1;
11087           ipv6_set = 1;
11088         }
11089       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11090         ;
11091       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11092         ;
11093       else if (unformat (line_input, "vni %d", &vni))
11094         vni_set = 1;
11095       else if (unformat (line_input, "next-ip4"))
11096         protocol = 1;
11097       else if (unformat (line_input, "next-ip6"))
11098         protocol = 2;
11099       else if (unformat (line_input, "next-ethernet"))
11100         protocol = 3;
11101       else if (unformat (line_input, "next-nsh"))
11102         protocol = 4;
11103       else
11104         {
11105           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
11106           return -99;
11107         }
11108     }
11109
11110   if (local_set == 0)
11111     {
11112       errmsg ("tunnel local address not specified\n");
11113       return -99;
11114     }
11115   if (remote_set == 0)
11116     {
11117       errmsg ("tunnel remote address not specified\n");
11118       return -99;
11119     }
11120   if (ipv4_set && ipv6_set)
11121     {
11122       errmsg ("both IPv4 and IPv6 addresses specified");
11123       return -99;
11124     }
11125
11126   if (vni_set == 0)
11127     {
11128       errmsg ("vni not specified\n");
11129       return -99;
11130     }
11131
11132   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
11133
11134
11135   if (ipv6_set)
11136     {
11137       clib_memcpy (&mp->local, &local6, sizeof (local6));
11138       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11139     }
11140   else
11141     {
11142       clib_memcpy (&mp->local, &local4, sizeof (local4));
11143       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11144     }
11145
11146   mp->encap_vrf_id = ntohl (encap_vrf_id);
11147   mp->decap_vrf_id = ntohl (decap_vrf_id);
11148   mp->protocol = protocol;
11149   mp->vni = ntohl (vni);
11150   mp->is_add = is_add;
11151   mp->is_ipv6 = ipv6_set;
11152
11153   S;
11154   W;
11155   /* NOTREACHED */
11156   return 0;
11157 }
11158
11159 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11160   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11161 {
11162   vat_main_t *vam = &vat_main;
11163
11164   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
11165            ntohl (mp->sw_if_index),
11166            format_ip46_address, &(mp->local[0]),
11167            format_ip46_address, &(mp->remote[0]),
11168            ntohl (mp->vni),
11169            ntohl (mp->protocol),
11170            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11171 }
11172
11173 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11174   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11175 {
11176   vat_main_t *vam = &vat_main;
11177   vat_json_node_t *node = NULL;
11178   struct in_addr ip4;
11179   struct in6_addr ip6;
11180
11181   if (VAT_JSON_ARRAY != vam->json_tree.type)
11182     {
11183       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11184       vat_json_init_array (&vam->json_tree);
11185     }
11186   node = vat_json_array_add (&vam->json_tree);
11187
11188   vat_json_init_object (node);
11189   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11190   if (mp->is_ipv6)
11191     {
11192       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11193       vat_json_object_add_ip6 (node, "local", ip6);
11194       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11195       vat_json_object_add_ip6 (node, "remote", ip6);
11196     }
11197   else
11198     {
11199       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11200       vat_json_object_add_ip4 (node, "local", ip4);
11201       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11202       vat_json_object_add_ip4 (node, "remote", ip4);
11203     }
11204   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11205   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11206   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11207   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11208   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11209 }
11210
11211 static int
11212 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11213 {
11214   unformat_input_t *i = vam->input;
11215   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11216   f64 timeout;
11217   u32 sw_if_index;
11218   u8 sw_if_index_set = 0;
11219
11220   /* Parse args required to build the message */
11221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11222     {
11223       if (unformat (i, "sw_if_index %d", &sw_if_index))
11224         sw_if_index_set = 1;
11225       else
11226         break;
11227     }
11228
11229   if (sw_if_index_set == 0)
11230     {
11231       sw_if_index = ~0;
11232     }
11233
11234   if (!vam->json_output)
11235     {
11236       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
11237                "sw_if_index", "local", "remote", "vni",
11238                "protocol", "encap_vrf_id", "decap_vrf_id");
11239     }
11240
11241   /* Get list of vxlan-tunnel interfaces */
11242   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11243
11244   mp->sw_if_index = htonl (sw_if_index);
11245
11246   S;
11247
11248   /* Use a control ping for synchronization */
11249   {
11250     vl_api_control_ping_t *mp;
11251     M (CONTROL_PING, control_ping);
11252     S;
11253   }
11254   W;
11255 }
11256
11257 u8 *
11258 format_l2_fib_mac_address (u8 * s, va_list * args)
11259 {
11260   u8 *a = va_arg (*args, u8 *);
11261
11262   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11263                  a[2], a[3], a[4], a[5], a[6], a[7]);
11264 }
11265
11266 static void vl_api_l2_fib_table_entry_t_handler
11267   (vl_api_l2_fib_table_entry_t * mp)
11268 {
11269   vat_main_t *vam = &vat_main;
11270
11271   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11272            "       %d       %d     %d\n",
11273            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11274            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11275            mp->bvi_mac);
11276 }
11277
11278 static void vl_api_l2_fib_table_entry_t_handler_json
11279   (vl_api_l2_fib_table_entry_t * mp)
11280 {
11281   vat_main_t *vam = &vat_main;
11282   vat_json_node_t *node = NULL;
11283
11284   if (VAT_JSON_ARRAY != vam->json_tree.type)
11285     {
11286       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11287       vat_json_init_array (&vam->json_tree);
11288     }
11289   node = vat_json_array_add (&vam->json_tree);
11290
11291   vat_json_init_object (node);
11292   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11293   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11294   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11295   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11296   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11297   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11298 }
11299
11300 static int
11301 api_l2_fib_table_dump (vat_main_t * vam)
11302 {
11303   unformat_input_t *i = vam->input;
11304   vl_api_l2_fib_table_dump_t *mp;
11305   f64 timeout;
11306   u32 bd_id;
11307   u8 bd_id_set = 0;
11308
11309   /* Parse args required to build the message */
11310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11311     {
11312       if (unformat (i, "bd_id %d", &bd_id))
11313         bd_id_set = 1;
11314       else
11315         break;
11316     }
11317
11318   if (bd_id_set == 0)
11319     {
11320       errmsg ("missing bridge domain\n");
11321       return -99;
11322     }
11323
11324   fformat (vam->ofp,
11325            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11326
11327   /* Get list of l2 fib entries */
11328   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11329
11330   mp->bd_id = ntohl (bd_id);
11331   S;
11332
11333   /* Use a control ping for synchronization */
11334   {
11335     vl_api_control_ping_t *mp;
11336     M (CONTROL_PING, control_ping);
11337     S;
11338   }
11339   W;
11340 }
11341
11342
11343 static int
11344 api_interface_name_renumber (vat_main_t * vam)
11345 {
11346   unformat_input_t *line_input = vam->input;
11347   vl_api_interface_name_renumber_t *mp;
11348   u32 sw_if_index = ~0;
11349   f64 timeout;
11350   u32 new_show_dev_instance = ~0;
11351
11352   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11353     {
11354       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11355                     &sw_if_index))
11356         ;
11357       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11358         ;
11359       else if (unformat (line_input, "new_show_dev_instance %d",
11360                          &new_show_dev_instance))
11361         ;
11362       else
11363         break;
11364     }
11365
11366   if (sw_if_index == ~0)
11367     {
11368       errmsg ("missing interface name or sw_if_index\n");
11369       return -99;
11370     }
11371
11372   if (new_show_dev_instance == ~0)
11373     {
11374       errmsg ("missing new_show_dev_instance\n");
11375       return -99;
11376     }
11377
11378   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11379
11380   mp->sw_if_index = ntohl (sw_if_index);
11381   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11382
11383   S;
11384   W;
11385 }
11386
11387 static int
11388 api_want_ip4_arp_events (vat_main_t * vam)
11389 {
11390   unformat_input_t *line_input = vam->input;
11391   vl_api_want_ip4_arp_events_t *mp;
11392   f64 timeout;
11393   ip4_address_t address;
11394   int address_set = 0;
11395   u32 enable_disable = 1;
11396
11397   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11398     {
11399       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11400         address_set = 1;
11401       else if (unformat (line_input, "del"))
11402         enable_disable = 0;
11403       else
11404         break;
11405     }
11406
11407   if (address_set == 0)
11408     {
11409       errmsg ("missing addresses\n");
11410       return -99;
11411     }
11412
11413   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11414   mp->enable_disable = enable_disable;
11415   mp->pid = getpid ();
11416   mp->address = address.as_u32;
11417
11418   S;
11419   W;
11420 }
11421
11422 static int
11423 api_want_ip6_nd_events (vat_main_t * vam)
11424 {
11425   unformat_input_t *line_input = vam->input;
11426   vl_api_want_ip6_nd_events_t *mp;
11427   f64 timeout;
11428   ip6_address_t address;
11429   int address_set = 0;
11430   u32 enable_disable = 1;
11431
11432   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11433     {
11434       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11435         address_set = 1;
11436       else if (unformat (line_input, "del"))
11437         enable_disable = 0;
11438       else
11439         break;
11440     }
11441
11442   if (address_set == 0)
11443     {
11444       errmsg ("missing addresses\n");
11445       return -99;
11446     }
11447
11448   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11449   mp->enable_disable = enable_disable;
11450   mp->pid = getpid ();
11451   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11452
11453   S;
11454   W;
11455 }
11456
11457 static int
11458 api_input_acl_set_interface (vat_main_t * vam)
11459 {
11460   unformat_input_t *i = vam->input;
11461   vl_api_input_acl_set_interface_t *mp;
11462   f64 timeout;
11463   u32 sw_if_index;
11464   int sw_if_index_set;
11465   u32 ip4_table_index = ~0;
11466   u32 ip6_table_index = ~0;
11467   u32 l2_table_index = ~0;
11468   u8 is_add = 1;
11469
11470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11471     {
11472       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11473         sw_if_index_set = 1;
11474       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11475         sw_if_index_set = 1;
11476       else if (unformat (i, "del"))
11477         is_add = 0;
11478       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11479         ;
11480       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11481         ;
11482       else if (unformat (i, "l2-table %d", &l2_table_index))
11483         ;
11484       else
11485         {
11486           clib_warning ("parse error '%U'", format_unformat_error, i);
11487           return -99;
11488         }
11489     }
11490
11491   if (sw_if_index_set == 0)
11492     {
11493       errmsg ("missing interface name or sw_if_index\n");
11494       return -99;
11495     }
11496
11497   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11498
11499   mp->sw_if_index = ntohl (sw_if_index);
11500   mp->ip4_table_index = ntohl (ip4_table_index);
11501   mp->ip6_table_index = ntohl (ip6_table_index);
11502   mp->l2_table_index = ntohl (l2_table_index);
11503   mp->is_add = is_add;
11504
11505   S;
11506   W;
11507   /* NOTREACHED */
11508   return 0;
11509 }
11510
11511 static int
11512 api_ip_address_dump (vat_main_t * vam)
11513 {
11514   unformat_input_t *i = vam->input;
11515   vl_api_ip_address_dump_t *mp;
11516   u32 sw_if_index = ~0;
11517   u8 sw_if_index_set = 0;
11518   u8 ipv4_set = 0;
11519   u8 ipv6_set = 0;
11520   f64 timeout;
11521
11522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11523     {
11524       if (unformat (i, "sw_if_index %d", &sw_if_index))
11525         sw_if_index_set = 1;
11526       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11527         sw_if_index_set = 1;
11528       else if (unformat (i, "ipv4"))
11529         ipv4_set = 1;
11530       else if (unformat (i, "ipv6"))
11531         ipv6_set = 1;
11532       else
11533         break;
11534     }
11535
11536   if (ipv4_set && ipv6_set)
11537     {
11538       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11539       return -99;
11540     }
11541
11542   if ((!ipv4_set) && (!ipv6_set))
11543     {
11544       errmsg ("no ipv4 nor ipv6 flag set\n");
11545       return -99;
11546     }
11547
11548   if (sw_if_index_set == 0)
11549     {
11550       errmsg ("missing interface name or sw_if_index\n");
11551       return -99;
11552     }
11553
11554   vam->current_sw_if_index = sw_if_index;
11555   vam->is_ipv6 = ipv6_set;
11556
11557   M (IP_ADDRESS_DUMP, ip_address_dump);
11558   mp->sw_if_index = ntohl (sw_if_index);
11559   mp->is_ipv6 = ipv6_set;
11560   S;
11561
11562   /* Use a control ping for synchronization */
11563   {
11564     vl_api_control_ping_t *mp;
11565     M (CONTROL_PING, control_ping);
11566     S;
11567   }
11568   W;
11569 }
11570
11571 static int
11572 api_ip_dump (vat_main_t * vam)
11573 {
11574   vl_api_ip_dump_t *mp;
11575   unformat_input_t *in = vam->input;
11576   int ipv4_set = 0;
11577   int ipv6_set = 0;
11578   int is_ipv6;
11579   f64 timeout;
11580   int i;
11581
11582   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11583     {
11584       if (unformat (in, "ipv4"))
11585         ipv4_set = 1;
11586       else if (unformat (in, "ipv6"))
11587         ipv6_set = 1;
11588       else
11589         break;
11590     }
11591
11592   if (ipv4_set && ipv6_set)
11593     {
11594       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11595       return -99;
11596     }
11597
11598   if ((!ipv4_set) && (!ipv6_set))
11599     {
11600       errmsg ("no ipv4 nor ipv6 flag set\n");
11601       return -99;
11602     }
11603
11604   is_ipv6 = ipv6_set;
11605   vam->is_ipv6 = is_ipv6;
11606
11607   /* free old data */
11608   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11609     {
11610       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11611     }
11612   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11613
11614   M (IP_DUMP, ip_dump);
11615   mp->is_ipv6 = ipv6_set;
11616   S;
11617
11618   /* Use a control ping for synchronization */
11619   {
11620     vl_api_control_ping_t *mp;
11621     M (CONTROL_PING, control_ping);
11622     S;
11623   }
11624   W;
11625 }
11626
11627 static int
11628 api_ipsec_spd_add_del (vat_main_t * vam)
11629 {
11630   unformat_input_t *i = vam->input;
11631   vl_api_ipsec_spd_add_del_t *mp;
11632   f64 timeout;
11633   u32 spd_id = ~0;
11634   u8 is_add = 1;
11635
11636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11637     {
11638       if (unformat (i, "spd_id %d", &spd_id))
11639         ;
11640       else if (unformat (i, "del"))
11641         is_add = 0;
11642       else
11643         {
11644           clib_warning ("parse error '%U'", format_unformat_error, i);
11645           return -99;
11646         }
11647     }
11648   if (spd_id == ~0)
11649     {
11650       errmsg ("spd_id must be set\n");
11651       return -99;
11652     }
11653
11654   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11655
11656   mp->spd_id = ntohl (spd_id);
11657   mp->is_add = is_add;
11658
11659   S;
11660   W;
11661   /* NOTREACHED */
11662   return 0;
11663 }
11664
11665 static int
11666 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11667 {
11668   unformat_input_t *i = vam->input;
11669   vl_api_ipsec_interface_add_del_spd_t *mp;
11670   f64 timeout;
11671   u32 sw_if_index;
11672   u8 sw_if_index_set = 0;
11673   u32 spd_id = (u32) ~ 0;
11674   u8 is_add = 1;
11675
11676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11677     {
11678       if (unformat (i, "del"))
11679         is_add = 0;
11680       else if (unformat (i, "spd_id %d", &spd_id))
11681         ;
11682       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11683         sw_if_index_set = 1;
11684       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11685         sw_if_index_set = 1;
11686       else
11687         {
11688           clib_warning ("parse error '%U'", format_unformat_error, i);
11689           return -99;
11690         }
11691
11692     }
11693
11694   if (spd_id == (u32) ~ 0)
11695     {
11696       errmsg ("spd_id must be set\n");
11697       return -99;
11698     }
11699
11700   if (sw_if_index_set == 0)
11701     {
11702       errmsg ("missing interface name or sw_if_index\n");
11703       return -99;
11704     }
11705
11706   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11707
11708   mp->spd_id = ntohl (spd_id);
11709   mp->sw_if_index = ntohl (sw_if_index);
11710   mp->is_add = is_add;
11711
11712   S;
11713   W;
11714   /* NOTREACHED */
11715   return 0;
11716 }
11717
11718 static int
11719 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11720 {
11721   unformat_input_t *i = vam->input;
11722   vl_api_ipsec_spd_add_del_entry_t *mp;
11723   f64 timeout;
11724   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11725   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11726   i32 priority = 0;
11727   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11728   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11729   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11730   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11731
11732   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11733   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11734   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11735   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11736   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11737   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11738
11739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11740     {
11741       if (unformat (i, "del"))
11742         is_add = 0;
11743       if (unformat (i, "outbound"))
11744         is_outbound = 1;
11745       if (unformat (i, "inbound"))
11746         is_outbound = 0;
11747       else if (unformat (i, "spd_id %d", &spd_id))
11748         ;
11749       else if (unformat (i, "sa_id %d", &sa_id))
11750         ;
11751       else if (unformat (i, "priority %d", &priority))
11752         ;
11753       else if (unformat (i, "protocol %d", &protocol))
11754         ;
11755       else if (unformat (i, "lport_start %d", &lport_start))
11756         ;
11757       else if (unformat (i, "lport_stop %d", &lport_stop))
11758         ;
11759       else if (unformat (i, "rport_start %d", &rport_start))
11760         ;
11761       else if (unformat (i, "rport_stop %d", &rport_stop))
11762         ;
11763       else
11764         if (unformat
11765             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11766         {
11767           is_ipv6 = 0;
11768           is_ip_any = 0;
11769         }
11770       else
11771         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11772         {
11773           is_ipv6 = 0;
11774           is_ip_any = 0;
11775         }
11776       else
11777         if (unformat
11778             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11779         {
11780           is_ipv6 = 0;
11781           is_ip_any = 0;
11782         }
11783       else
11784         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11785         {
11786           is_ipv6 = 0;
11787           is_ip_any = 0;
11788         }
11789       else
11790         if (unformat
11791             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11792         {
11793           is_ipv6 = 1;
11794           is_ip_any = 0;
11795         }
11796       else
11797         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11798         {
11799           is_ipv6 = 1;
11800           is_ip_any = 0;
11801         }
11802       else
11803         if (unformat
11804             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11805         {
11806           is_ipv6 = 1;
11807           is_ip_any = 0;
11808         }
11809       else
11810         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11811         {
11812           is_ipv6 = 1;
11813           is_ip_any = 0;
11814         }
11815       else
11816         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11817         {
11818           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11819             {
11820               clib_warning ("unsupported action: 'resolve'");
11821               return -99;
11822             }
11823         }
11824       else
11825         {
11826           clib_warning ("parse error '%U'", format_unformat_error, i);
11827           return -99;
11828         }
11829
11830     }
11831
11832   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11833
11834   mp->spd_id = ntohl (spd_id);
11835   mp->priority = ntohl (priority);
11836   mp->is_outbound = is_outbound;
11837
11838   mp->is_ipv6 = is_ipv6;
11839   if (is_ipv6 || is_ip_any)
11840     {
11841       clib_memcpy (mp->remote_address_start, &raddr6_start,
11842                    sizeof (ip6_address_t));
11843       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11844                    sizeof (ip6_address_t));
11845       clib_memcpy (mp->local_address_start, &laddr6_start,
11846                    sizeof (ip6_address_t));
11847       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11848                    sizeof (ip6_address_t));
11849     }
11850   else
11851     {
11852       clib_memcpy (mp->remote_address_start, &raddr4_start,
11853                    sizeof (ip4_address_t));
11854       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11855                    sizeof (ip4_address_t));
11856       clib_memcpy (mp->local_address_start, &laddr4_start,
11857                    sizeof (ip4_address_t));
11858       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11859                    sizeof (ip4_address_t));
11860     }
11861   mp->protocol = (u8) protocol;
11862   mp->local_port_start = ntohs ((u16) lport_start);
11863   mp->local_port_stop = ntohs ((u16) lport_stop);
11864   mp->remote_port_start = ntohs ((u16) rport_start);
11865   mp->remote_port_stop = ntohs ((u16) rport_stop);
11866   mp->policy = (u8) policy;
11867   mp->sa_id = ntohl (sa_id);
11868   mp->is_add = is_add;
11869   mp->is_ip_any = is_ip_any;
11870   S;
11871   W;
11872   /* NOTREACHED */
11873   return 0;
11874 }
11875
11876 static int
11877 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11878 {
11879   unformat_input_t *i = vam->input;
11880   vl_api_ipsec_sad_add_del_entry_t *mp;
11881   f64 timeout;
11882   u32 sad_id = 0, spi = 0;
11883   u8 *ck = 0, *ik = 0;
11884   u8 is_add = 1;
11885
11886   u8 protocol = IPSEC_PROTOCOL_AH;
11887   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11888   u32 crypto_alg = 0, integ_alg = 0;
11889   ip4_address_t tun_src4;
11890   ip4_address_t tun_dst4;
11891   ip6_address_t tun_src6;
11892   ip6_address_t tun_dst6;
11893
11894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11895     {
11896       if (unformat (i, "del"))
11897         is_add = 0;
11898       else if (unformat (i, "sad_id %d", &sad_id))
11899         ;
11900       else if (unformat (i, "spi %d", &spi))
11901         ;
11902       else if (unformat (i, "esp"))
11903         protocol = IPSEC_PROTOCOL_ESP;
11904       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11905         {
11906           is_tunnel = 1;
11907           is_tunnel_ipv6 = 0;
11908         }
11909       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11910         {
11911           is_tunnel = 1;
11912           is_tunnel_ipv6 = 0;
11913         }
11914       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11915         {
11916           is_tunnel = 1;
11917           is_tunnel_ipv6 = 1;
11918         }
11919       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11920         {
11921           is_tunnel = 1;
11922           is_tunnel_ipv6 = 1;
11923         }
11924       else
11925         if (unformat
11926             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11927         {
11928           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11929               crypto_alg >= IPSEC_CRYPTO_N_ALG)
11930             {
11931               clib_warning ("unsupported crypto-alg: '%U'",
11932                             format_ipsec_crypto_alg, crypto_alg);
11933               return -99;
11934             }
11935         }
11936       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11937         ;
11938       else
11939         if (unformat
11940             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11941         {
11942 #if DPDK_CRYPTO==1
11943           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
11944 #else
11945           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11946 #endif
11947               integ_alg >= IPSEC_INTEG_N_ALG)
11948             {
11949               clib_warning ("unsupported integ-alg: '%U'",
11950                             format_ipsec_integ_alg, integ_alg);
11951               return -99;
11952             }
11953         }
11954       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11955         ;
11956       else
11957         {
11958           clib_warning ("parse error '%U'", format_unformat_error, i);
11959           return -99;
11960         }
11961
11962     }
11963
11964 #if DPDK_CRYPTO==1
11965   /*Special cases, aes-gcm-128 encryption */
11966   if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
11967     {
11968       if (integ_alg != IPSEC_INTEG_ALG_NONE
11969           && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
11970         {
11971           clib_warning
11972             ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
11973           return -99;
11974         }
11975       else                      /*set integ-alg internally to aes-gcm-128 */
11976         integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
11977     }
11978   else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
11979     {
11980       clib_warning ("unsupported integ-alg: aes-gcm-128");
11981       return -99;
11982     }
11983   else if (integ_alg == IPSEC_INTEG_ALG_NONE)
11984     {
11985       clib_warning ("unsupported integ-alg: none");
11986       return -99;
11987     }
11988 #endif
11989
11990
11991   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11992
11993   mp->sad_id = ntohl (sad_id);
11994   mp->is_add = is_add;
11995   mp->protocol = protocol;
11996   mp->spi = ntohl (spi);
11997   mp->is_tunnel = is_tunnel;
11998   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11999   mp->crypto_algorithm = crypto_alg;
12000   mp->integrity_algorithm = integ_alg;
12001   mp->crypto_key_length = vec_len (ck);
12002   mp->integrity_key_length = vec_len (ik);
12003
12004   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12005     mp->crypto_key_length = sizeof (mp->crypto_key);
12006
12007   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12008     mp->integrity_key_length = sizeof (mp->integrity_key);
12009
12010   if (ck)
12011     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12012   if (ik)
12013     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12014
12015   if (is_tunnel)
12016     {
12017       if (is_tunnel_ipv6)
12018         {
12019           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12020                        sizeof (ip6_address_t));
12021           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12022                        sizeof (ip6_address_t));
12023         }
12024       else
12025         {
12026           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12027                        sizeof (ip4_address_t));
12028           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12029                        sizeof (ip4_address_t));
12030         }
12031     }
12032
12033   S;
12034   W;
12035   /* NOTREACHED */
12036   return 0;
12037 }
12038
12039 static int
12040 api_ipsec_sa_set_key (vat_main_t * vam)
12041 {
12042   unformat_input_t *i = vam->input;
12043   vl_api_ipsec_sa_set_key_t *mp;
12044   f64 timeout;
12045   u32 sa_id;
12046   u8 *ck = 0, *ik = 0;
12047
12048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12049     {
12050       if (unformat (i, "sa_id %d", &sa_id))
12051         ;
12052       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12053         ;
12054       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12055         ;
12056       else
12057         {
12058           clib_warning ("parse error '%U'", format_unformat_error, i);
12059           return -99;
12060         }
12061     }
12062
12063   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
12064
12065   mp->sa_id = ntohl (sa_id);
12066   mp->crypto_key_length = vec_len (ck);
12067   mp->integrity_key_length = vec_len (ik);
12068
12069   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12070     mp->crypto_key_length = sizeof (mp->crypto_key);
12071
12072   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12073     mp->integrity_key_length = sizeof (mp->integrity_key);
12074
12075   if (ck)
12076     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12077   if (ik)
12078     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12079
12080   S;
12081   W;
12082   /* NOTREACHED */
12083   return 0;
12084 }
12085
12086 static int
12087 api_ikev2_profile_add_del (vat_main_t * vam)
12088 {
12089   unformat_input_t *i = vam->input;
12090   vl_api_ikev2_profile_add_del_t *mp;
12091   f64 timeout;
12092   u8 is_add = 1;
12093   u8 *name = 0;
12094
12095   const char *valid_chars = "a-zA-Z0-9_";
12096
12097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12098     {
12099       if (unformat (i, "del"))
12100         is_add = 0;
12101       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12102         vec_add1 (name, 0);
12103       else
12104         {
12105           errmsg ("parse error '%U'", format_unformat_error, i);
12106           return -99;
12107         }
12108     }
12109
12110   if (!vec_len (name))
12111     {
12112       errmsg ("profile name must be specified");
12113       return -99;
12114     }
12115
12116   if (vec_len (name) > 64)
12117     {
12118       errmsg ("profile name too long");
12119       return -99;
12120     }
12121
12122   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
12123
12124   clib_memcpy (mp->name, name, vec_len (name));
12125   mp->is_add = is_add;
12126   vec_free (name);
12127
12128   S;
12129   W;
12130   /* NOTREACHED */
12131   return 0;
12132 }
12133
12134 static int
12135 api_ikev2_profile_set_auth (vat_main_t * vam)
12136 {
12137   unformat_input_t *i = vam->input;
12138   vl_api_ikev2_profile_set_auth_t *mp;
12139   f64 timeout;
12140   u8 *name = 0;
12141   u8 *data = 0;
12142   u32 auth_method = 0;
12143   u8 is_hex = 0;
12144
12145   const char *valid_chars = "a-zA-Z0-9_";
12146
12147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12148     {
12149       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12150         vec_add1 (name, 0);
12151       else if (unformat (i, "auth_method %U",
12152                          unformat_ikev2_auth_method, &auth_method))
12153         ;
12154       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12155         is_hex = 1;
12156       else if (unformat (i, "auth_data %v", &data))
12157         ;
12158       else
12159         {
12160           errmsg ("parse error '%U'", format_unformat_error, i);
12161           return -99;
12162         }
12163     }
12164
12165   if (!vec_len (name))
12166     {
12167       errmsg ("profile name must be specified");
12168       return -99;
12169     }
12170
12171   if (vec_len (name) > 64)
12172     {
12173       errmsg ("profile name too long");
12174       return -99;
12175     }
12176
12177   if (!vec_len (data))
12178     {
12179       errmsg ("auth_data must be specified");
12180       return -99;
12181     }
12182
12183   if (!auth_method)
12184     {
12185       errmsg ("auth_method must be specified");
12186       return -99;
12187     }
12188
12189   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12190
12191   mp->is_hex = is_hex;
12192   mp->auth_method = (u8) auth_method;
12193   mp->data_len = vec_len (data);
12194   clib_memcpy (mp->name, name, vec_len (name));
12195   clib_memcpy (mp->data, data, vec_len (data));
12196   vec_free (name);
12197   vec_free (data);
12198
12199   S;
12200   W;
12201   /* NOTREACHED */
12202   return 0;
12203 }
12204
12205 static int
12206 api_ikev2_profile_set_id (vat_main_t * vam)
12207 {
12208   unformat_input_t *i = vam->input;
12209   vl_api_ikev2_profile_set_id_t *mp;
12210   f64 timeout;
12211   u8 *name = 0;
12212   u8 *data = 0;
12213   u8 is_local = 0;
12214   u32 id_type = 0;
12215   ip4_address_t ip4;
12216
12217   const char *valid_chars = "a-zA-Z0-9_";
12218
12219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12220     {
12221       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12222         vec_add1 (name, 0);
12223       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12224         ;
12225       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12226         {
12227           data = vec_new (u8, 4);
12228           clib_memcpy (data, ip4.as_u8, 4);
12229         }
12230       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12231         ;
12232       else if (unformat (i, "id_data %v", &data))
12233         ;
12234       else if (unformat (i, "local"))
12235         is_local = 1;
12236       else if (unformat (i, "remote"))
12237         is_local = 0;
12238       else
12239         {
12240           errmsg ("parse error '%U'", format_unformat_error, i);
12241           return -99;
12242         }
12243     }
12244
12245   if (!vec_len (name))
12246     {
12247       errmsg ("profile name must be specified");
12248       return -99;
12249     }
12250
12251   if (vec_len (name) > 64)
12252     {
12253       errmsg ("profile name too long");
12254       return -99;
12255     }
12256
12257   if (!vec_len (data))
12258     {
12259       errmsg ("id_data must be specified");
12260       return -99;
12261     }
12262
12263   if (!id_type)
12264     {
12265       errmsg ("id_type must be specified");
12266       return -99;
12267     }
12268
12269   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12270
12271   mp->is_local = is_local;
12272   mp->id_type = (u8) id_type;
12273   mp->data_len = vec_len (data);
12274   clib_memcpy (mp->name, name, vec_len (name));
12275   clib_memcpy (mp->data, data, vec_len (data));
12276   vec_free (name);
12277   vec_free (data);
12278
12279   S;
12280   W;
12281   /* NOTREACHED */
12282   return 0;
12283 }
12284
12285 static int
12286 api_ikev2_profile_set_ts (vat_main_t * vam)
12287 {
12288   unformat_input_t *i = vam->input;
12289   vl_api_ikev2_profile_set_ts_t *mp;
12290   f64 timeout;
12291   u8 *name = 0;
12292   u8 is_local = 0;
12293   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12294   ip4_address_t start_addr, end_addr;
12295
12296   const char *valid_chars = "a-zA-Z0-9_";
12297
12298   start_addr.as_u32 = 0;
12299   end_addr.as_u32 = (u32) ~ 0;
12300
12301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12302     {
12303       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12304         vec_add1 (name, 0);
12305       else if (unformat (i, "protocol %d", &proto))
12306         ;
12307       else if (unformat (i, "start_port %d", &start_port))
12308         ;
12309       else if (unformat (i, "end_port %d", &end_port))
12310         ;
12311       else
12312         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12313         ;
12314       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12315         ;
12316       else if (unformat (i, "local"))
12317         is_local = 1;
12318       else if (unformat (i, "remote"))
12319         is_local = 0;
12320       else
12321         {
12322           errmsg ("parse error '%U'", format_unformat_error, i);
12323           return -99;
12324         }
12325     }
12326
12327   if (!vec_len (name))
12328     {
12329       errmsg ("profile name must be specified");
12330       return -99;
12331     }
12332
12333   if (vec_len (name) > 64)
12334     {
12335       errmsg ("profile name too long");
12336       return -99;
12337     }
12338
12339   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12340
12341   mp->is_local = is_local;
12342   mp->proto = (u8) proto;
12343   mp->start_port = (u16) start_port;
12344   mp->end_port = (u16) end_port;
12345   mp->start_addr = start_addr.as_u32;
12346   mp->end_addr = end_addr.as_u32;
12347   clib_memcpy (mp->name, name, vec_len (name));
12348   vec_free (name);
12349
12350   S;
12351   W;
12352   /* NOTREACHED */
12353   return 0;
12354 }
12355
12356 static int
12357 api_ikev2_set_local_key (vat_main_t * vam)
12358 {
12359   unformat_input_t *i = vam->input;
12360   vl_api_ikev2_set_local_key_t *mp;
12361   f64 timeout;
12362   u8 *file = 0;
12363
12364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12365     {
12366       if (unformat (i, "file %v", &file))
12367         vec_add1 (file, 0);
12368       else
12369         {
12370           errmsg ("parse error '%U'", format_unformat_error, i);
12371           return -99;
12372         }
12373     }
12374
12375   if (!vec_len (file))
12376     {
12377       errmsg ("RSA key file must be specified");
12378       return -99;
12379     }
12380
12381   if (vec_len (file) > 256)
12382     {
12383       errmsg ("file name too long");
12384       return -99;
12385     }
12386
12387   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12388
12389   clib_memcpy (mp->key_file, file, vec_len (file));
12390   vec_free (file);
12391
12392   S;
12393   W;
12394   /* NOTREACHED */
12395   return 0;
12396 }
12397
12398 /*
12399  * MAP
12400  */
12401 static int
12402 api_map_add_domain (vat_main_t * vam)
12403 {
12404   unformat_input_t *i = vam->input;
12405   vl_api_map_add_domain_t *mp;
12406   f64 timeout;
12407
12408   ip4_address_t ip4_prefix;
12409   ip6_address_t ip6_prefix;
12410   ip6_address_t ip6_src;
12411   u32 num_m_args = 0;
12412   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12413     0, psid_length = 0;
12414   u8 is_translation = 0;
12415   u32 mtu = 0;
12416   u32 ip6_src_len = 128;
12417
12418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12419     {
12420       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12421                     &ip4_prefix, &ip4_prefix_len))
12422         num_m_args++;
12423       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12424                          &ip6_prefix, &ip6_prefix_len))
12425         num_m_args++;
12426       else
12427         if (unformat
12428             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12429              &ip6_src_len))
12430         num_m_args++;
12431       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12432         num_m_args++;
12433       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12434         num_m_args++;
12435       else if (unformat (i, "psid-offset %d", &psid_offset))
12436         num_m_args++;
12437       else if (unformat (i, "psid-len %d", &psid_length))
12438         num_m_args++;
12439       else if (unformat (i, "mtu %d", &mtu))
12440         num_m_args++;
12441       else if (unformat (i, "map-t"))
12442         is_translation = 1;
12443       else
12444         {
12445           clib_warning ("parse error '%U'", format_unformat_error, i);
12446           return -99;
12447         }
12448     }
12449
12450   if (num_m_args < 3)
12451     {
12452       errmsg ("mandatory argument(s) missing\n");
12453       return -99;
12454     }
12455
12456   /* Construct the API message */
12457   M (MAP_ADD_DOMAIN, map_add_domain);
12458
12459   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12460   mp->ip4_prefix_len = ip4_prefix_len;
12461
12462   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12463   mp->ip6_prefix_len = ip6_prefix_len;
12464
12465   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12466   mp->ip6_src_prefix_len = ip6_src_len;
12467
12468   mp->ea_bits_len = ea_bits_len;
12469   mp->psid_offset = psid_offset;
12470   mp->psid_length = psid_length;
12471   mp->is_translation = is_translation;
12472   mp->mtu = htons (mtu);
12473
12474   /* send it... */
12475   S;
12476
12477   /* Wait for a reply, return good/bad news  */
12478   W;
12479 }
12480
12481 static int
12482 api_map_del_domain (vat_main_t * vam)
12483 {
12484   unformat_input_t *i = vam->input;
12485   vl_api_map_del_domain_t *mp;
12486   f64 timeout;
12487
12488   u32 num_m_args = 0;
12489   u32 index;
12490
12491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12492     {
12493       if (unformat (i, "index %d", &index))
12494         num_m_args++;
12495       else
12496         {
12497           clib_warning ("parse error '%U'", format_unformat_error, i);
12498           return -99;
12499         }
12500     }
12501
12502   if (num_m_args != 1)
12503     {
12504       errmsg ("mandatory argument(s) missing\n");
12505       return -99;
12506     }
12507
12508   /* Construct the API message */
12509   M (MAP_DEL_DOMAIN, map_del_domain);
12510
12511   mp->index = ntohl (index);
12512
12513   /* send it... */
12514   S;
12515
12516   /* Wait for a reply, return good/bad news  */
12517   W;
12518 }
12519
12520 static int
12521 api_map_add_del_rule (vat_main_t * vam)
12522 {
12523   unformat_input_t *i = vam->input;
12524   vl_api_map_add_del_rule_t *mp;
12525   f64 timeout;
12526   u8 is_add = 1;
12527   ip6_address_t ip6_dst;
12528   u32 num_m_args = 0, index, psid = 0;
12529
12530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12531     {
12532       if (unformat (i, "index %d", &index))
12533         num_m_args++;
12534       else if (unformat (i, "psid %d", &psid))
12535         num_m_args++;
12536       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12537         num_m_args++;
12538       else if (unformat (i, "del"))
12539         {
12540           is_add = 0;
12541         }
12542       else
12543         {
12544           clib_warning ("parse error '%U'", format_unformat_error, i);
12545           return -99;
12546         }
12547     }
12548
12549   /* Construct the API message */
12550   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12551
12552   mp->index = ntohl (index);
12553   mp->is_add = is_add;
12554   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12555   mp->psid = ntohs (psid);
12556
12557   /* send it... */
12558   S;
12559
12560   /* Wait for a reply, return good/bad news  */
12561   W;
12562 }
12563
12564 static int
12565 api_map_domain_dump (vat_main_t * vam)
12566 {
12567   vl_api_map_domain_dump_t *mp;
12568   f64 timeout;
12569
12570   /* Construct the API message */
12571   M (MAP_DOMAIN_DUMP, map_domain_dump);
12572
12573   /* send it... */
12574   S;
12575
12576   /* Use a control ping for synchronization */
12577   {
12578     vl_api_control_ping_t *mp;
12579     M (CONTROL_PING, control_ping);
12580     S;
12581   }
12582   W;
12583 }
12584
12585 static int
12586 api_map_rule_dump (vat_main_t * vam)
12587 {
12588   unformat_input_t *i = vam->input;
12589   vl_api_map_rule_dump_t *mp;
12590   f64 timeout;
12591   u32 domain_index = ~0;
12592
12593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12594     {
12595       if (unformat (i, "index %u", &domain_index))
12596         ;
12597       else
12598         break;
12599     }
12600
12601   if (domain_index == ~0)
12602     {
12603       clib_warning ("parse error: domain index expected");
12604       return -99;
12605     }
12606
12607   /* Construct the API message */
12608   M (MAP_RULE_DUMP, map_rule_dump);
12609
12610   mp->domain_index = htonl (domain_index);
12611
12612   /* send it... */
12613   S;
12614
12615   /* Use a control ping for synchronization */
12616   {
12617     vl_api_control_ping_t *mp;
12618     M (CONTROL_PING, control_ping);
12619     S;
12620   }
12621   W;
12622 }
12623
12624 static void vl_api_map_add_domain_reply_t_handler
12625   (vl_api_map_add_domain_reply_t * mp)
12626 {
12627   vat_main_t *vam = &vat_main;
12628   i32 retval = ntohl (mp->retval);
12629
12630   if (vam->async_mode)
12631     {
12632       vam->async_errors += (retval < 0);
12633     }
12634   else
12635     {
12636       vam->retval = retval;
12637       vam->result_ready = 1;
12638     }
12639 }
12640
12641 static void vl_api_map_add_domain_reply_t_handler_json
12642   (vl_api_map_add_domain_reply_t * mp)
12643 {
12644   vat_main_t *vam = &vat_main;
12645   vat_json_node_t node;
12646
12647   vat_json_init_object (&node);
12648   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12649   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12650
12651   vat_json_print (vam->ofp, &node);
12652   vat_json_free (&node);
12653
12654   vam->retval = ntohl (mp->retval);
12655   vam->result_ready = 1;
12656 }
12657
12658 static int
12659 api_get_first_msg_id (vat_main_t * vam)
12660 {
12661   vl_api_get_first_msg_id_t *mp;
12662   f64 timeout;
12663   unformat_input_t *i = vam->input;
12664   u8 *name;
12665   u8 name_set = 0;
12666
12667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12668     {
12669       if (unformat (i, "client %s", &name))
12670         name_set = 1;
12671       else
12672         break;
12673     }
12674
12675   if (name_set == 0)
12676     {
12677       errmsg ("missing client name\n");
12678       return -99;
12679     }
12680   vec_add1 (name, 0);
12681
12682   if (vec_len (name) > 63)
12683     {
12684       errmsg ("client name too long\n");
12685       return -99;
12686     }
12687
12688   M (GET_FIRST_MSG_ID, get_first_msg_id);
12689   clib_memcpy (mp->name, name, vec_len (name));
12690   S;
12691   W;
12692   /* NOTREACHED */
12693   return 0;
12694 }
12695
12696 static int
12697 api_cop_interface_enable_disable (vat_main_t * vam)
12698 {
12699   unformat_input_t *line_input = vam->input;
12700   vl_api_cop_interface_enable_disable_t *mp;
12701   f64 timeout;
12702   u32 sw_if_index = ~0;
12703   u8 enable_disable = 1;
12704
12705   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12706     {
12707       if (unformat (line_input, "disable"))
12708         enable_disable = 0;
12709       if (unformat (line_input, "enable"))
12710         enable_disable = 1;
12711       else if (unformat (line_input, "%U", unformat_sw_if_index,
12712                          vam, &sw_if_index))
12713         ;
12714       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12715         ;
12716       else
12717         break;
12718     }
12719
12720   if (sw_if_index == ~0)
12721     {
12722       errmsg ("missing interface name or sw_if_index\n");
12723       return -99;
12724     }
12725
12726   /* Construct the API message */
12727   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12728   mp->sw_if_index = ntohl (sw_if_index);
12729   mp->enable_disable = enable_disable;
12730
12731   /* send it... */
12732   S;
12733   /* Wait for the reply */
12734   W;
12735 }
12736
12737 static int
12738 api_cop_whitelist_enable_disable (vat_main_t * vam)
12739 {
12740   unformat_input_t *line_input = vam->input;
12741   vl_api_cop_whitelist_enable_disable_t *mp;
12742   f64 timeout;
12743   u32 sw_if_index = ~0;
12744   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12745   u32 fib_id = 0;
12746
12747   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12748     {
12749       if (unformat (line_input, "ip4"))
12750         ip4 = 1;
12751       else if (unformat (line_input, "ip6"))
12752         ip6 = 1;
12753       else if (unformat (line_input, "default"))
12754         default_cop = 1;
12755       else if (unformat (line_input, "%U", unformat_sw_if_index,
12756                          vam, &sw_if_index))
12757         ;
12758       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12759         ;
12760       else if (unformat (line_input, "fib-id %d", &fib_id))
12761         ;
12762       else
12763         break;
12764     }
12765
12766   if (sw_if_index == ~0)
12767     {
12768       errmsg ("missing interface name or sw_if_index\n");
12769       return -99;
12770     }
12771
12772   /* Construct the API message */
12773   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12774   mp->sw_if_index = ntohl (sw_if_index);
12775   mp->fib_id = ntohl (fib_id);
12776   mp->ip4 = ip4;
12777   mp->ip6 = ip6;
12778   mp->default_cop = default_cop;
12779
12780   /* send it... */
12781   S;
12782   /* Wait for the reply */
12783   W;
12784 }
12785
12786 static int
12787 api_get_node_graph (vat_main_t * vam)
12788 {
12789   vl_api_get_node_graph_t *mp;
12790   f64 timeout;
12791
12792   M (GET_NODE_GRAPH, get_node_graph);
12793
12794   /* send it... */
12795   S;
12796   /* Wait for the reply */
12797   W;
12798 }
12799
12800 /* *INDENT-OFF* */
12801 /** Used for parsing LISP eids */
12802 typedef CLIB_PACKED(struct{
12803   u8 addr[16];   /**< eid address */
12804   u32 len;       /**< prefix length if IP */
12805   u8 type;      /**< type of eid */
12806 }) lisp_eid_vat_t;
12807 /* *INDENT-ON* */
12808
12809 static uword
12810 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12811 {
12812   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12813
12814   memset (a, 0, sizeof (a[0]));
12815
12816   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12817     {
12818       a->type = 0;              /* ipv4 type */
12819     }
12820   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12821     {
12822       a->type = 1;              /* ipv6 type */
12823     }
12824   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12825     {
12826       a->type = 2;              /* mac type */
12827     }
12828   else
12829     {
12830       return 0;
12831     }
12832
12833   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12834     {
12835       return 0;
12836     }
12837
12838   return 1;
12839 }
12840
12841 static int
12842 lisp_eid_size_vat (u8 type)
12843 {
12844   switch (type)
12845     {
12846     case 0:
12847       return 4;
12848     case 1:
12849       return 16;
12850     case 2:
12851       return 6;
12852     }
12853   return 0;
12854 }
12855
12856 static void
12857 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12858 {
12859   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12860 }
12861
12862 /* *INDENT-OFF* */
12863 /** Used for transferring locators via VPP API */
12864 typedef CLIB_PACKED(struct
12865 {
12866   u32 sw_if_index; /**< locator sw_if_index */
12867   u8 priority; /**< locator priority */
12868   u8 weight;   /**< locator weight */
12869 }) ls_locator_t;
12870 /* *INDENT-ON* */
12871
12872 static int
12873 api_lisp_add_del_locator_set (vat_main_t * vam)
12874 {
12875   unformat_input_t *input = vam->input;
12876   vl_api_lisp_add_del_locator_set_t *mp;
12877   f64 timeout = ~0;
12878   u8 is_add = 1;
12879   u8 *locator_set_name = NULL;
12880   u8 locator_set_name_set = 0;
12881   ls_locator_t locator, *locators = 0;
12882   u32 sw_if_index, priority, weight;
12883   u32 data_len = 0;
12884
12885   /* Parse args required to build the message */
12886   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12887     {
12888       if (unformat (input, "del"))
12889         {
12890           is_add = 0;
12891         }
12892       else if (unformat (input, "locator-set %s", &locator_set_name))
12893         {
12894           locator_set_name_set = 1;
12895         }
12896       else if (unformat (input, "sw_if_index %u p %u w %u",
12897                          &sw_if_index, &priority, &weight))
12898         {
12899           locator.sw_if_index = htonl (sw_if_index);
12900           locator.priority = priority;
12901           locator.weight = weight;
12902           vec_add1 (locators, locator);
12903         }
12904       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12905                          vam, &sw_if_index, &priority, &weight))
12906         {
12907           locator.sw_if_index = htonl (sw_if_index);
12908           locator.priority = priority;
12909           locator.weight = weight;
12910           vec_add1 (locators, locator);
12911         }
12912       else
12913         break;
12914     }
12915
12916   if (locator_set_name_set == 0)
12917     {
12918       errmsg ("missing locator-set name");
12919       vec_free (locators);
12920       return -99;
12921     }
12922
12923   if (vec_len (locator_set_name) > 64)
12924     {
12925       errmsg ("locator-set name too long\n");
12926       vec_free (locator_set_name);
12927       vec_free (locators);
12928       return -99;
12929     }
12930   vec_add1 (locator_set_name, 0);
12931
12932   data_len = sizeof (ls_locator_t) * vec_len (locators);
12933
12934   /* Construct the API message */
12935   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12936
12937   mp->is_add = is_add;
12938   clib_memcpy (mp->locator_set_name, locator_set_name,
12939                vec_len (locator_set_name));
12940   vec_free (locator_set_name);
12941
12942   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12943   if (locators)
12944     clib_memcpy (mp->locators, locators, data_len);
12945   vec_free (locators);
12946
12947   /* send it... */
12948   S;
12949
12950   /* Wait for a reply... */
12951   W;
12952
12953   /* NOTREACHED */
12954   return 0;
12955 }
12956
12957 static int
12958 api_lisp_add_del_locator (vat_main_t * vam)
12959 {
12960   unformat_input_t *input = vam->input;
12961   vl_api_lisp_add_del_locator_t *mp;
12962   f64 timeout = ~0;
12963   u32 tmp_if_index = ~0;
12964   u32 sw_if_index = ~0;
12965   u8 sw_if_index_set = 0;
12966   u8 sw_if_index_if_name_set = 0;
12967   u32 priority = ~0;
12968   u8 priority_set = 0;
12969   u32 weight = ~0;
12970   u8 weight_set = 0;
12971   u8 is_add = 1;
12972   u8 *locator_set_name = NULL;
12973   u8 locator_set_name_set = 0;
12974
12975   /* Parse args required to build the message */
12976   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12977     {
12978       if (unformat (input, "del"))
12979         {
12980           is_add = 0;
12981         }
12982       else if (unformat (input, "locator-set %s", &locator_set_name))
12983         {
12984           locator_set_name_set = 1;
12985         }
12986       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12987                          &tmp_if_index))
12988         {
12989           sw_if_index_if_name_set = 1;
12990           sw_if_index = tmp_if_index;
12991         }
12992       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12993         {
12994           sw_if_index_set = 1;
12995           sw_if_index = tmp_if_index;
12996         }
12997       else if (unformat (input, "p %d", &priority))
12998         {
12999           priority_set = 1;
13000         }
13001       else if (unformat (input, "w %d", &weight))
13002         {
13003           weight_set = 1;
13004         }
13005       else
13006         break;
13007     }
13008
13009   if (locator_set_name_set == 0)
13010     {
13011       errmsg ("missing locator-set name");
13012       return -99;
13013     }
13014
13015   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13016     {
13017       errmsg ("missing sw_if_index");
13018       vec_free (locator_set_name);
13019       return -99;
13020     }
13021
13022   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13023     {
13024       errmsg ("cannot use both params interface name and sw_if_index");
13025       vec_free (locator_set_name);
13026       return -99;
13027     }
13028
13029   if (priority_set == 0)
13030     {
13031       errmsg ("missing locator-set priority\n");
13032       vec_free (locator_set_name);
13033       return -99;
13034     }
13035
13036   if (weight_set == 0)
13037     {
13038       errmsg ("missing locator-set weight\n");
13039       vec_free (locator_set_name);
13040       return -99;
13041     }
13042
13043   if (vec_len (locator_set_name) > 64)
13044     {
13045       errmsg ("locator-set name too long\n");
13046       vec_free (locator_set_name);
13047       return -99;
13048     }
13049   vec_add1 (locator_set_name, 0);
13050
13051   /* Construct the API message */
13052   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
13053
13054   mp->is_add = is_add;
13055   mp->sw_if_index = ntohl (sw_if_index);
13056   mp->priority = priority;
13057   mp->weight = weight;
13058   clib_memcpy (mp->locator_set_name, locator_set_name,
13059                vec_len (locator_set_name));
13060   vec_free (locator_set_name);
13061
13062   /* send it... */
13063   S;
13064
13065   /* Wait for a reply... */
13066   W;
13067
13068   /* NOTREACHED */
13069   return 0;
13070 }
13071
13072 uword
13073 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13074 {
13075   u32 *key_id = va_arg (*args, u32 *);
13076   u8 *s = 0;
13077
13078   if (unformat (input, "%s", &s))
13079     {
13080       if (!strcmp ((char *) s, "sha1"))
13081         key_id[0] = HMAC_SHA_1_96;
13082       else if (!strcmp ((char *) s, "sha256"))
13083         key_id[0] = HMAC_SHA_256_128;
13084       else
13085         {
13086           clib_warning ("invalid key_id: '%s'", s);
13087           key_id[0] = HMAC_NO_KEY;
13088         }
13089     }
13090   else
13091     return 0;
13092
13093   vec_free (s);
13094   return 1;
13095 }
13096
13097 static int
13098 api_lisp_add_del_local_eid (vat_main_t * vam)
13099 {
13100   unformat_input_t *input = vam->input;
13101   vl_api_lisp_add_del_local_eid_t *mp;
13102   f64 timeout = ~0;
13103   u8 is_add = 1;
13104   u8 eid_set = 0;
13105   lisp_eid_vat_t _eid, *eid = &_eid;
13106   u8 *locator_set_name = 0;
13107   u8 locator_set_name_set = 0;
13108   u32 vni = 0;
13109   u16 key_id = 0;
13110   u8 *key = 0;
13111
13112   /* Parse args required to build the message */
13113   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13114     {
13115       if (unformat (input, "del"))
13116         {
13117           is_add = 0;
13118         }
13119       else if (unformat (input, "vni %d", &vni))
13120         {
13121           ;
13122         }
13123       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13124         {
13125           eid_set = 1;
13126         }
13127       else if (unformat (input, "locator-set %s", &locator_set_name))
13128         {
13129           locator_set_name_set = 1;
13130         }
13131       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13132         ;
13133       else if (unformat (input, "secret-key %_%v%_", &key))
13134         ;
13135       else
13136         break;
13137     }
13138
13139   if (locator_set_name_set == 0)
13140     {
13141       errmsg ("missing locator-set name\n");
13142       return -99;
13143     }
13144
13145   if (0 == eid_set)
13146     {
13147       errmsg ("EID address not set!");
13148       vec_free (locator_set_name);
13149       return -99;
13150     }
13151
13152   if (key && (0 == key_id))
13153     {
13154       errmsg ("invalid key_id!");
13155       return -99;
13156     }
13157
13158   if (vec_len (key) > 64)
13159     {
13160       errmsg ("key too long");
13161       vec_free (key);
13162       return -99;
13163     }
13164
13165   if (vec_len (locator_set_name) > 64)
13166     {
13167       errmsg ("locator-set name too long\n");
13168       vec_free (locator_set_name);
13169       return -99;
13170     }
13171   vec_add1 (locator_set_name, 0);
13172
13173   /* Construct the API message */
13174   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
13175
13176   mp->is_add = is_add;
13177   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13178   mp->eid_type = eid->type;
13179   mp->prefix_len = eid->len;
13180   mp->vni = clib_host_to_net_u32 (vni);
13181   mp->key_id = clib_host_to_net_u16 (key_id);
13182   clib_memcpy (mp->locator_set_name, locator_set_name,
13183                vec_len (locator_set_name));
13184   clib_memcpy (mp->key, key, vec_len (key));
13185
13186   vec_free (locator_set_name);
13187   vec_free (key);
13188
13189   /* send it... */
13190   S;
13191
13192   /* Wait for a reply... */
13193   W;
13194
13195   /* NOTREACHED */
13196   return 0;
13197 }
13198
13199 /* *INDENT-OFF* */
13200 /** Used for transferring locators via VPP API */
13201 typedef CLIB_PACKED(struct
13202 {
13203   u8 is_ip4; /**< is locator an IPv4 address? */
13204   u8 priority; /**< locator priority */
13205   u8 weight;   /**< locator weight */
13206   u8 addr[16]; /**< IPv4/IPv6 address */
13207 }) rloc_t;
13208 /* *INDENT-ON* */
13209
13210 static int
13211 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13212 {
13213   unformat_input_t *input = vam->input;
13214   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13215   f64 timeout = ~0;
13216   u8 is_add = 1;
13217   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13218   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13219   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13220   u32 action = ~0, p, w;
13221   ip4_address_t rmt_rloc4, lcl_rloc4;
13222   ip6_address_t rmt_rloc6, lcl_rloc6;
13223   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13224
13225   memset (&rloc, 0, sizeof (rloc));
13226
13227   /* Parse args required to build the message */
13228   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13229     {
13230       if (unformat (input, "del"))
13231         {
13232           is_add = 0;
13233         }
13234       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
13235         {
13236           rmt_eid_set = 1;
13237         }
13238       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
13239         {
13240           lcl_eid_set = 1;
13241         }
13242       else if (unformat (input, "p %d w %d", &p, &w))
13243         {
13244           if (!curr_rloc)
13245             {
13246               errmsg ("No RLOC configured for setting priority/weight!");
13247               return -99;
13248             }
13249           curr_rloc->priority = p;
13250           curr_rloc->weight = w;
13251         }
13252       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13253                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13254         {
13255           rloc.is_ip4 = 1;
13256
13257           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13258           rloc.priority = rloc.weight = 0;
13259           vec_add1 (lcl_locs, rloc);
13260
13261           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13262           vec_add1 (rmt_locs, rloc);
13263           /* priority and weight saved in rmt loc */
13264           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13265         }
13266       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13267                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13268         {
13269           rloc.is_ip4 = 0;
13270           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13271           rloc.priority = rloc.weight = 0;
13272           vec_add1 (lcl_locs, rloc);
13273
13274           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13275           vec_add1 (rmt_locs, rloc);
13276           /* priority and weight saved in rmt loc */
13277           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13278         }
13279       else if (unformat (input, "action %d", &action))
13280         {
13281           ;
13282         }
13283       else
13284         {
13285           clib_warning ("parse error '%U'", format_unformat_error, input);
13286           return -99;
13287         }
13288     }
13289
13290   if (!rmt_eid_set)
13291     {
13292       errmsg ("remote eid addresses not set\n");
13293       return -99;
13294     }
13295
13296   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13297     {
13298       errmsg ("eid types don't match\n");
13299       return -99;
13300     }
13301
13302   if (0 == rmt_locs && (u32) ~ 0 == action)
13303     {
13304       errmsg ("action not set for negative mapping\n");
13305       return -99;
13306     }
13307
13308   /* Construct the API message */
13309   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13310
13311   mp->is_add = is_add;
13312   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13313   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13314   mp->eid_type = rmt_eid->type;
13315   mp->rmt_len = rmt_eid->len;
13316   mp->lcl_len = lcl_eid->len;
13317   mp->action = action;
13318
13319   if (0 != rmt_locs && 0 != lcl_locs)
13320     {
13321       mp->loc_num = vec_len (rmt_locs);
13322       clib_memcpy (mp->lcl_locs, lcl_locs,
13323                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13324       clib_memcpy (mp->rmt_locs, rmt_locs,
13325                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13326     }
13327   vec_free (lcl_locs);
13328   vec_free (rmt_locs);
13329
13330   /* send it... */
13331   S;
13332
13333   /* Wait for a reply... */
13334   W;
13335
13336   /* NOTREACHED */
13337   return 0;
13338 }
13339
13340 static int
13341 api_lisp_add_del_map_server (vat_main_t * vam)
13342 {
13343   unformat_input_t *input = vam->input;
13344   vl_api_lisp_add_del_map_server_t *mp;
13345   f64 timeout = ~0;
13346   u8 is_add = 1;
13347   u8 ipv4_set = 0;
13348   u8 ipv6_set = 0;
13349   ip4_address_t ipv4;
13350   ip6_address_t ipv6;
13351
13352   /* Parse args required to build the message */
13353   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13354     {
13355       if (unformat (input, "del"))
13356         {
13357           is_add = 0;
13358         }
13359       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13360         {
13361           ipv4_set = 1;
13362         }
13363       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13364         {
13365           ipv6_set = 1;
13366         }
13367       else
13368         break;
13369     }
13370
13371   if (ipv4_set && ipv6_set)
13372     {
13373       errmsg ("both eid v4 and v6 addresses set\n");
13374       return -99;
13375     }
13376
13377   if (!ipv4_set && !ipv6_set)
13378     {
13379       errmsg ("eid addresses not set\n");
13380       return -99;
13381     }
13382
13383   /* Construct the API message */
13384   M (LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server);
13385
13386   mp->is_add = is_add;
13387   if (ipv6_set)
13388     {
13389       mp->is_ipv6 = 1;
13390       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13391     }
13392   else
13393     {
13394       mp->is_ipv6 = 0;
13395       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13396     }
13397
13398   /* send it... */
13399   S;
13400
13401   /* Wait for a reply... */
13402   W;
13403
13404   /* NOTREACHED */
13405   return 0;
13406 }
13407
13408 static int
13409 api_lisp_add_del_map_resolver (vat_main_t * vam)
13410 {
13411   unformat_input_t *input = vam->input;
13412   vl_api_lisp_add_del_map_resolver_t *mp;
13413   f64 timeout = ~0;
13414   u8 is_add = 1;
13415   u8 ipv4_set = 0;
13416   u8 ipv6_set = 0;
13417   ip4_address_t ipv4;
13418   ip6_address_t ipv6;
13419
13420   /* Parse args required to build the message */
13421   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13422     {
13423       if (unformat (input, "del"))
13424         {
13425           is_add = 0;
13426         }
13427       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13428         {
13429           ipv4_set = 1;
13430         }
13431       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13432         {
13433           ipv6_set = 1;
13434         }
13435       else
13436         break;
13437     }
13438
13439   if (ipv4_set && ipv6_set)
13440     {
13441       errmsg ("both eid v4 and v6 addresses set\n");
13442       return -99;
13443     }
13444
13445   if (!ipv4_set && !ipv6_set)
13446     {
13447       errmsg ("eid addresses not set\n");
13448       return -99;
13449     }
13450
13451   /* Construct the API message */
13452   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13453
13454   mp->is_add = is_add;
13455   if (ipv6_set)
13456     {
13457       mp->is_ipv6 = 1;
13458       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13459     }
13460   else
13461     {
13462       mp->is_ipv6 = 0;
13463       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13464     }
13465
13466   /* send it... */
13467   S;
13468
13469   /* Wait for a reply... */
13470   W;
13471
13472   /* NOTREACHED */
13473   return 0;
13474 }
13475
13476 static int
13477 api_lisp_gpe_enable_disable (vat_main_t * vam)
13478 {
13479   unformat_input_t *input = vam->input;
13480   vl_api_lisp_gpe_enable_disable_t *mp;
13481   f64 timeout = ~0;
13482   u8 is_set = 0;
13483   u8 is_en = 1;
13484
13485   /* Parse args required to build the message */
13486   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13487     {
13488       if (unformat (input, "enable"))
13489         {
13490           is_set = 1;
13491           is_en = 1;
13492         }
13493       else if (unformat (input, "disable"))
13494         {
13495           is_set = 1;
13496           is_en = 0;
13497         }
13498       else
13499         break;
13500     }
13501
13502   if (is_set == 0)
13503     {
13504       errmsg ("Value not set\n");
13505       return -99;
13506     }
13507
13508   /* Construct the API message */
13509   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13510
13511   mp->is_en = 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_rloc_probe_enable_disable (vat_main_t * vam)
13525 {
13526   unformat_input_t *input = vam->input;
13527   vl_api_lisp_rloc_probe_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         is_set = 1;
13542       else
13543         break;
13544     }
13545
13546   if (!is_set)
13547     {
13548       errmsg ("Value not set\n");
13549       return -99;
13550     }
13551
13552   /* Construct the API message */
13553   M (LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable);
13554
13555   mp->is_enabled = is_en;
13556
13557   /* send it... */
13558   S;
13559
13560   /* Wait for a reply... */
13561   W;
13562
13563   /* NOTREACHED */
13564   return 0;
13565 }
13566
13567 static int
13568 api_lisp_map_register_enable_disable (vat_main_t * vam)
13569 {
13570   unformat_input_t *input = vam->input;
13571   vl_api_lisp_map_register_enable_disable_t *mp;
13572   f64 timeout = ~0;
13573   u8 is_set = 0;
13574   u8 is_en = 0;
13575
13576   /* Parse args required to build the message */
13577   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13578     {
13579       if (unformat (input, "enable"))
13580         {
13581           is_set = 1;
13582           is_en = 1;
13583         }
13584       else if (unformat (input, "disable"))
13585         is_set = 1;
13586       else
13587         break;
13588     }
13589
13590   if (!is_set)
13591     {
13592       errmsg ("Value not set\n");
13593       return -99;
13594     }
13595
13596   /* Construct the API message */
13597   M (LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable);
13598
13599   mp->is_enabled = is_en;
13600
13601   /* send it... */
13602   S;
13603
13604   /* Wait for a reply... */
13605   W;
13606
13607   /* NOTREACHED */
13608   return 0;
13609 }
13610
13611 static int
13612 api_lisp_enable_disable (vat_main_t * vam)
13613 {
13614   unformat_input_t *input = vam->input;
13615   vl_api_lisp_enable_disable_t *mp;
13616   f64 timeout = ~0;
13617   u8 is_set = 0;
13618   u8 is_en = 0;
13619
13620   /* Parse args required to build the message */
13621   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13622     {
13623       if (unformat (input, "enable"))
13624         {
13625           is_set = 1;
13626           is_en = 1;
13627         }
13628       else if (unformat (input, "disable"))
13629         {
13630           is_set = 1;
13631         }
13632       else
13633         break;
13634     }
13635
13636   if (!is_set)
13637     {
13638       errmsg ("Value not set\n");
13639       return -99;
13640     }
13641
13642   /* Construct the API message */
13643   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13644
13645   mp->is_en = is_en;
13646
13647   /* send it... */
13648   S;
13649
13650   /* Wait for a reply... */
13651   W;
13652
13653   /* NOTREACHED */
13654   return 0;
13655 }
13656
13657 static int
13658 api_show_lisp_map_register_state (vat_main_t * vam)
13659 {
13660   f64 timeout = ~0;
13661   vl_api_show_lisp_map_register_state_t *mp;
13662
13663   M (SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state);
13664
13665   /* send */
13666   S;
13667
13668   /* wait for reply */
13669   W;
13670
13671   return 0;
13672 }
13673
13674 static int
13675 api_show_lisp_rloc_probe_state (vat_main_t * vam)
13676 {
13677   f64 timeout = ~0;
13678   vl_api_show_lisp_rloc_probe_state_t *mp;
13679
13680   M (SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state);
13681
13682   /* send */
13683   S;
13684
13685   /* wait for reply */
13686   W;
13687
13688   return 0;
13689 }
13690
13691 static int
13692 api_show_lisp_map_request_mode (vat_main_t * vam)
13693 {
13694   f64 timeout = ~0;
13695   vl_api_show_lisp_map_request_mode_t *mp;
13696
13697   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13698
13699   /* send */
13700   S;
13701
13702   /* wait for reply */
13703   W;
13704
13705   return 0;
13706 }
13707
13708 static int
13709 api_lisp_map_request_mode (vat_main_t * vam)
13710 {
13711   f64 timeout = ~0;
13712   unformat_input_t *input = vam->input;
13713   vl_api_lisp_map_request_mode_t *mp;
13714   u8 mode = 0;
13715
13716   /* Parse args required to build the message */
13717   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13718     {
13719       if (unformat (input, "dst-only"))
13720         mode = 0;
13721       else if (unformat (input, "src-dst"))
13722         mode = 1;
13723       else
13724         {
13725           errmsg ("parse error '%U'", format_unformat_error, input);
13726           return -99;
13727         }
13728     }
13729
13730   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13731
13732   mp->mode = mode;
13733
13734   /* send */
13735   S;
13736
13737   /* wait for reply */
13738   W;
13739
13740   /* notreached */
13741   return 0;
13742 }
13743
13744 /**
13745  * Enable/disable LISP proxy ITR.
13746  *
13747  * @param vam vpp API test context
13748  * @return return code
13749  */
13750 static int
13751 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13752 {
13753   f64 timeout = ~0;
13754   u8 ls_name_set = 0;
13755   unformat_input_t *input = vam->input;
13756   vl_api_lisp_pitr_set_locator_set_t *mp;
13757   u8 is_add = 1;
13758   u8 *ls_name = 0;
13759
13760   /* Parse args required to build the message */
13761   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13762     {
13763       if (unformat (input, "del"))
13764         is_add = 0;
13765       else if (unformat (input, "locator-set %s", &ls_name))
13766         ls_name_set = 1;
13767       else
13768         {
13769           errmsg ("parse error '%U'", format_unformat_error, input);
13770           return -99;
13771         }
13772     }
13773
13774   if (!ls_name_set)
13775     {
13776       errmsg ("locator-set name not set!");
13777       return -99;
13778     }
13779
13780   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13781
13782   mp->is_add = is_add;
13783   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13784   vec_free (ls_name);
13785
13786   /* send */
13787   S;
13788
13789   /* wait for reply */
13790   W;
13791
13792   /* notreached */
13793   return 0;
13794 }
13795
13796 static int
13797 api_show_lisp_pitr (vat_main_t * vam)
13798 {
13799   vl_api_show_lisp_pitr_t *mp;
13800   f64 timeout = ~0;
13801
13802   if (!vam->json_output)
13803     {
13804       fformat (vam->ofp, "%=20s\n", "lisp status:");
13805     }
13806
13807   M (SHOW_LISP_PITR, show_lisp_pitr);
13808   /* send it... */
13809   S;
13810
13811   /* Wait for a reply... */
13812   W;
13813
13814   /* NOTREACHED */
13815   return 0;
13816 }
13817
13818 /**
13819  * Add/delete mapping between vni and vrf
13820  */
13821 static int
13822 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13823 {
13824   f64 timeout = ~0;
13825   unformat_input_t *input = vam->input;
13826   vl_api_lisp_eid_table_add_del_map_t *mp;
13827   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13828   u32 vni, vrf, bd_index;
13829
13830   /* Parse args required to build the message */
13831   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13832     {
13833       if (unformat (input, "del"))
13834         is_add = 0;
13835       else if (unformat (input, "vrf %d", &vrf))
13836         vrf_set = 1;
13837       else if (unformat (input, "bd_index %d", &bd_index))
13838         bd_index_set = 1;
13839       else if (unformat (input, "vni %d", &vni))
13840         vni_set = 1;
13841       else
13842         break;
13843     }
13844
13845   if (!vni_set || (!vrf_set && !bd_index_set))
13846     {
13847       errmsg ("missing arguments!");
13848       return -99;
13849     }
13850
13851   if (vrf_set && bd_index_set)
13852     {
13853       errmsg ("error: both vrf and bd entered!");
13854       return -99;
13855     }
13856
13857   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13858
13859   mp->is_add = is_add;
13860   mp->vni = htonl (vni);
13861   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13862   mp->is_l2 = bd_index_set;
13863
13864   /* send */
13865   S;
13866
13867   /* wait for reply */
13868   W;
13869
13870   /* notreached */
13871   return 0;
13872 }
13873
13874 uword
13875 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13876 {
13877   u32 *action = va_arg (*args, u32 *);
13878   u8 *s = 0;
13879
13880   if (unformat (input, "%s", &s))
13881     {
13882       if (!strcmp ((char *) s, "no-action"))
13883         action[0] = 0;
13884       else if (!strcmp ((char *) s, "natively-forward"))
13885         action[0] = 1;
13886       else if (!strcmp ((char *) s, "send-map-request"))
13887         action[0] = 2;
13888       else if (!strcmp ((char *) s, "drop"))
13889         action[0] = 3;
13890       else
13891         {
13892           clib_warning ("invalid action: '%s'", s);
13893           action[0] = 3;
13894         }
13895     }
13896   else
13897     return 0;
13898
13899   vec_free (s);
13900   return 1;
13901 }
13902
13903 /**
13904  * Add/del remote mapping to/from LISP control plane
13905  *
13906  * @param vam vpp API test context
13907  * @return return code
13908  */
13909 static int
13910 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13911 {
13912   unformat_input_t *input = vam->input;
13913   vl_api_lisp_add_del_remote_mapping_t *mp;
13914   f64 timeout = ~0;
13915   u32 vni = 0;
13916   lisp_eid_vat_t _eid, *eid = &_eid;
13917   lisp_eid_vat_t _seid, *seid = &_seid;
13918   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13919   u32 action = ~0, p, w, data_len;
13920   ip4_address_t rloc4;
13921   ip6_address_t rloc6;
13922   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13923
13924   memset (&rloc, 0, sizeof (rloc));
13925
13926   /* Parse args required to build the message */
13927   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13928     {
13929       if (unformat (input, "del-all"))
13930         {
13931           del_all = 1;
13932         }
13933       else if (unformat (input, "del"))
13934         {
13935           is_add = 0;
13936         }
13937       else if (unformat (input, "add"))
13938         {
13939           is_add = 1;
13940         }
13941       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13942         {
13943           eid_set = 1;
13944         }
13945       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13946         {
13947           seid_set = 1;
13948         }
13949       else if (unformat (input, "vni %d", &vni))
13950         {
13951           ;
13952         }
13953       else if (unformat (input, "p %d w %d", &p, &w))
13954         {
13955           if (!curr_rloc)
13956             {
13957               errmsg ("No RLOC configured for setting priority/weight!");
13958               return -99;
13959             }
13960           curr_rloc->priority = p;
13961           curr_rloc->weight = w;
13962         }
13963       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13964         {
13965           rloc.is_ip4 = 1;
13966           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13967           vec_add1 (rlocs, rloc);
13968           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13969         }
13970       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13971         {
13972           rloc.is_ip4 = 0;
13973           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13974           vec_add1 (rlocs, rloc);
13975           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13976         }
13977       else if (unformat (input, "action %U",
13978                          unformat_negative_mapping_action, &action))
13979         {
13980           ;
13981         }
13982       else
13983         {
13984           clib_warning ("parse error '%U'", format_unformat_error, input);
13985           return -99;
13986         }
13987     }
13988
13989   if (0 == eid_set)
13990     {
13991       errmsg ("missing params!");
13992       return -99;
13993     }
13994
13995   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13996     {
13997       errmsg ("no action set for negative map-reply!");
13998       return -99;
13999     }
14000
14001   data_len = vec_len (rlocs) * sizeof (rloc_t);
14002
14003   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
14004   mp->is_add = is_add;
14005   mp->vni = htonl (vni);
14006   mp->action = (u8) action;
14007   mp->is_src_dst = seid_set;
14008   mp->eid_len = eid->len;
14009   mp->seid_len = seid->len;
14010   mp->del_all = del_all;
14011   mp->eid_type = eid->type;
14012   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14013   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14014
14015   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14016   clib_memcpy (mp->rlocs, rlocs, data_len);
14017   vec_free (rlocs);
14018
14019   /* send it... */
14020   S;
14021
14022   /* Wait for a reply... */
14023   W;
14024
14025   /* NOTREACHED */
14026   return 0;
14027 }
14028
14029 /**
14030  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14031  * forwarding entries in data-plane accordingly.
14032  *
14033  * @param vam vpp API test context
14034  * @return return code
14035  */
14036 static int
14037 api_lisp_add_del_adjacency (vat_main_t * vam)
14038 {
14039   unformat_input_t *input = vam->input;
14040   vl_api_lisp_add_del_adjacency_t *mp;
14041   f64 timeout = ~0;
14042   u32 vni = 0;
14043   ip4_address_t leid4, reid4;
14044   ip6_address_t leid6, reid6;
14045   u8 reid_mac[6] = { 0 };
14046   u8 leid_mac[6] = { 0 };
14047   u8 reid_type, leid_type;
14048   u32 leid_len = 0, reid_len = 0, len;
14049   u8 is_add = 1;
14050
14051   leid_type = reid_type = (u8) ~ 0;
14052
14053   /* Parse args required to build the message */
14054   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14055     {
14056       if (unformat (input, "del"))
14057         {
14058           is_add = 0;
14059         }
14060       else if (unformat (input, "add"))
14061         {
14062           is_add = 1;
14063         }
14064       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14065                          &reid4, &len))
14066         {
14067           reid_type = 0;        /* ipv4 */
14068           reid_len = len;
14069         }
14070       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14071                          &reid6, &len))
14072         {
14073           reid_type = 1;        /* ipv6 */
14074           reid_len = len;
14075         }
14076       else if (unformat (input, "reid %U", unformat_ethernet_address,
14077                          reid_mac))
14078         {
14079           reid_type = 2;        /* mac */
14080         }
14081       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14082                          &leid4, &len))
14083         {
14084           leid_type = 0;        /* ipv4 */
14085           leid_len = len;
14086         }
14087       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14088                          &leid6, &len))
14089         {
14090           leid_type = 1;        /* ipv6 */
14091           leid_len = len;
14092         }
14093       else if (unformat (input, "leid %U", unformat_ethernet_address,
14094                          leid_mac))
14095         {
14096           leid_type = 2;        /* mac */
14097         }
14098       else if (unformat (input, "vni %d", &vni))
14099         {
14100           ;
14101         }
14102       else
14103         {
14104           errmsg ("parse error '%U'", format_unformat_error, input);
14105           return -99;
14106         }
14107     }
14108
14109   if ((u8) ~ 0 == reid_type)
14110     {
14111       errmsg ("missing params!");
14112       return -99;
14113     }
14114
14115   if (leid_type != reid_type)
14116     {
14117       errmsg ("remote and local EIDs are of different types!");
14118       return -99;
14119     }
14120
14121   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
14122   mp->is_add = is_add;
14123   mp->vni = htonl (vni);
14124   mp->leid_len = leid_len;
14125   mp->reid_len = reid_len;
14126   mp->eid_type = reid_type;
14127
14128   switch (mp->eid_type)
14129     {
14130     case 0:
14131       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14132       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14133       break;
14134     case 1:
14135       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14136       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14137       break;
14138     case 2:
14139       clib_memcpy (mp->leid, leid_mac, 6);
14140       clib_memcpy (mp->reid, reid_mac, 6);
14141       break;
14142     default:
14143       errmsg ("unknown EID type %d!", mp->eid_type);
14144       return 0;
14145     }
14146
14147   /* send it... */
14148   S;
14149
14150   /* Wait for a reply... */
14151   W;
14152
14153   /* NOTREACHED */
14154   return 0;
14155 }
14156
14157 static int
14158 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14159 {
14160   unformat_input_t *input = vam->input;
14161   vl_api_lisp_gpe_add_del_iface_t *mp;
14162   f64 timeout = ~0;
14163   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14164   u32 dp_table = 0, vni = 0;
14165
14166   /* Parse args required to build the message */
14167   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14168     {
14169       if (unformat (input, "up"))
14170         {
14171           action_set = 1;
14172           is_add = 1;
14173         }
14174       else if (unformat (input, "down"))
14175         {
14176           action_set = 1;
14177           is_add = 0;
14178         }
14179       else if (unformat (input, "table_id %d", &dp_table))
14180         {
14181           dp_table_set = 1;
14182         }
14183       else if (unformat (input, "bd_id %d", &dp_table))
14184         {
14185           dp_table_set = 1;
14186           is_l2 = 1;
14187         }
14188       else if (unformat (input, "vni %d", &vni))
14189         {
14190           vni_set = 1;
14191         }
14192       else
14193         break;
14194     }
14195
14196   if (action_set == 0)
14197     {
14198       errmsg ("Action not set\n");
14199       return -99;
14200     }
14201   if (dp_table_set == 0 || vni_set == 0)
14202     {
14203       errmsg ("vni and dp_table must be set\n");
14204       return -99;
14205     }
14206
14207   /* Construct the API message */
14208   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
14209
14210   mp->is_add = is_add;
14211   mp->dp_table = dp_table;
14212   mp->is_l2 = is_l2;
14213   mp->vni = vni;
14214
14215   /* send it... */
14216   S;
14217
14218   /* Wait for a reply... */
14219   W;
14220
14221   /* NOTREACHED */
14222   return 0;
14223 }
14224
14225 /**
14226  * Add/del map request itr rlocs from LISP control plane and updates
14227  *
14228  * @param vam vpp API test context
14229  * @return return code
14230  */
14231 static int
14232 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14233 {
14234   unformat_input_t *input = vam->input;
14235   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14236   f64 timeout = ~0;
14237   u8 *locator_set_name = 0;
14238   u8 locator_set_name_set = 0;
14239   u8 is_add = 1;
14240
14241   /* Parse args required to build the message */
14242   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14243     {
14244       if (unformat (input, "del"))
14245         {
14246           is_add = 0;
14247         }
14248       else if (unformat (input, "%_%v%_", &locator_set_name))
14249         {
14250           locator_set_name_set = 1;
14251         }
14252       else
14253         {
14254           clib_warning ("parse error '%U'", format_unformat_error, input);
14255           return -99;
14256         }
14257     }
14258
14259   if (is_add && !locator_set_name_set)
14260     {
14261       errmsg ("itr-rloc is not set!");
14262       return -99;
14263     }
14264
14265   if (is_add && vec_len (locator_set_name) > 64)
14266     {
14267       errmsg ("itr-rloc locator-set name too long\n");
14268       vec_free (locator_set_name);
14269       return -99;
14270     }
14271
14272   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
14273   mp->is_add = is_add;
14274   if (is_add)
14275     {
14276       clib_memcpy (mp->locator_set_name, locator_set_name,
14277                    vec_len (locator_set_name));
14278     }
14279   else
14280     {
14281       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14282     }
14283   vec_free (locator_set_name);
14284
14285   /* send it... */
14286   S;
14287
14288   /* Wait for a reply... */
14289   W;
14290
14291   /* NOTREACHED */
14292   return 0;
14293 }
14294
14295 static int
14296 api_lisp_locator_dump (vat_main_t * vam)
14297 {
14298   unformat_input_t *input = vam->input;
14299   vl_api_lisp_locator_dump_t *mp;
14300   f64 timeout = ~0;
14301   u8 is_index_set = 0, is_name_set = 0;
14302   u8 *ls_name = 0;
14303   u32 ls_index = ~0;
14304
14305   /* Parse args required to build the message */
14306   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14307     {
14308       if (unformat (input, "ls_name %_%v%_", &ls_name))
14309         {
14310           is_name_set = 1;
14311         }
14312       else if (unformat (input, "ls_index %d", &ls_index))
14313         {
14314           is_index_set = 1;
14315         }
14316       else
14317         {
14318           errmsg ("parse error '%U'", format_unformat_error, input);
14319           return -99;
14320         }
14321     }
14322
14323   if (!is_index_set && !is_name_set)
14324     {
14325       errmsg ("error: expected one of index or name!\n");
14326       return -99;
14327     }
14328
14329   if (is_index_set && is_name_set)
14330     {
14331       errmsg ("error: only one param expected!\n");
14332       return -99;
14333     }
14334
14335   if (vec_len (ls_name) > 62)
14336     {
14337       errmsg ("error: locator set name too long!");
14338       return -99;
14339     }
14340
14341   if (!vam->json_output)
14342     {
14343       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
14344                "weight");
14345     }
14346
14347   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
14348   mp->is_index_set = is_index_set;
14349
14350   if (is_index_set)
14351     mp->ls_index = clib_host_to_net_u32 (ls_index);
14352   else
14353     {
14354       vec_add1 (ls_name, 0);
14355       strncpy ((char *) mp->ls_name, (char *) ls_name,
14356                sizeof (mp->ls_name) - 1);
14357     }
14358
14359   /* send it... */
14360   S;
14361
14362   /* Use a control ping for synchronization */
14363   {
14364     vl_api_control_ping_t *mp;
14365     M (CONTROL_PING, control_ping);
14366     S;
14367   }
14368   /* Wait for a reply... */
14369   W;
14370
14371   /* NOTREACHED */
14372   return 0;
14373 }
14374
14375 static int
14376 api_lisp_locator_set_dump (vat_main_t * vam)
14377 {
14378   vl_api_lisp_locator_set_dump_t *mp;
14379   unformat_input_t *input = vam->input;
14380   f64 timeout = ~0;
14381   u8 filter = 0;
14382
14383   /* Parse args required to build the message */
14384   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14385     {
14386       if (unformat (input, "local"))
14387         {
14388           filter = 1;
14389         }
14390       else if (unformat (input, "remote"))
14391         {
14392           filter = 2;
14393         }
14394       else
14395         {
14396           errmsg ("parse error '%U'", format_unformat_error, input);
14397           return -99;
14398         }
14399     }
14400
14401   if (!vam->json_output)
14402     {
14403       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
14404     }
14405
14406   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14407
14408   mp->filter = filter;
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_map_dump (vat_main_t * vam)
14428 {
14429   u8 is_l2 = 0;
14430   u8 mode_set = 0;
14431   unformat_input_t *input = vam->input;
14432   vl_api_lisp_eid_table_map_dump_t *mp;
14433   f64 timeout = ~0;
14434
14435   /* Parse args required to build the message */
14436   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14437     {
14438       if (unformat (input, "l2"))
14439         {
14440           is_l2 = 1;
14441           mode_set = 1;
14442         }
14443       else if (unformat (input, "l3"))
14444         {
14445           is_l2 = 0;
14446           mode_set = 1;
14447         }
14448       else
14449         {
14450           errmsg ("parse error '%U'", format_unformat_error, input);
14451           return -99;
14452         }
14453     }
14454
14455   if (!mode_set)
14456     {
14457       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
14458       return -99;
14459     }
14460
14461   if (!vam->json_output)
14462     {
14463       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
14464     }
14465
14466   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14467   mp->is_l2 = is_l2;
14468
14469   /* send it... */
14470   S;
14471
14472   /* Use a control ping for synchronization */
14473   {
14474     vl_api_control_ping_t *mp;
14475     M (CONTROL_PING, control_ping);
14476     S;
14477   }
14478   /* Wait for a reply... */
14479   W;
14480
14481   /* NOTREACHED */
14482   return 0;
14483 }
14484
14485 static int
14486 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14487 {
14488   vl_api_lisp_eid_table_vni_dump_t *mp;
14489   f64 timeout = ~0;
14490
14491   if (!vam->json_output)
14492     {
14493       fformat (vam->ofp, "VNI\n");
14494     }
14495
14496   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14497
14498   /* send it... */
14499   S;
14500
14501   /* Use a control ping for synchronization */
14502   {
14503     vl_api_control_ping_t *mp;
14504     M (CONTROL_PING, control_ping);
14505     S;
14506   }
14507   /* Wait for a reply... */
14508   W;
14509
14510   /* NOTREACHED */
14511   return 0;
14512 }
14513
14514 static int
14515 api_lisp_eid_table_dump (vat_main_t * vam)
14516 {
14517   unformat_input_t *i = vam->input;
14518   vl_api_lisp_eid_table_dump_t *mp;
14519   f64 timeout = ~0;
14520   struct in_addr ip4;
14521   struct in6_addr ip6;
14522   u8 mac[6];
14523   u8 eid_type = ~0, eid_set = 0;
14524   u32 prefix_length = ~0, t, vni = 0;
14525   u8 filter = 0;
14526
14527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14528     {
14529       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14530         {
14531           eid_set = 1;
14532           eid_type = 0;
14533           prefix_length = t;
14534         }
14535       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14536         {
14537           eid_set = 1;
14538           eid_type = 1;
14539           prefix_length = t;
14540         }
14541       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14542         {
14543           eid_set = 1;
14544           eid_type = 2;
14545         }
14546       else if (unformat (i, "vni %d", &t))
14547         {
14548           vni = t;
14549         }
14550       else if (unformat (i, "local"))
14551         {
14552           filter = 1;
14553         }
14554       else if (unformat (i, "remote"))
14555         {
14556           filter = 2;
14557         }
14558       else
14559         {
14560           errmsg ("parse error '%U'", format_unformat_error, i);
14561           return -99;
14562         }
14563     }
14564
14565   if (!vam->json_output)
14566     {
14567       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s\n", "EID",
14568                "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14569     }
14570
14571   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14572
14573   mp->filter = filter;
14574   if (eid_set)
14575     {
14576       mp->eid_set = 1;
14577       mp->vni = htonl (vni);
14578       mp->eid_type = eid_type;
14579       switch (eid_type)
14580         {
14581         case 0:
14582           mp->prefix_length = prefix_length;
14583           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14584           break;
14585         case 1:
14586           mp->prefix_length = prefix_length;
14587           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14588           break;
14589         case 2:
14590           clib_memcpy (mp->eid, mac, sizeof (mac));
14591           break;
14592         default:
14593           errmsg ("unknown EID type %d!", eid_type);
14594           return -99;
14595         }
14596     }
14597
14598   /* send it... */
14599   S;
14600
14601   /* Use a control ping for synchronization */
14602   {
14603     vl_api_control_ping_t *mp;
14604     M (CONTROL_PING, control_ping);
14605     S;
14606   }
14607
14608   /* Wait for a reply... */
14609   W;
14610
14611   /* NOTREACHED */
14612   return 0;
14613 }
14614
14615 static int
14616 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14617 {
14618   vl_api_lisp_gpe_tunnel_dump_t *mp;
14619   f64 timeout = ~0;
14620
14621   if (!vam->json_output)
14622     {
14623       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14624                "%=16s%=16s%=16s%=16s%=16s\n",
14625                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14626                "Decap next", "Lisp version", "Flags", "Next protocol",
14627                "ver_res", "res", "iid");
14628     }
14629
14630   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14631   /* send it... */
14632   S;
14633
14634   /* Use a control ping for synchronization */
14635   {
14636     vl_api_control_ping_t *mp;
14637     M (CONTROL_PING, control_ping);
14638     S;
14639   }
14640   /* Wait for a reply... */
14641   W;
14642
14643   /* NOTREACHED */
14644   return 0;
14645 }
14646
14647 static int
14648 api_lisp_adjacencies_get (vat_main_t * vam)
14649 {
14650   unformat_input_t *i = vam->input;
14651   vl_api_lisp_adjacencies_get_t *mp;
14652   f64 timeout = ~0;
14653   u8 vni_set = 0;
14654   u32 vni = ~0;
14655
14656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14657     {
14658       if (unformat (i, "vni %d", &vni))
14659         {
14660           vni_set = 1;
14661         }
14662       else
14663         {
14664           errmsg ("parse error '%U'\n", format_unformat_error, i);
14665           return -99;
14666         }
14667     }
14668
14669   if (!vni_set)
14670     {
14671       errmsg ("vni not set!\n");
14672       return -99;
14673     }
14674
14675   if (!vam->json_output)
14676     {
14677       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14678     }
14679
14680   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14681   mp->vni = clib_host_to_net_u32 (vni);
14682
14683   /* send it... */
14684   S;
14685
14686   /* Wait for a reply... */
14687   W;
14688
14689   /* NOTREACHED */
14690   return 0;
14691 }
14692
14693 static int
14694 api_lisp_map_server_dump (vat_main_t * vam)
14695 {
14696   vl_api_lisp_map_server_dump_t *mp;
14697   f64 timeout = ~0;
14698
14699   if (!vam->json_output)
14700     {
14701       fformat (vam->ofp, "%=20s\n", "Map server");
14702     }
14703
14704   M (LISP_MAP_SERVER_DUMP, lisp_map_server_dump);
14705   /* send it... */
14706   S;
14707
14708   /* Use a control ping for synchronization */
14709   {
14710     vl_api_control_ping_t *mp;
14711     M (CONTROL_PING, control_ping);
14712     S;
14713   }
14714   /* Wait for a reply... */
14715   W;
14716
14717   /* NOTREACHED */
14718   return 0;
14719 }
14720
14721 static int
14722 api_lisp_map_resolver_dump (vat_main_t * vam)
14723 {
14724   vl_api_lisp_map_resolver_dump_t *mp;
14725   f64 timeout = ~0;
14726
14727   if (!vam->json_output)
14728     {
14729       fformat (vam->ofp, "%=20s\n", "Map resolver");
14730     }
14731
14732   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14733   /* send it... */
14734   S;
14735
14736   /* Use a control ping for synchronization */
14737   {
14738     vl_api_control_ping_t *mp;
14739     M (CONTROL_PING, control_ping);
14740     S;
14741   }
14742   /* Wait for a reply... */
14743   W;
14744
14745   /* NOTREACHED */
14746   return 0;
14747 }
14748
14749 static int
14750 api_show_lisp_status (vat_main_t * vam)
14751 {
14752   vl_api_show_lisp_status_t *mp;
14753   f64 timeout = ~0;
14754
14755   if (!vam->json_output)
14756     {
14757       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14758     }
14759
14760   M (SHOW_LISP_STATUS, show_lisp_status);
14761   /* send it... */
14762   S;
14763   /* Wait for a reply... */
14764   W;
14765
14766   /* NOTREACHED */
14767   return 0;
14768 }
14769
14770 static int
14771 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14772 {
14773   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14774   f64 timeout = ~0;
14775
14776   if (!vam->json_output)
14777     {
14778       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14779     }
14780
14781   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14782   /* send it... */
14783   S;
14784   /* Wait for a reply... */
14785   W;
14786
14787   /* NOTREACHED */
14788   return 0;
14789 }
14790
14791 static int
14792 api_af_packet_create (vat_main_t * vam)
14793 {
14794   unformat_input_t *i = vam->input;
14795   vl_api_af_packet_create_t *mp;
14796   f64 timeout;
14797   u8 *host_if_name = 0;
14798   u8 hw_addr[6];
14799   u8 random_hw_addr = 1;
14800
14801   memset (hw_addr, 0, sizeof (hw_addr));
14802
14803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14804     {
14805       if (unformat (i, "name %s", &host_if_name))
14806         vec_add1 (host_if_name, 0);
14807       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14808         random_hw_addr = 0;
14809       else
14810         break;
14811     }
14812
14813   if (!vec_len (host_if_name))
14814     {
14815       errmsg ("host-interface name must be specified");
14816       return -99;
14817     }
14818
14819   if (vec_len (host_if_name) > 64)
14820     {
14821       errmsg ("host-interface name too long");
14822       return -99;
14823     }
14824
14825   M (AF_PACKET_CREATE, af_packet_create);
14826
14827   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14828   clib_memcpy (mp->hw_addr, hw_addr, 6);
14829   mp->use_random_hw_addr = random_hw_addr;
14830   vec_free (host_if_name);
14831
14832   S;
14833   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14834   /* NOTREACHED */
14835   return 0;
14836 }
14837
14838 static int
14839 api_af_packet_delete (vat_main_t * vam)
14840 {
14841   unformat_input_t *i = vam->input;
14842   vl_api_af_packet_delete_t *mp;
14843   f64 timeout;
14844   u8 *host_if_name = 0;
14845
14846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14847     {
14848       if (unformat (i, "name %s", &host_if_name))
14849         vec_add1 (host_if_name, 0);
14850       else
14851         break;
14852     }
14853
14854   if (!vec_len (host_if_name))
14855     {
14856       errmsg ("host-interface name must be specified");
14857       return -99;
14858     }
14859
14860   if (vec_len (host_if_name) > 64)
14861     {
14862       errmsg ("host-interface name too long");
14863       return -99;
14864     }
14865
14866   M (AF_PACKET_DELETE, af_packet_delete);
14867
14868   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14869   vec_free (host_if_name);
14870
14871   S;
14872   W;
14873   /* NOTREACHED */
14874   return 0;
14875 }
14876
14877 static int
14878 api_policer_add_del (vat_main_t * vam)
14879 {
14880   unformat_input_t *i = vam->input;
14881   vl_api_policer_add_del_t *mp;
14882   f64 timeout;
14883   u8 is_add = 1;
14884   u8 *name = 0;
14885   u32 cir = 0;
14886   u32 eir = 0;
14887   u64 cb = 0;
14888   u64 eb = 0;
14889   u8 rate_type = 0;
14890   u8 round_type = 0;
14891   u8 type = 0;
14892   u8 color_aware = 0;
14893   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14894
14895   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14896   conform_action.dscp = 0;
14897   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14898   exceed_action.dscp = 0;
14899   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14900   violate_action.dscp = 0;
14901
14902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14903     {
14904       if (unformat (i, "del"))
14905         is_add = 0;
14906       else if (unformat (i, "name %s", &name))
14907         vec_add1 (name, 0);
14908       else if (unformat (i, "cir %u", &cir))
14909         ;
14910       else if (unformat (i, "eir %u", &eir))
14911         ;
14912       else if (unformat (i, "cb %u", &cb))
14913         ;
14914       else if (unformat (i, "eb %u", &eb))
14915         ;
14916       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14917                          &rate_type))
14918         ;
14919       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14920                          &round_type))
14921         ;
14922       else if (unformat (i, "type %U", unformat_policer_type, &type))
14923         ;
14924       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14925                          &conform_action))
14926         ;
14927       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14928                          &exceed_action))
14929         ;
14930       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14931                          &violate_action))
14932         ;
14933       else if (unformat (i, "color-aware"))
14934         color_aware = 1;
14935       else
14936         break;
14937     }
14938
14939   if (!vec_len (name))
14940     {
14941       errmsg ("policer name must be specified");
14942       return -99;
14943     }
14944
14945   if (vec_len (name) > 64)
14946     {
14947       errmsg ("policer name too long");
14948       return -99;
14949     }
14950
14951   M (POLICER_ADD_DEL, policer_add_del);
14952
14953   clib_memcpy (mp->name, name, vec_len (name));
14954   vec_free (name);
14955   mp->is_add = is_add;
14956   mp->cir = cir;
14957   mp->eir = eir;
14958   mp->cb = cb;
14959   mp->eb = eb;
14960   mp->rate_type = rate_type;
14961   mp->round_type = round_type;
14962   mp->type = type;
14963   mp->conform_action_type = conform_action.action_type;
14964   mp->conform_dscp = conform_action.dscp;
14965   mp->exceed_action_type = exceed_action.action_type;
14966   mp->exceed_dscp = exceed_action.dscp;
14967   mp->violate_action_type = violate_action.action_type;
14968   mp->violate_dscp = violate_action.dscp;
14969   mp->color_aware = color_aware;
14970
14971   S;
14972   W;
14973   /* NOTREACHED */
14974   return 0;
14975 }
14976
14977 static int
14978 api_policer_dump (vat_main_t * vam)
14979 {
14980   unformat_input_t *i = vam->input;
14981   vl_api_policer_dump_t *mp;
14982   f64 timeout = ~0;
14983   u8 *match_name = 0;
14984   u8 match_name_valid = 0;
14985
14986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14987     {
14988       if (unformat (i, "name %s", &match_name))
14989         {
14990           vec_add1 (match_name, 0);
14991           match_name_valid = 1;
14992         }
14993       else
14994         break;
14995     }
14996
14997   M (POLICER_DUMP, policer_dump);
14998   mp->match_name_valid = match_name_valid;
14999   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15000   vec_free (match_name);
15001   /* send it... */
15002   S;
15003
15004   /* Use a control ping for synchronization */
15005   {
15006     vl_api_control_ping_t *mp;
15007     M (CONTROL_PING, control_ping);
15008     S;
15009   }
15010   /* Wait for a reply... */
15011   W;
15012
15013   /* NOTREACHED */
15014   return 0;
15015 }
15016
15017 static int
15018 api_policer_classify_set_interface (vat_main_t * vam)
15019 {
15020   unformat_input_t *i = vam->input;
15021   vl_api_policer_classify_set_interface_t *mp;
15022   f64 timeout;
15023   u32 sw_if_index;
15024   int sw_if_index_set;
15025   u32 ip4_table_index = ~0;
15026   u32 ip6_table_index = ~0;
15027   u32 l2_table_index = ~0;
15028   u8 is_add = 1;
15029
15030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15031     {
15032       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15033         sw_if_index_set = 1;
15034       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15035         sw_if_index_set = 1;
15036       else if (unformat (i, "del"))
15037         is_add = 0;
15038       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15039         ;
15040       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15041         ;
15042       else if (unformat (i, "l2-table %d", &l2_table_index))
15043         ;
15044       else
15045         {
15046           clib_warning ("parse error '%U'", format_unformat_error, i);
15047           return -99;
15048         }
15049     }
15050
15051   if (sw_if_index_set == 0)
15052     {
15053       errmsg ("missing interface name or sw_if_index\n");
15054       return -99;
15055     }
15056
15057   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
15058
15059   mp->sw_if_index = ntohl (sw_if_index);
15060   mp->ip4_table_index = ntohl (ip4_table_index);
15061   mp->ip6_table_index = ntohl (ip6_table_index);
15062   mp->l2_table_index = ntohl (l2_table_index);
15063   mp->is_add = is_add;
15064
15065   S;
15066   W;
15067   /* NOTREACHED */
15068   return 0;
15069 }
15070
15071 static int
15072 api_policer_classify_dump (vat_main_t * vam)
15073 {
15074   unformat_input_t *i = vam->input;
15075   vl_api_policer_classify_dump_t *mp;
15076   f64 timeout = ~0;
15077   u8 type = POLICER_CLASSIFY_N_TABLES;
15078
15079   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15080     ;
15081   else
15082     {
15083       errmsg ("classify table type must be specified\n");
15084       return -99;
15085     }
15086
15087   if (!vam->json_output)
15088     {
15089       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
15090     }
15091
15092   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
15093   mp->type = type;
15094   /* send it... */
15095   S;
15096
15097   /* Use a control ping for synchronization */
15098   {
15099     vl_api_control_ping_t *mp;
15100     M (CONTROL_PING, control_ping);
15101     S;
15102   }
15103   /* Wait for a reply... */
15104   W;
15105
15106   /* NOTREACHED */
15107   return 0;
15108 }
15109
15110 static int
15111 api_netmap_create (vat_main_t * vam)
15112 {
15113   unformat_input_t *i = vam->input;
15114   vl_api_netmap_create_t *mp;
15115   f64 timeout;
15116   u8 *if_name = 0;
15117   u8 hw_addr[6];
15118   u8 random_hw_addr = 1;
15119   u8 is_pipe = 0;
15120   u8 is_master = 0;
15121
15122   memset (hw_addr, 0, sizeof (hw_addr));
15123
15124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15125     {
15126       if (unformat (i, "name %s", &if_name))
15127         vec_add1 (if_name, 0);
15128       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15129         random_hw_addr = 0;
15130       else if (unformat (i, "pipe"))
15131         is_pipe = 1;
15132       else if (unformat (i, "master"))
15133         is_master = 1;
15134       else if (unformat (i, "slave"))
15135         is_master = 0;
15136       else
15137         break;
15138     }
15139
15140   if (!vec_len (if_name))
15141     {
15142       errmsg ("interface name must be specified");
15143       return -99;
15144     }
15145
15146   if (vec_len (if_name) > 64)
15147     {
15148       errmsg ("interface name too long");
15149       return -99;
15150     }
15151
15152   M (NETMAP_CREATE, netmap_create);
15153
15154   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15155   clib_memcpy (mp->hw_addr, hw_addr, 6);
15156   mp->use_random_hw_addr = random_hw_addr;
15157   mp->is_pipe = is_pipe;
15158   mp->is_master = is_master;
15159   vec_free (if_name);
15160
15161   S;
15162   W;
15163   /* NOTREACHED */
15164   return 0;
15165 }
15166
15167 static int
15168 api_netmap_delete (vat_main_t * vam)
15169 {
15170   unformat_input_t *i = vam->input;
15171   vl_api_netmap_delete_t *mp;
15172   f64 timeout;
15173   u8 *if_name = 0;
15174
15175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15176     {
15177       if (unformat (i, "name %s", &if_name))
15178         vec_add1 (if_name, 0);
15179       else
15180         break;
15181     }
15182
15183   if (!vec_len (if_name))
15184     {
15185       errmsg ("interface name must be specified");
15186       return -99;
15187     }
15188
15189   if (vec_len (if_name) > 64)
15190     {
15191       errmsg ("interface name too long");
15192       return -99;
15193     }
15194
15195   M (NETMAP_DELETE, netmap_delete);
15196
15197   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15198   vec_free (if_name);
15199
15200   S;
15201   W;
15202   /* NOTREACHED */
15203   return 0;
15204 }
15205
15206 static void vl_api_mpls_tunnel_details_t_handler
15207   (vl_api_mpls_tunnel_details_t * mp)
15208 {
15209   vat_main_t *vam = &vat_main;
15210   i32 len = mp->mt_next_hop_n_labels;
15211   i32 i;
15212
15213   fformat (vam->ofp, "[%d]: via %U %d labels ",
15214            mp->tunnel_index,
15215            format_ip4_address, mp->mt_next_hop,
15216            ntohl (mp->mt_next_hop_sw_if_index));
15217   for (i = 0; i < len; i++)
15218     {
15219       fformat (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15220     }
15221   fformat (vam->ofp, "\n");
15222 }
15223
15224 static void vl_api_mpls_tunnel_details_t_handler_json
15225   (vl_api_mpls_tunnel_details_t * mp)
15226 {
15227   vat_main_t *vam = &vat_main;
15228   vat_json_node_t *node = NULL;
15229   struct in_addr ip4;
15230   i32 i;
15231   i32 len = mp->mt_next_hop_n_labels;
15232
15233   if (VAT_JSON_ARRAY != vam->json_tree.type)
15234     {
15235       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15236       vat_json_init_array (&vam->json_tree);
15237     }
15238   node = vat_json_array_add (&vam->json_tree);
15239
15240   vat_json_init_object (node);
15241   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15242   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15243   vat_json_object_add_ip4 (node, "next_hop", ip4);
15244   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15245                             ntohl (mp->mt_next_hop_sw_if_index));
15246   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15247   vat_json_object_add_uint (node, "label_count", len);
15248   for (i = 0; i < len; i++)
15249     {
15250       vat_json_object_add_uint (node, "label",
15251                                 ntohl (mp->mt_next_hop_out_labels[i]));
15252     }
15253 }
15254
15255 static int
15256 api_mpls_tunnel_dump (vat_main_t * vam)
15257 {
15258   vl_api_mpls_tunnel_dump_t *mp;
15259   f64 timeout;
15260   i32 index = -1;
15261
15262   /* Parse args required to build the message */
15263   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15264     {
15265       if (!unformat (vam->input, "tunnel_index %d", &index))
15266         {
15267           index = -1;
15268           break;
15269         }
15270     }
15271
15272   fformat (vam->ofp, "  tunnel_index %d\n", index);
15273
15274   M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
15275   mp->tunnel_index = htonl (index);
15276   S;
15277
15278   /* Use a control ping for synchronization */
15279   {
15280     vl_api_control_ping_t *mp;
15281     M (CONTROL_PING, control_ping);
15282     S;
15283   }
15284   W;
15285 }
15286
15287 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15288 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15289
15290 static void
15291 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15292 {
15293   vat_main_t *vam = &vat_main;
15294   int count = ntohl (mp->count);
15295   vl_api_fib_path2_t *fp;
15296   int i;
15297
15298   fformat (vam->ofp,
15299            "table-id %d, label %u, ess_bit %u\n",
15300            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15301   fp = mp->path;
15302   for (i = 0; i < count; i++)
15303     {
15304       if (fp->afi == IP46_TYPE_IP6)
15305         fformat (vam->ofp,
15306                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15307                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15308                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15309                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15310                  format_ip6_address, fp->next_hop);
15311       else if (fp->afi == IP46_TYPE_IP4)
15312         fformat (vam->ofp,
15313                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15314                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15315                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15316                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15317                  format_ip4_address, fp->next_hop);
15318       fp++;
15319     }
15320 }
15321
15322 static void vl_api_mpls_fib_details_t_handler_json
15323   (vl_api_mpls_fib_details_t * mp)
15324 {
15325   vat_main_t *vam = &vat_main;
15326   int count = ntohl (mp->count);
15327   vat_json_node_t *node = NULL;
15328   struct in_addr ip4;
15329   struct in6_addr ip6;
15330   vl_api_fib_path2_t *fp;
15331   int i;
15332
15333   if (VAT_JSON_ARRAY != vam->json_tree.type)
15334     {
15335       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15336       vat_json_init_array (&vam->json_tree);
15337     }
15338   node = vat_json_array_add (&vam->json_tree);
15339
15340   vat_json_init_object (node);
15341   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15342   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15343   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15344   vat_json_object_add_uint (node, "path_count", count);
15345   fp = mp->path;
15346   for (i = 0; i < count; i++)
15347     {
15348       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15349       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15350       vat_json_object_add_uint (node, "is_local", fp->is_local);
15351       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15352       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15353       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15354       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15355       if (fp->afi == IP46_TYPE_IP4)
15356         {
15357           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15358           vat_json_object_add_ip4 (node, "next_hop", ip4);
15359         }
15360       else if (fp->afi == IP46_TYPE_IP6)
15361         {
15362           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15363           vat_json_object_add_ip6 (node, "next_hop", ip6);
15364         }
15365     }
15366 }
15367
15368 static int
15369 api_mpls_fib_dump (vat_main_t * vam)
15370 {
15371   vl_api_mpls_fib_dump_t *mp;
15372   f64 timeout;
15373
15374   M (MPLS_FIB_DUMP, mpls_fib_dump);
15375   S;
15376
15377   /* Use a control ping for synchronization */
15378   {
15379     vl_api_control_ping_t *mp;
15380     M (CONTROL_PING, control_ping);
15381     S;
15382   }
15383   W;
15384 }
15385
15386 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15387 #define vl_api_ip_fib_details_t_print vl_noop_handler
15388
15389 static void
15390 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15391 {
15392   vat_main_t *vam = &vat_main;
15393   int count = ntohl (mp->count);
15394   vl_api_fib_path_t *fp;
15395   int i;
15396
15397   fformat (vam->ofp,
15398            "table-id %d, prefix %U/%d\n",
15399            ntohl (mp->table_id), format_ip4_address, mp->address,
15400            mp->address_length);
15401   fp = mp->path;
15402   for (i = 0; i < count; i++)
15403     {
15404       if (fp->afi == IP46_TYPE_IP6)
15405         fformat (vam->ofp,
15406                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15407                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15408                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15409                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15410                  format_ip6_address, fp->next_hop);
15411       else if (fp->afi == IP46_TYPE_IP4)
15412         fformat (vam->ofp,
15413                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15414                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15415                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15416                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15417                  format_ip4_address, fp->next_hop);
15418       fp++;
15419     }
15420 }
15421
15422 static void vl_api_ip_fib_details_t_handler_json
15423   (vl_api_ip_fib_details_t * mp)
15424 {
15425   vat_main_t *vam = &vat_main;
15426   int count = ntohl (mp->count);
15427   vat_json_node_t *node = NULL;
15428   struct in_addr ip4;
15429   struct in6_addr ip6;
15430   vl_api_fib_path_t *fp;
15431   int i;
15432
15433   if (VAT_JSON_ARRAY != vam->json_tree.type)
15434     {
15435       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15436       vat_json_init_array (&vam->json_tree);
15437     }
15438   node = vat_json_array_add (&vam->json_tree);
15439
15440   vat_json_init_object (node);
15441   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15442   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15443   vat_json_object_add_ip4 (node, "prefix", ip4);
15444   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15445   vat_json_object_add_uint (node, "path_count", count);
15446   fp = mp->path;
15447   for (i = 0; i < count; i++)
15448     {
15449       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15450       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15451       vat_json_object_add_uint (node, "is_local", fp->is_local);
15452       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15453       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15454       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15455       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15456       if (fp->afi == IP46_TYPE_IP4)
15457         {
15458           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15459           vat_json_object_add_ip4 (node, "next_hop", ip4);
15460         }
15461       else if (fp->afi == IP46_TYPE_IP6)
15462         {
15463           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15464           vat_json_object_add_ip6 (node, "next_hop", ip6);
15465         }
15466     }
15467 }
15468
15469 static int
15470 api_ip_fib_dump (vat_main_t * vam)
15471 {
15472   vl_api_ip_fib_dump_t *mp;
15473   f64 timeout;
15474
15475   M (IP_FIB_DUMP, ip_fib_dump);
15476   S;
15477
15478   /* Use a control ping for synchronization */
15479   {
15480     vl_api_control_ping_t *mp;
15481     M (CONTROL_PING, control_ping);
15482     S;
15483   }
15484   W;
15485 }
15486
15487 static void vl_api_ip_neighbor_details_t_handler
15488   (vl_api_ip_neighbor_details_t * mp)
15489 {
15490   vat_main_t *vam = &vat_main;
15491
15492   fformat (vam->ofp, "%c %U %U\n",
15493            (mp->is_static) ? 'S' : 'D',
15494            format_ethernet_address, &mp->mac_address,
15495            (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15496            &mp->ip_address);
15497 }
15498
15499 static void vl_api_ip_neighbor_details_t_handler_json
15500   (vl_api_ip_neighbor_details_t * mp)
15501 {
15502
15503   vat_main_t *vam = &vat_main;
15504   vat_json_node_t *node;
15505   struct in_addr ip4;
15506   struct in6_addr ip6;
15507
15508   if (VAT_JSON_ARRAY != vam->json_tree.type)
15509     {
15510       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15511       vat_json_init_array (&vam->json_tree);
15512     }
15513   node = vat_json_array_add (&vam->json_tree);
15514
15515   vat_json_init_object (node);
15516   vat_json_object_add_string_copy (node, "flag",
15517                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15518                                    "dynamic");
15519
15520   vat_json_object_add_string_copy (node, "link_layer",
15521                                    format (0, "%U", format_ethernet_address,
15522                                            &mp->mac_address));
15523
15524   if (mp->is_ipv6)
15525     {
15526       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15527       vat_json_object_add_ip6 (node, "ip_address", ip6);
15528     }
15529   else
15530     {
15531       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15532       vat_json_object_add_ip4 (node, "ip_address", ip4);
15533     }
15534 }
15535
15536 static int
15537 api_ip_neighbor_dump (vat_main_t * vam)
15538 {
15539   unformat_input_t *i = vam->input;
15540   vl_api_ip_neighbor_dump_t *mp;
15541   f64 timeout;
15542   u8 is_ipv6 = 0;
15543   u32 sw_if_index = ~0;
15544
15545   /* Parse args required to build the message */
15546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15547     {
15548       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15549         ;
15550       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15551         ;
15552       else if (unformat (i, "ip6"))
15553         is_ipv6 = 1;
15554       else
15555         break;
15556     }
15557
15558   if (sw_if_index == ~0)
15559     {
15560       errmsg ("missing interface name or sw_if_index\n");
15561       return -99;
15562     }
15563
15564   M (IP_NEIGHBOR_DUMP, ip_neighbor_dump);
15565   mp->is_ipv6 = (u8) is_ipv6;
15566   mp->sw_if_index = ntohl (sw_if_index);
15567   S;
15568
15569   /* Use a control ping for synchronization */
15570   {
15571     vl_api_control_ping_t *mp;
15572     M (CONTROL_PING, control_ping);
15573     S;
15574   }
15575   W;
15576 }
15577
15578 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15579 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15580
15581 static void
15582 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15583 {
15584   vat_main_t *vam = &vat_main;
15585   int count = ntohl (mp->count);
15586   vl_api_fib_path_t *fp;
15587   int i;
15588
15589   fformat (vam->ofp,
15590            "table-id %d, prefix %U/%d\n",
15591            ntohl (mp->table_id), format_ip6_address, mp->address,
15592            mp->address_length);
15593   fp = mp->path;
15594   for (i = 0; i < count; i++)
15595     {
15596       if (fp->afi == IP46_TYPE_IP6)
15597         fformat (vam->ofp,
15598                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15599                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15600                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15601                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15602                  format_ip6_address, fp->next_hop);
15603       else if (fp->afi == IP46_TYPE_IP4)
15604         fformat (vam->ofp,
15605                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15606                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15607                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15608                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15609                  format_ip4_address, fp->next_hop);
15610       fp++;
15611     }
15612 }
15613
15614 static void vl_api_ip6_fib_details_t_handler_json
15615   (vl_api_ip6_fib_details_t * mp)
15616 {
15617   vat_main_t *vam = &vat_main;
15618   int count = ntohl (mp->count);
15619   vat_json_node_t *node = NULL;
15620   struct in_addr ip4;
15621   struct in6_addr ip6;
15622   vl_api_fib_path_t *fp;
15623   int i;
15624
15625   if (VAT_JSON_ARRAY != vam->json_tree.type)
15626     {
15627       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15628       vat_json_init_array (&vam->json_tree);
15629     }
15630   node = vat_json_array_add (&vam->json_tree);
15631
15632   vat_json_init_object (node);
15633   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15634   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15635   vat_json_object_add_ip6 (node, "prefix", ip6);
15636   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15637   vat_json_object_add_uint (node, "path_count", count);
15638   fp = mp->path;
15639   for (i = 0; i < count; i++)
15640     {
15641       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15642       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15643       vat_json_object_add_uint (node, "is_local", fp->is_local);
15644       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15645       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15646       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15647       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15648       if (fp->afi == IP46_TYPE_IP4)
15649         {
15650           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15651           vat_json_object_add_ip4 (node, "next_hop", ip4);
15652         }
15653       else if (fp->afi == IP46_TYPE_IP6)
15654         {
15655           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15656           vat_json_object_add_ip6 (node, "next_hop", ip6);
15657         }
15658     }
15659 }
15660
15661 static int
15662 api_ip6_fib_dump (vat_main_t * vam)
15663 {
15664   vl_api_ip6_fib_dump_t *mp;
15665   f64 timeout;
15666
15667   M (IP6_FIB_DUMP, ip6_fib_dump);
15668   S;
15669
15670   /* Use a control ping for synchronization */
15671   {
15672     vl_api_control_ping_t *mp;
15673     M (CONTROL_PING, control_ping);
15674     S;
15675   }
15676   W;
15677 }
15678
15679 int
15680 api_classify_table_ids (vat_main_t * vam)
15681 {
15682   vl_api_classify_table_ids_t *mp;
15683   f64 timeout;
15684
15685   /* Construct the API message */
15686   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15687   mp->context = 0;
15688
15689   S;
15690   W;
15691   /* NOTREACHED */
15692   return 0;
15693 }
15694
15695 int
15696 api_classify_table_by_interface (vat_main_t * vam)
15697 {
15698   unformat_input_t *input = vam->input;
15699   vl_api_classify_table_by_interface_t *mp;
15700   f64 timeout;
15701
15702   u32 sw_if_index = ~0;
15703   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15704     {
15705       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15706         ;
15707       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15708         ;
15709       else
15710         break;
15711     }
15712   if (sw_if_index == ~0)
15713     {
15714       errmsg ("missing interface name or sw_if_index\n");
15715       return -99;
15716     }
15717
15718   /* Construct the API message */
15719   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15720   mp->context = 0;
15721   mp->sw_if_index = ntohl (sw_if_index);
15722
15723   S;
15724   W;
15725   /* NOTREACHED */
15726   return 0;
15727 }
15728
15729 int
15730 api_classify_table_info (vat_main_t * vam)
15731 {
15732   unformat_input_t *input = vam->input;
15733   vl_api_classify_table_info_t *mp;
15734   f64 timeout;
15735
15736   u32 table_id = ~0;
15737   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15738     {
15739       if (unformat (input, "table_id %d", &table_id))
15740         ;
15741       else
15742         break;
15743     }
15744   if (table_id == ~0)
15745     {
15746       errmsg ("missing table id\n");
15747       return -99;
15748     }
15749
15750   /* Construct the API message */
15751   M (CLASSIFY_TABLE_INFO, classify_table_info);
15752   mp->context = 0;
15753   mp->table_id = ntohl (table_id);
15754
15755   S;
15756   W;
15757   /* NOTREACHED */
15758   return 0;
15759 }
15760
15761 int
15762 api_classify_session_dump (vat_main_t * vam)
15763 {
15764   unformat_input_t *input = vam->input;
15765   vl_api_classify_session_dump_t *mp;
15766   f64 timeout;
15767
15768   u32 table_id = ~0;
15769   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15770     {
15771       if (unformat (input, "table_id %d", &table_id))
15772         ;
15773       else
15774         break;
15775     }
15776   if (table_id == ~0)
15777     {
15778       errmsg ("missing table id\n");
15779       return -99;
15780     }
15781
15782   /* Construct the API message */
15783   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15784   mp->context = 0;
15785   mp->table_id = ntohl (table_id);
15786   S;
15787
15788   /* Use a control ping for synchronization */
15789   {
15790     vl_api_control_ping_t *mp;
15791     M (CONTROL_PING, control_ping);
15792     S;
15793   }
15794   W;
15795   /* NOTREACHED */
15796   return 0;
15797 }
15798
15799 static void
15800 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15801 {
15802   vat_main_t *vam = &vat_main;
15803
15804   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15805            "src_address %U, vrf_id %d, path_mtu %u, "
15806            "template_interval %u, udp_checksum %d\n",
15807            format_ip4_address, mp->collector_address,
15808            ntohs (mp->collector_port),
15809            format_ip4_address, mp->src_address,
15810            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15811            ntohl (mp->template_interval), mp->udp_checksum);
15812
15813   vam->retval = 0;
15814   vam->result_ready = 1;
15815 }
15816
15817 static void
15818   vl_api_ipfix_exporter_details_t_handler_json
15819   (vl_api_ipfix_exporter_details_t * mp)
15820 {
15821   vat_main_t *vam = &vat_main;
15822   vat_json_node_t node;
15823   struct in_addr collector_address;
15824   struct in_addr src_address;
15825
15826   vat_json_init_object (&node);
15827   clib_memcpy (&collector_address, &mp->collector_address,
15828                sizeof (collector_address));
15829   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15830   vat_json_object_add_uint (&node, "collector_port",
15831                             ntohs (mp->collector_port));
15832   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15833   vat_json_object_add_ip4 (&node, "src_address", src_address);
15834   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15835   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15836   vat_json_object_add_uint (&node, "template_interval",
15837                             ntohl (mp->template_interval));
15838   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15839
15840   vat_json_print (vam->ofp, &node);
15841   vat_json_free (&node);
15842   vam->retval = 0;
15843   vam->result_ready = 1;
15844 }
15845
15846 int
15847 api_ipfix_exporter_dump (vat_main_t * vam)
15848 {
15849   vl_api_ipfix_exporter_dump_t *mp;
15850   f64 timeout;
15851
15852   /* Construct the API message */
15853   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15854   mp->context = 0;
15855
15856   S;
15857   W;
15858   /* NOTREACHED */
15859   return 0;
15860 }
15861
15862 static int
15863 api_ipfix_classify_stream_dump (vat_main_t * vam)
15864 {
15865   vl_api_ipfix_classify_stream_dump_t *mp;
15866   f64 timeout;
15867
15868   /* Construct the API message */
15869   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15870   mp->context = 0;
15871
15872   S;
15873   W;
15874   /* NOTREACHED */
15875   return 0;
15876 }
15877
15878 static void
15879   vl_api_ipfix_classify_stream_details_t_handler
15880   (vl_api_ipfix_classify_stream_details_t * mp)
15881 {
15882   vat_main_t *vam = &vat_main;
15883   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15884            ntohl (mp->domain_id), ntohs (mp->src_port));
15885   vam->retval = 0;
15886   vam->result_ready = 1;
15887 }
15888
15889 static void
15890   vl_api_ipfix_classify_stream_details_t_handler_json
15891   (vl_api_ipfix_classify_stream_details_t * mp)
15892 {
15893   vat_main_t *vam = &vat_main;
15894   vat_json_node_t node;
15895
15896   vat_json_init_object (&node);
15897   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15898   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15899
15900   vat_json_print (vam->ofp, &node);
15901   vat_json_free (&node);
15902   vam->retval = 0;
15903   vam->result_ready = 1;
15904 }
15905
15906 static int
15907 api_ipfix_classify_table_dump (vat_main_t * vam)
15908 {
15909   vl_api_ipfix_classify_table_dump_t *mp;
15910   f64 timeout;
15911
15912   if (!vam->json_output)
15913     {
15914       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15915                "transport_protocol");
15916     }
15917
15918   /* Construct the API message */
15919   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15920
15921   /* send it... */
15922   S;
15923
15924   /* Use a control ping for synchronization */
15925   {
15926     vl_api_control_ping_t *mp;
15927     M (CONTROL_PING, control_ping);
15928     S;
15929   }
15930   W;
15931 }
15932
15933 static void
15934   vl_api_ipfix_classify_table_details_t_handler
15935   (vl_api_ipfix_classify_table_details_t * mp)
15936 {
15937   vat_main_t *vam = &vat_main;
15938   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15939            mp->transport_protocol);
15940 }
15941
15942 static void
15943   vl_api_ipfix_classify_table_details_t_handler_json
15944   (vl_api_ipfix_classify_table_details_t * mp)
15945 {
15946   vat_json_node_t *node = NULL;
15947   vat_main_t *vam = &vat_main;
15948
15949   if (VAT_JSON_ARRAY != vam->json_tree.type)
15950     {
15951       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15952       vat_json_init_array (&vam->json_tree);
15953     }
15954
15955   node = vat_json_array_add (&vam->json_tree);
15956   vat_json_init_object (node);
15957
15958   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15959   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15960   vat_json_object_add_uint (node, "transport_protocol",
15961                             mp->transport_protocol);
15962 }
15963
15964 static int
15965 api_sw_interface_span_enable_disable (vat_main_t * vam)
15966 {
15967   unformat_input_t *i = vam->input;
15968   vl_api_sw_interface_span_enable_disable_t *mp;
15969   f64 timeout;
15970   u32 src_sw_if_index = ~0;
15971   u32 dst_sw_if_index = ~0;
15972   u8 state = 3;
15973
15974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15975     {
15976       if (unformat (i, "src %U", unformat_sw_if_index, vam, &src_sw_if_index))
15977         ;
15978       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15979         ;
15980       else
15981         if (unformat
15982             (i, "dst %U", unformat_sw_if_index, vam, &dst_sw_if_index))
15983         ;
15984       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15985         ;
15986       else if (unformat (i, "disable"))
15987         state = 0;
15988       else if (unformat (i, "rx"))
15989         state = 1;
15990       else if (unformat (i, "tx"))
15991         state = 2;
15992       else if (unformat (i, "both"))
15993         state = 3;
15994       else
15995         break;
15996     }
15997
15998   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
15999
16000   mp->sw_if_index_from = htonl (src_sw_if_index);
16001   mp->sw_if_index_to = htonl (dst_sw_if_index);
16002   mp->state = state;
16003
16004   S;
16005   W;
16006   /* NOTREACHED */
16007   return 0;
16008 }
16009
16010 static void
16011 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16012                                             * mp)
16013 {
16014   vat_main_t *vam = &vat_main;
16015   u8 *sw_if_from_name = 0;
16016   u8 *sw_if_to_name = 0;
16017   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16018   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16019   char *states[] = { "none", "rx", "tx", "both" };
16020   hash_pair_t *p;
16021
16022   /* *INDENT-OFF* */
16023   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16024   ({
16025     if ((u32) p->value[0] == sw_if_index_from)
16026       {
16027         sw_if_from_name = (u8 *)(p->key);
16028         if (sw_if_to_name)
16029           break;
16030       }
16031     if ((u32) p->value[0] == sw_if_index_to)
16032       {
16033         sw_if_to_name = (u8 *)(p->key);
16034         if (sw_if_from_name)
16035           break;
16036       }
16037   }));
16038   /* *INDENT-ON* */
16039   fformat (vam->ofp, "%20s => %20s (%s)\n",
16040            sw_if_from_name, sw_if_to_name, states[mp->state]);
16041 }
16042
16043 static void
16044   vl_api_sw_interface_span_details_t_handler_json
16045   (vl_api_sw_interface_span_details_t * mp)
16046 {
16047   vat_main_t *vam = &vat_main;
16048   vat_json_node_t *node = NULL;
16049   u8 *sw_if_from_name = 0;
16050   u8 *sw_if_to_name = 0;
16051   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16052   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16053   hash_pair_t *p;
16054
16055   /* *INDENT-OFF* */
16056   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16057   ({
16058     if ((u32) p->value[0] == sw_if_index_from)
16059       {
16060         sw_if_from_name = (u8 *)(p->key);
16061         if (sw_if_to_name)
16062           break;
16063       }
16064     if ((u32) p->value[0] == sw_if_index_to)
16065       {
16066         sw_if_to_name = (u8 *)(p->key);
16067         if (sw_if_from_name)
16068           break;
16069       }
16070   }));
16071   /* *INDENT-ON* */
16072
16073   if (VAT_JSON_ARRAY != vam->json_tree.type)
16074     {
16075       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16076       vat_json_init_array (&vam->json_tree);
16077     }
16078   node = vat_json_array_add (&vam->json_tree);
16079
16080   vat_json_init_object (node);
16081   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16082   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16083   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16084   vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16085   vat_json_object_add_uint (node, "state", mp->state);
16086 }
16087
16088 static int
16089 api_sw_interface_span_dump (vat_main_t * vam)
16090 {
16091   vl_api_sw_interface_span_dump_t *mp;
16092   f64 timeout;
16093
16094   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
16095   S;
16096
16097   /* Use a control ping for synchronization */
16098   {
16099     vl_api_control_ping_t *mp;
16100     M (CONTROL_PING, control_ping);
16101     S;
16102   }
16103   W;
16104 }
16105
16106 int
16107 api_pg_create_interface (vat_main_t * vam)
16108 {
16109   unformat_input_t *input = vam->input;
16110   vl_api_pg_create_interface_t *mp;
16111   f64 timeout;
16112
16113   u32 if_id = ~0;
16114   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16115     {
16116       if (unformat (input, "if_id %d", &if_id))
16117         ;
16118       else
16119         break;
16120     }
16121   if (if_id == ~0)
16122     {
16123       errmsg ("missing pg interface index\n");
16124       return -99;
16125     }
16126
16127   /* Construct the API message */
16128   M (PG_CREATE_INTERFACE, pg_create_interface);
16129   mp->context = 0;
16130   mp->interface_id = ntohl (if_id);
16131
16132   S;
16133   W;
16134   /* NOTREACHED */
16135   return 0;
16136 }
16137
16138 int
16139 api_pg_capture (vat_main_t * vam)
16140 {
16141   unformat_input_t *input = vam->input;
16142   vl_api_pg_capture_t *mp;
16143   f64 timeout;
16144
16145   u32 if_id = ~0;
16146   u8 enable = 1;
16147   u32 count = 1;
16148   u8 pcap_file_set = 0;
16149   u8 *pcap_file = 0;
16150   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16151     {
16152       if (unformat (input, "if_id %d", &if_id))
16153         ;
16154       else if (unformat (input, "pcap %s", &pcap_file))
16155         pcap_file_set = 1;
16156       else if (unformat (input, "count %d", &count))
16157         ;
16158       else if (unformat (input, "disable"))
16159         enable = 0;
16160       else
16161         break;
16162     }
16163   if (if_id == ~0)
16164     {
16165       errmsg ("missing pg interface index\n");
16166       return -99;
16167     }
16168   if (pcap_file_set > 0)
16169     {
16170       if (vec_len (pcap_file) > 255)
16171         {
16172           errmsg ("pcap file name is too long\n");
16173           return -99;
16174         }
16175     }
16176
16177   u32 name_len = vec_len (pcap_file);
16178   /* Construct the API message */
16179   M (PG_CAPTURE, pg_capture);
16180   mp->context = 0;
16181   mp->interface_id = ntohl (if_id);
16182   mp->is_enabled = enable;
16183   mp->count = ntohl (count);
16184   mp->pcap_name_length = ntohl (name_len);
16185   if (pcap_file_set != 0)
16186     {
16187       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16188     }
16189   vec_free (pcap_file);
16190
16191   S;
16192   W;
16193   /* NOTREACHED */
16194   return 0;
16195 }
16196
16197 int
16198 api_pg_enable_disable (vat_main_t * vam)
16199 {
16200   unformat_input_t *input = vam->input;
16201   vl_api_pg_enable_disable_t *mp;
16202   f64 timeout;
16203
16204   u8 enable = 1;
16205   u8 stream_name_set = 0;
16206   u8 *stream_name = 0;
16207   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16208     {
16209       if (unformat (input, "stream %s", &stream_name))
16210         stream_name_set = 1;
16211       else if (unformat (input, "disable"))
16212         enable = 0;
16213       else
16214         break;
16215     }
16216
16217   if (stream_name_set > 0)
16218     {
16219       if (vec_len (stream_name) > 255)
16220         {
16221           errmsg ("stream name too long\n");
16222           return -99;
16223         }
16224     }
16225
16226   u32 name_len = vec_len (stream_name);
16227   /* Construct the API message */
16228   M (PG_ENABLE_DISABLE, pg_enable_disable);
16229   mp->context = 0;
16230   mp->is_enabled = enable;
16231   if (stream_name_set != 0)
16232     {
16233       mp->stream_name_length = ntohl (name_len);
16234       clib_memcpy (mp->stream_name, stream_name, name_len);
16235     }
16236   vec_free (stream_name);
16237
16238   S;
16239   W;
16240   /* NOTREACHED */
16241   return 0;
16242 }
16243
16244 int
16245 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16246 {
16247   unformat_input_t *input = vam->input;
16248   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16249   f64 timeout;
16250
16251   u16 *low_ports = 0;
16252   u16 *high_ports = 0;
16253   u16 this_low;
16254   u16 this_hi;
16255   ip4_address_t ip4_addr;
16256   ip6_address_t ip6_addr;
16257   u32 length;
16258   u32 tmp, tmp2;
16259   u8 prefix_set = 0;
16260   u32 vrf_id = ~0;
16261   u8 is_add = 1;
16262   u8 is_ipv6 = 0;
16263
16264   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16265     {
16266       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16267         {
16268           prefix_set = 1;
16269         }
16270       else
16271         if (unformat
16272             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16273         {
16274           prefix_set = 1;
16275           is_ipv6 = 1;
16276         }
16277       else if (unformat (input, "vrf %d", &vrf_id))
16278         ;
16279       else if (unformat (input, "del"))
16280         is_add = 0;
16281       else if (unformat (input, "port %d", &tmp))
16282         {
16283           if (tmp == 0 || tmp > 65535)
16284             {
16285               errmsg ("port %d out of range", tmp);
16286               return -99;
16287             }
16288           this_low = tmp;
16289           this_hi = this_low + 1;
16290           vec_add1 (low_ports, this_low);
16291           vec_add1 (high_ports, this_hi);
16292         }
16293       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16294         {
16295           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16296             {
16297               errmsg ("incorrect range parameters\n");
16298               return -99;
16299             }
16300           this_low = tmp;
16301           /* Note: in debug CLI +1 is added to high before
16302              passing to real fn that does "the work"
16303              (ip_source_and_port_range_check_add_del).
16304              This fn is a wrapper around the binary API fn a
16305              control plane will call, which expects this increment
16306              to have occurred. Hence letting the binary API control
16307              plane fn do the increment for consistency between VAT
16308              and other control planes.
16309            */
16310           this_hi = tmp2;
16311           vec_add1 (low_ports, this_low);
16312           vec_add1 (high_ports, this_hi);
16313         }
16314       else
16315         break;
16316     }
16317
16318   if (prefix_set == 0)
16319     {
16320       errmsg ("<address>/<mask> not specified\n");
16321       return -99;
16322     }
16323
16324   if (vrf_id == ~0)
16325     {
16326       errmsg ("VRF ID required, not specified\n");
16327       return -99;
16328     }
16329
16330   if (vrf_id == 0)
16331     {
16332       errmsg
16333         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
16334       return -99;
16335     }
16336
16337   if (vec_len (low_ports) == 0)
16338     {
16339       errmsg ("At least one port or port range required\n");
16340       return -99;
16341     }
16342
16343   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
16344      ip_source_and_port_range_check_add_del);
16345
16346   mp->is_add = is_add;
16347
16348   if (is_ipv6)
16349     {
16350       mp->is_ipv6 = 1;
16351       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16352     }
16353   else
16354     {
16355       mp->is_ipv6 = 0;
16356       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16357     }
16358
16359   mp->mask_length = length;
16360   mp->number_of_ranges = vec_len (low_ports);
16361
16362   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16363   vec_free (low_ports);
16364
16365   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16366   vec_free (high_ports);
16367
16368   mp->vrf_id = ntohl (vrf_id);
16369
16370   S;
16371   W;
16372   /* NOTREACHED */
16373   return 0;
16374 }
16375
16376 int
16377 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16378 {
16379   unformat_input_t *input = vam->input;
16380   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16381   f64 timeout;
16382   u32 sw_if_index = ~0;
16383   int vrf_set = 0;
16384   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16385   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16386   u8 is_add = 1;
16387
16388   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16389     {
16390       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
16391         ;
16392       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16393         ;
16394       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16395         vrf_set = 1;
16396       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16397         vrf_set = 1;
16398       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16399         vrf_set = 1;
16400       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16401         vrf_set = 1;
16402       else if (unformat (input, "del"))
16403         is_add = 0;
16404       else
16405         break;
16406     }
16407
16408   if (sw_if_index == ~0)
16409     {
16410       errmsg ("Interface required but not specified\n");
16411       return -99;
16412     }
16413
16414   if (vrf_set == 0)
16415     {
16416       errmsg ("VRF ID required but not specified\n");
16417       return -99;
16418     }
16419
16420   if (tcp_out_vrf_id == 0
16421       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16422     {
16423       errmsg
16424         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
16425       return -99;
16426     }
16427
16428   /* Construct the API message */
16429   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
16430      ip_source_and_port_range_check_interface_add_del);
16431
16432   mp->sw_if_index = ntohl (sw_if_index);
16433   mp->is_add = is_add;
16434   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16435   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16436   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16437   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16438
16439   /* send it... */
16440   S;
16441
16442   /* Wait for a reply... */
16443   W;
16444 }
16445
16446 static int
16447 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16448 {
16449   unformat_input_t *i = vam->input;
16450   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16451   f64 timeout;
16452   u32 local_sa_id = 0;
16453   u32 remote_sa_id = 0;
16454   ip4_address_t src_address;
16455   ip4_address_t dst_address;
16456   u8 is_add = 1;
16457
16458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16459     {
16460       if (unformat (i, "local_sa %d", &local_sa_id))
16461         ;
16462       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16463         ;
16464       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16465         ;
16466       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16467         ;
16468       else if (unformat (i, "del"))
16469         is_add = 0;
16470       else
16471         {
16472           clib_warning ("parse error '%U'", format_unformat_error, i);
16473           return -99;
16474         }
16475     }
16476
16477   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
16478
16479   mp->local_sa_id = ntohl (local_sa_id);
16480   mp->remote_sa_id = ntohl (remote_sa_id);
16481   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16482   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16483   mp->is_add = is_add;
16484
16485   S;
16486   W;
16487   /* NOTREACHED */
16488   return 0;
16489 }
16490
16491 static int
16492 api_punt (vat_main_t * vam)
16493 {
16494   unformat_input_t *i = vam->input;
16495   vl_api_punt_t *mp;
16496   f64 timeout;
16497   u32 ipv = ~0;
16498   u32 protocol = ~0;
16499   u32 port = ~0;
16500   int is_add = 1;
16501
16502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16503     {
16504       if (unformat (i, "ip %d", &ipv))
16505         ;
16506       else if (unformat (i, "protocol %d", &protocol))
16507         ;
16508       else if (unformat (i, "port %d", &port))
16509         ;
16510       else if (unformat (i, "del"))
16511         is_add = 0;
16512       else
16513         {
16514           clib_warning ("parse error '%U'", format_unformat_error, i);
16515           return -99;
16516         }
16517     }
16518
16519   M (PUNT, punt);
16520
16521   mp->is_add = (u8) is_add;
16522   mp->ipv = (u8) ipv;
16523   mp->l4_protocol = (u8) protocol;
16524   mp->l4_port = htons ((u16) port);
16525
16526   S;
16527   W;
16528   /* NOTREACHED */
16529   return 0;
16530 }
16531
16532 static void vl_api_ipsec_gre_tunnel_details_t_handler
16533   (vl_api_ipsec_gre_tunnel_details_t * mp)
16534 {
16535   vat_main_t *vam = &vat_main;
16536
16537   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
16538            ntohl (mp->sw_if_index),
16539            format_ip4_address, &mp->src_address,
16540            format_ip4_address, &mp->dst_address,
16541            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16542 }
16543
16544 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16545   (vl_api_ipsec_gre_tunnel_details_t * mp)
16546 {
16547   vat_main_t *vam = &vat_main;
16548   vat_json_node_t *node = NULL;
16549   struct in_addr ip4;
16550
16551   if (VAT_JSON_ARRAY != vam->json_tree.type)
16552     {
16553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16554       vat_json_init_array (&vam->json_tree);
16555     }
16556   node = vat_json_array_add (&vam->json_tree);
16557
16558   vat_json_init_object (node);
16559   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16560   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16561   vat_json_object_add_ip4 (node, "src_address", ip4);
16562   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16563   vat_json_object_add_ip4 (node, "dst_address", ip4);
16564   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16565   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16566 }
16567
16568 static int
16569 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16570 {
16571   unformat_input_t *i = vam->input;
16572   vl_api_ipsec_gre_tunnel_dump_t *mp;
16573   f64 timeout;
16574   u32 sw_if_index;
16575   u8 sw_if_index_set = 0;
16576
16577   /* Parse args required to build the message */
16578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16579     {
16580       if (unformat (i, "sw_if_index %d", &sw_if_index))
16581         sw_if_index_set = 1;
16582       else
16583         break;
16584     }
16585
16586   if (sw_if_index_set == 0)
16587     {
16588       sw_if_index = ~0;
16589     }
16590
16591   if (!vam->json_output)
16592     {
16593       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
16594                "sw_if_index", "src_address", "dst_address",
16595                "local_sa_id", "remote_sa_id");
16596     }
16597
16598   /* Get list of gre-tunnel interfaces */
16599   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16600
16601   mp->sw_if_index = htonl (sw_if_index);
16602
16603   S;
16604
16605   /* Use a control ping for synchronization */
16606   {
16607     vl_api_control_ping_t *mp;
16608     M (CONTROL_PING, control_ping);
16609     S;
16610   }
16611   W;
16612 }
16613
16614 static int
16615 api_delete_subif (vat_main_t * vam)
16616 {
16617   unformat_input_t *i = vam->input;
16618   vl_api_delete_subif_t *mp;
16619   f64 timeout;
16620   u32 sw_if_index = ~0;
16621
16622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16623     {
16624       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16625         ;
16626       if (unformat (i, "sw_if_index %d", &sw_if_index))
16627         ;
16628       else
16629         break;
16630     }
16631
16632   if (sw_if_index == ~0)
16633     {
16634       errmsg ("missing sw_if_index\n");
16635       return -99;
16636     }
16637
16638   /* Construct the API message */
16639   M (DELETE_SUBIF, delete_subif);
16640   mp->sw_if_index = ntohl (sw_if_index);
16641
16642   S;
16643   W;
16644 }
16645
16646 #define foreach_pbb_vtr_op      \
16647 _("disable",  L2_VTR_DISABLED)  \
16648 _("pop",  L2_VTR_POP_2)         \
16649 _("push",  L2_VTR_PUSH_2)
16650
16651 static int
16652 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16653 {
16654   unformat_input_t *i = vam->input;
16655   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16656   f64 timeout;
16657   u32 sw_if_index = ~0, vtr_op = ~0;
16658   u16 outer_tag = ~0;
16659   u8 dmac[6], smac[6];
16660   u8 dmac_set = 0, smac_set = 0;
16661   u16 vlanid = 0;
16662   u32 sid = ~0;
16663   u32 tmp;
16664
16665   /* Shut up coverity */
16666   memset (dmac, 0, sizeof (dmac));
16667   memset (smac, 0, sizeof (smac));
16668
16669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16670     {
16671       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16672         ;
16673       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16674         ;
16675       else if (unformat (i, "vtr_op %d", &vtr_op))
16676         ;
16677 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16678       foreach_pbb_vtr_op
16679 #undef _
16680         else if (unformat (i, "translate_pbb_stag"))
16681         {
16682           if (unformat (i, "%d", &tmp))
16683             {
16684               vtr_op = L2_VTR_TRANSLATE_2_1;
16685               outer_tag = tmp;
16686             }
16687           else
16688             {
16689               errmsg
16690                 ("translate_pbb_stag operation requires outer tag definition\n");
16691               return -99;
16692             }
16693         }
16694       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16695         dmac_set++;
16696       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16697         smac_set++;
16698       else if (unformat (i, "sid %d", &sid))
16699         ;
16700       else if (unformat (i, "vlanid %d", &tmp))
16701         vlanid = tmp;
16702       else
16703         {
16704           clib_warning ("parse error '%U'", format_unformat_error, i);
16705           return -99;
16706         }
16707     }
16708
16709   if ((sw_if_index == ~0) || (vtr_op == ~0))
16710     {
16711       errmsg ("missing sw_if_index or vtr operation\n");
16712       return -99;
16713     }
16714   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16715       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16716     {
16717       errmsg
16718         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
16719       return -99;
16720     }
16721
16722   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16723   mp->sw_if_index = ntohl (sw_if_index);
16724   mp->vtr_op = ntohl (vtr_op);
16725   mp->outer_tag = ntohs (outer_tag);
16726   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16727   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16728   mp->b_vlanid = ntohs (vlanid);
16729   mp->i_sid = ntohl (sid);
16730
16731   S;
16732   W;
16733   /* NOTREACHED */
16734   return 0;
16735 }
16736
16737 static int
16738 api_flow_classify_set_interface (vat_main_t * vam)
16739 {
16740   unformat_input_t *i = vam->input;
16741   vl_api_flow_classify_set_interface_t *mp;
16742   f64 timeout;
16743   u32 sw_if_index;
16744   int sw_if_index_set;
16745   u32 ip4_table_index = ~0;
16746   u32 ip6_table_index = ~0;
16747   u8 is_add = 1;
16748
16749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16750     {
16751       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16752         sw_if_index_set = 1;
16753       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16754         sw_if_index_set = 1;
16755       else if (unformat (i, "del"))
16756         is_add = 0;
16757       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16758         ;
16759       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16760         ;
16761       else
16762         {
16763           clib_warning ("parse error '%U'", format_unformat_error, i);
16764           return -99;
16765         }
16766     }
16767
16768   if (sw_if_index_set == 0)
16769     {
16770       errmsg ("missing interface name or sw_if_index\n");
16771       return -99;
16772     }
16773
16774   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16775
16776   mp->sw_if_index = ntohl (sw_if_index);
16777   mp->ip4_table_index = ntohl (ip4_table_index);
16778   mp->ip6_table_index = ntohl (ip6_table_index);
16779   mp->is_add = is_add;
16780
16781   S;
16782   W;
16783   /* NOTREACHED */
16784   return 0;
16785 }
16786
16787 static int
16788 api_flow_classify_dump (vat_main_t * vam)
16789 {
16790   unformat_input_t *i = vam->input;
16791   vl_api_flow_classify_dump_t *mp;
16792   f64 timeout = ~0;
16793   u8 type = FLOW_CLASSIFY_N_TABLES;
16794
16795   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16796     ;
16797   else
16798     {
16799       errmsg ("classify table type must be specified\n");
16800       return -99;
16801     }
16802
16803   if (!vam->json_output)
16804     {
16805       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
16806     }
16807
16808   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16809   mp->type = type;
16810   /* send it... */
16811   S;
16812
16813   /* Use a control ping for synchronization */
16814   {
16815     vl_api_control_ping_t *mp;
16816     M (CONTROL_PING, control_ping);
16817     S;
16818   }
16819   /* Wait for a reply... */
16820   W;
16821
16822   /* NOTREACHED */
16823   return 0;
16824 }
16825
16826 static int
16827 api_feature_enable_disable (vat_main_t * vam)
16828 {
16829   unformat_input_t *i = vam->input;
16830   vl_api_feature_enable_disable_t *mp;
16831   f64 timeout;
16832   u8 *arc_name = 0;
16833   u8 *feature_name = 0;
16834   u32 sw_if_index = ~0;
16835   u8 enable = 1;
16836
16837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16838     {
16839       if (unformat (i, "arc_name %s", &arc_name))
16840         ;
16841       else if (unformat (i, "feature_name %s", &feature_name))
16842         ;
16843       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16844         ;
16845       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16846         ;
16847       else if (unformat (i, "disable"))
16848         enable = 0;
16849       else
16850         break;
16851     }
16852
16853   if (arc_name == 0)
16854     {
16855       errmsg ("missing arc name\n");
16856       return -99;
16857     }
16858   if (vec_len (arc_name) > 63)
16859     {
16860       errmsg ("arc name too long\n");
16861     }
16862
16863   if (feature_name == 0)
16864     {
16865       errmsg ("missing feature name\n");
16866       return -99;
16867     }
16868   if (vec_len (feature_name) > 63)
16869     {
16870       errmsg ("feature name too long\n");
16871     }
16872
16873   if (sw_if_index == ~0)
16874     {
16875       errmsg ("missing interface name or sw_if_index\n");
16876       return -99;
16877     }
16878
16879   /* Construct the API message */
16880   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16881   mp->sw_if_index = ntohl (sw_if_index);
16882   mp->enable = enable;
16883   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16884   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16885   vec_free (arc_name);
16886   vec_free (feature_name);
16887
16888   S;
16889   W;
16890 }
16891
16892 static int
16893 api_sw_interface_tag_add_del (vat_main_t * vam)
16894 {
16895   unformat_input_t *i = vam->input;
16896   vl_api_sw_interface_tag_add_del_t *mp;
16897   f64 timeout;
16898   u32 sw_if_index = ~0;
16899   u8 *tag = 0;
16900   u8 enable = 1;
16901
16902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16903     {
16904       if (unformat (i, "tag %s", &tag))
16905         ;
16906       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16907         ;
16908       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16909         ;
16910       else if (unformat (i, "del"))
16911         enable = 0;
16912       else
16913         break;
16914     }
16915
16916   if (sw_if_index == ~0)
16917     {
16918       errmsg ("missing interface name or sw_if_index\n");
16919       return -99;
16920     }
16921
16922   if (enable && (tag == 0))
16923     {
16924       errmsg ("no tag specified\n");
16925       return -99;
16926     }
16927
16928   /* Construct the API message */
16929   M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
16930   mp->sw_if_index = ntohl (sw_if_index);
16931   mp->is_add = enable;
16932   if (enable)
16933     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
16934   vec_free (tag);
16935
16936   S;
16937   W;
16938 }
16939
16940 static void vl_api_l2_xconnect_details_t_handler
16941   (vl_api_l2_xconnect_details_t * mp)
16942 {
16943   vat_main_t *vam = &vat_main;
16944
16945   fformat (vam->ofp, "%15d%15d\n",
16946            ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
16947 }
16948
16949 static void vl_api_l2_xconnect_details_t_handler_json
16950   (vl_api_l2_xconnect_details_t * mp)
16951 {
16952   vat_main_t *vam = &vat_main;
16953   vat_json_node_t *node = NULL;
16954
16955   if (VAT_JSON_ARRAY != vam->json_tree.type)
16956     {
16957       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16958       vat_json_init_array (&vam->json_tree);
16959     }
16960   node = vat_json_array_add (&vam->json_tree);
16961
16962   vat_json_init_object (node);
16963   vat_json_object_add_uint (node, "rx_sw_if_index",
16964                             ntohl (mp->rx_sw_if_index));
16965   vat_json_object_add_uint (node, "tx_sw_if_index",
16966                             ntohl (mp->tx_sw_if_index));
16967 }
16968
16969 static int
16970 api_l2_xconnect_dump (vat_main_t * vam)
16971 {
16972   vl_api_l2_xconnect_dump_t *mp;
16973   f64 timeout;
16974
16975   if (!vam->json_output)
16976     {
16977       fformat (vam->ofp, "%15s%15s\n", "rx_sw_if_index", "tx_sw_if_index");
16978     }
16979
16980   M (L2_XCONNECT_DUMP, l2_xconnect_dump);
16981
16982   S;
16983
16984   /* Use a control ping for synchronization */
16985   {
16986     vl_api_control_ping_t *mp;
16987     M (CONTROL_PING, control_ping);
16988     S;
16989   }
16990   W;
16991 }
16992
16993 static int
16994 api_sw_interface_set_mtu (vat_main_t * vam)
16995 {
16996   unformat_input_t *i = vam->input;
16997   vl_api_sw_interface_set_mtu_t *mp;
16998   f64 timeout;
16999   u32 sw_if_index = ~0;
17000   u32 mtu = 0;
17001
17002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17003     {
17004       if (unformat (i, "mtu %d", &mtu))
17005         ;
17006       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
17007         ;
17008       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17009         ;
17010       else
17011         break;
17012     }
17013
17014   if (sw_if_index == ~0)
17015     {
17016       errmsg ("missing interface name or sw_if_index\n");
17017       return -99;
17018     }
17019
17020   if (mtu == 0)
17021     {
17022       errmsg ("no mtu specified\n");
17023       return -99;
17024     }
17025
17026   /* Construct the API message */
17027   M (SW_INTERFACE_SET_MTU, sw_interface_set_mtu);
17028   mp->sw_if_index = ntohl (sw_if_index);
17029   mp->mtu = ntohs ((u16) mtu);
17030
17031   S;
17032   W;
17033 }
17034
17035
17036 static int
17037 q_or_quit (vat_main_t * vam)
17038 {
17039   longjmp (vam->jump_buf, 1);
17040   return 0;                     /* not so much */
17041 }
17042
17043 static int
17044 q (vat_main_t * vam)
17045 {
17046   return q_or_quit (vam);
17047 }
17048
17049 static int
17050 quit (vat_main_t * vam)
17051 {
17052   return q_or_quit (vam);
17053 }
17054
17055 static int
17056 comment (vat_main_t * vam)
17057 {
17058   return 0;
17059 }
17060
17061 static int
17062 cmd_cmp (void *a1, void *a2)
17063 {
17064   u8 **c1 = a1;
17065   u8 **c2 = a2;
17066
17067   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17068 }
17069
17070 static int
17071 help (vat_main_t * vam)
17072 {
17073   u8 **cmds = 0;
17074   u8 *name = 0;
17075   hash_pair_t *p;
17076   unformat_input_t *i = vam->input;
17077   int j;
17078
17079   if (unformat (i, "%s", &name))
17080     {
17081       uword *hs;
17082
17083       vec_add1 (name, 0);
17084
17085       hs = hash_get_mem (vam->help_by_name, name);
17086       if (hs)
17087         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
17088       else
17089         fformat (vam->ofp, "No such msg / command '%s'\n", name);
17090       vec_free (name);
17091       return 0;
17092     }
17093
17094   fformat (vam->ofp, "Help is available for the following:\n");
17095
17096     /* *INDENT-OFF* */
17097     hash_foreach_pair (p, vam->function_by_name,
17098     ({
17099       vec_add1 (cmds, (u8 *)(p->key));
17100     }));
17101     /* *INDENT-ON* */
17102
17103   vec_sort_with_function (cmds, cmd_cmp);
17104
17105   for (j = 0; j < vec_len (cmds); j++)
17106     fformat (vam->ofp, "%s\n", cmds[j]);
17107
17108   vec_free (cmds);
17109   return 0;
17110 }
17111
17112 static int
17113 set (vat_main_t * vam)
17114 {
17115   u8 *name = 0, *value = 0;
17116   unformat_input_t *i = vam->input;
17117
17118   if (unformat (i, "%s", &name))
17119     {
17120       /* The input buffer is a vector, not a string. */
17121       value = vec_dup (i->buffer);
17122       vec_delete (value, i->index, 0);
17123       /* Almost certainly has a trailing newline */
17124       if (value[vec_len (value) - 1] == '\n')
17125         value[vec_len (value) - 1] = 0;
17126       /* Make sure it's a proper string, one way or the other */
17127       vec_add1 (value, 0);
17128       (void) clib_macro_set_value (&vam->macro_main,
17129                                    (char *) name, (char *) value);
17130     }
17131   else
17132     errmsg ("usage: set <name> <value>\n");
17133
17134   vec_free (name);
17135   vec_free (value);
17136   return 0;
17137 }
17138
17139 static int
17140 unset (vat_main_t * vam)
17141 {
17142   u8 *name = 0;
17143
17144   if (unformat (vam->input, "%s", &name))
17145     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17146       errmsg ("unset: %s wasn't set\n", name);
17147   vec_free (name);
17148   return 0;
17149 }
17150
17151 typedef struct
17152 {
17153   u8 *name;
17154   u8 *value;
17155 } macro_sort_t;
17156
17157
17158 static int
17159 macro_sort_cmp (void *a1, void *a2)
17160 {
17161   macro_sort_t *s1 = a1;
17162   macro_sort_t *s2 = a2;
17163
17164   return strcmp ((char *) (s1->name), (char *) (s2->name));
17165 }
17166
17167 static int
17168 dump_macro_table (vat_main_t * vam)
17169 {
17170   macro_sort_t *sort_me = 0, *sm;
17171   int i;
17172   hash_pair_t *p;
17173
17174     /* *INDENT-OFF* */
17175     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17176     ({
17177       vec_add2 (sort_me, sm, 1);
17178       sm->name = (u8 *)(p->key);
17179       sm->value = (u8 *) (p->value[0]);
17180     }));
17181     /* *INDENT-ON* */
17182
17183   vec_sort_with_function (sort_me, macro_sort_cmp);
17184
17185   if (vec_len (sort_me))
17186     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
17187   else
17188     fformat (vam->ofp, "The macro table is empty...\n");
17189
17190   for (i = 0; i < vec_len (sort_me); i++)
17191     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
17192   return 0;
17193 }
17194
17195 static int
17196 dump_node_table (vat_main_t * vam)
17197 {
17198   int i, j;
17199   vlib_node_t *node, *next_node;
17200
17201   if (vec_len (vam->graph_nodes) == 0)
17202     {
17203       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
17204       return 0;
17205     }
17206
17207   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17208     {
17209       node = vam->graph_nodes[i];
17210       fformat (vam->ofp, "[%d] %s\n", i, node->name);
17211       for (j = 0; j < vec_len (node->next_nodes); j++)
17212         {
17213           if (node->next_nodes[j] != ~0)
17214             {
17215               next_node = vam->graph_nodes[node->next_nodes[j]];
17216               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
17217             }
17218         }
17219     }
17220   return 0;
17221 }
17222
17223 static int
17224 value_sort_cmp (void *a1, void *a2)
17225 {
17226   name_sort_t *n1 = a1;
17227   name_sort_t *n2 = a2;
17228
17229   if (n1->value < n2->value)
17230     return -1;
17231   if (n1->value > n2->value)
17232     return 1;
17233   return 0;
17234 }
17235
17236
17237 static int
17238 dump_msg_api_table (vat_main_t * vam)
17239 {
17240   api_main_t *am = &api_main;
17241   name_sort_t *nses = 0, *ns;
17242   hash_pair_t *hp;
17243   int i;
17244
17245   /* *INDENT-OFF* */
17246   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17247   ({
17248     vec_add2 (nses, ns, 1);
17249     ns->name = (u8 *)(hp->key);
17250     ns->value = (u32) hp->value[0];
17251   }));
17252   /* *INDENT-ON* */
17253
17254   vec_sort_with_function (nses, value_sort_cmp);
17255
17256   for (i = 0; i < vec_len (nses); i++)
17257     fformat (vam->ofp, " [%d]: %s\n", nses[i].value, nses[i].name);
17258   vec_free (nses);
17259   return 0;
17260 }
17261
17262 static int
17263 get_msg_id (vat_main_t * vam)
17264 {
17265   u8 *name_and_crc;
17266   u32 message_index;
17267
17268   if (unformat (vam->input, "%s", &name_and_crc))
17269     {
17270       message_index = vl_api_get_msg_index (name_and_crc);
17271       if (message_index == ~0)
17272         {
17273           fformat (vam->ofp, " '%s' not found\n", name_and_crc);
17274           return 0;
17275         }
17276       fformat (vam->ofp, " '%s' has message index %d\n",
17277                name_and_crc, message_index);
17278       return 0;
17279     }
17280   errmsg ("name_and_crc required...\n");
17281   return 0;
17282 }
17283
17284 static int
17285 search_node_table (vat_main_t * vam)
17286 {
17287   unformat_input_t *line_input = vam->input;
17288   u8 *node_to_find;
17289   int j;
17290   vlib_node_t *node, *next_node;
17291   uword *p;
17292
17293   if (vam->graph_node_index_by_name == 0)
17294     {
17295       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
17296       return 0;
17297     }
17298
17299   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17300     {
17301       if (unformat (line_input, "%s", &node_to_find))
17302         {
17303           vec_add1 (node_to_find, 0);
17304           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17305           if (p == 0)
17306             {
17307               fformat (vam->ofp, "%s not found...\n", node_to_find);
17308               goto out;
17309             }
17310           node = vam->graph_nodes[p[0]];
17311           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
17312           for (j = 0; j < vec_len (node->next_nodes); j++)
17313             {
17314               if (node->next_nodes[j] != ~0)
17315                 {
17316                   next_node = vam->graph_nodes[node->next_nodes[j]];
17317                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
17318                 }
17319             }
17320         }
17321
17322       else
17323         {
17324           clib_warning ("parse error '%U'", format_unformat_error,
17325                         line_input);
17326           return -99;
17327         }
17328
17329     out:
17330       vec_free (node_to_find);
17331
17332     }
17333
17334   return 0;
17335 }
17336
17337
17338 static int
17339 script (vat_main_t * vam)
17340 {
17341   u8 *s = 0;
17342   char *save_current_file;
17343   unformat_input_t save_input;
17344   jmp_buf save_jump_buf;
17345   u32 save_line_number;
17346
17347   FILE *new_fp, *save_ifp;
17348
17349   if (unformat (vam->input, "%s", &s))
17350     {
17351       new_fp = fopen ((char *) s, "r");
17352       if (new_fp == 0)
17353         {
17354           errmsg ("Couldn't open script file %s\n", s);
17355           vec_free (s);
17356           return -99;
17357         }
17358     }
17359   else
17360     {
17361       errmsg ("Missing script name\n");
17362       return -99;
17363     }
17364
17365   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17366   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17367   save_ifp = vam->ifp;
17368   save_line_number = vam->input_line_number;
17369   save_current_file = (char *) vam->current_file;
17370
17371   vam->input_line_number = 0;
17372   vam->ifp = new_fp;
17373   vam->current_file = s;
17374   do_one_file (vam);
17375
17376   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17377   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17378   vam->ifp = save_ifp;
17379   vam->input_line_number = save_line_number;
17380   vam->current_file = (u8 *) save_current_file;
17381   vec_free (s);
17382
17383   return 0;
17384 }
17385
17386 static int
17387 echo (vat_main_t * vam)
17388 {
17389   fformat (vam->ofp, "%v", vam->input->buffer);
17390   return 0;
17391 }
17392
17393 /* List of API message constructors, CLI names map to api_xxx */
17394 #define foreach_vpe_api_msg                                             \
17395 _(create_loopback,"[mac <mac-addr>]")                                   \
17396 _(sw_interface_dump,"")                                                 \
17397 _(sw_interface_set_flags,                                               \
17398   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17399 _(sw_interface_add_del_address,                                         \
17400   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17401 _(sw_interface_set_table,                                               \
17402   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17403 _(sw_interface_set_mpls_enable,                                                \
17404   "<intfc> | sw_if_index [disable | dis]")                                \
17405 _(sw_interface_set_vpath,                                               \
17406   "<intfc> | sw_if_index <id> enable | disable")                        \
17407 _(sw_interface_set_vxlan_bypass,                                               \
17408   "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable")                        \
17409 _(sw_interface_set_l2_xconnect,                                         \
17410   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17411   "enable | disable")                                                   \
17412 _(sw_interface_set_l2_bridge,                                           \
17413   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
17414   "[shg <split-horizon-group>] [bvi]\n"                                 \
17415   "enable | disable")                                                   \
17416 _(sw_interface_set_dpdk_hqos_pipe,                                      \
17417   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
17418   "profile <profile-id>\n")                                             \
17419 _(sw_interface_set_dpdk_hqos_subport,                                   \
17420   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
17421   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
17422 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
17423   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
17424 _(bridge_domain_add_del,                                                \
17425   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
17426 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
17427 _(l2fib_add_del,                                                        \
17428   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17429 _(l2_flags,                                                             \
17430   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
17431 _(bridge_flags,                                                         \
17432   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17433 _(tap_connect,                                                          \
17434   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17435 _(tap_modify,                                                           \
17436   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17437 _(tap_delete,                                                           \
17438   "<vpp-if-name> | sw_if_index <id>")                                   \
17439 _(sw_interface_tap_dump, "")                                            \
17440 _(ip_add_del_route,                                                     \
17441   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17442   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17443   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17444   "[multipath] [count <n>]")                                            \
17445 _(mpls_route_add_del,                                                   \
17446   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17447   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17448   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17449   "[multipath] [count <n>]")                                            \
17450 _(mpls_ip_bind_unbind,                                                  \
17451   "<label> <addr/len>")                                                 \
17452 _(mpls_tunnel_add_del,                                                  \
17453   " via <addr> [table-id <n>]\n"                                        \
17454   "sw_if_index <id>] [l2]  [del]")                                      \
17455 _(proxy_arp_add_del,                                                    \
17456   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17457 _(proxy_arp_intfc_enable_disable,                                       \
17458   "<intfc> | sw_if_index <id> enable | disable")                        \
17459 _(sw_interface_set_unnumbered,                                          \
17460   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17461 _(ip_neighbor_add_del,                                                  \
17462   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17463   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17464 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17465 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17466 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17467   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17468   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17469   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17470 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17471 _(reset_fib, "vrf <n> [ipv6]")                                          \
17472 _(dhcp_proxy_config,                                                    \
17473   "svr <v46-address> src <v46-address>\n"                               \
17474    "insert-cid <n> [del]")                                              \
17475 _(dhcp_proxy_config_2,                                                  \
17476   "svr <v46-address> src <v46-address>\n"                               \
17477    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
17478 _(dhcp_proxy_set_vss,                                                   \
17479   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17480 _(dhcp_client_config,                                                   \
17481   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17482 _(set_ip_flow_hash,                                                     \
17483   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17484 _(sw_interface_ip6_enable_disable,                                      \
17485   "<intfc> | sw_if_index <id> enable | disable")                        \
17486 _(sw_interface_ip6_set_link_local_address,                              \
17487   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17488 _(sw_interface_ip6nd_ra_prefix,                                         \
17489   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17490   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17491   "[nolink] [isno]")                                                    \
17492 _(sw_interface_ip6nd_ra_config,                                         \
17493   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17494   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17495   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17496 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17497 _(l2_patch_add_del,                                                     \
17498   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17499   "enable | disable")                                                   \
17500 _(sr_tunnel_add_del,                                                    \
17501   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
17502   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
17503   "[policy <policy_name>]")                                             \
17504 _(sr_policy_add_del,                                                    \
17505   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
17506 _(sr_multicast_map_add_del,                                             \
17507   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
17508 _(classify_add_del_table,                                               \
17509   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17510   " [del] [del-chain] mask <mask-value>\n"                              \
17511   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17512   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17513 _(classify_add_del_session,                                             \
17514   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17515   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17516   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17517   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17518 _(classify_set_interface_ip_table,                                      \
17519   "<intfc> | sw_if_index <nn> table <nn>")                              \
17520 _(classify_set_interface_l2_tables,                                     \
17521   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17522   "  [other-table <nn>]")                                               \
17523 _(get_node_index, "node <node-name")                                    \
17524 _(add_node_next, "node <node-name> next <next-node-name>")              \
17525 _(l2tpv3_create_tunnel,                                                 \
17526   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17527   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
17528   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17529 _(l2tpv3_set_tunnel_cookies,                                            \
17530   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17531   "[new_remote_cookie <nn>]\n")                                         \
17532 _(l2tpv3_interface_enable_disable,                                      \
17533   "<intfc> | sw_if_index <nn> enable | disable")                        \
17534 _(l2tpv3_set_lookup_key,                                                \
17535   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
17536 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
17537 _(vxlan_add_del_tunnel,                                                 \
17538   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
17539   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
17540   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
17541 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
17542 _(gre_add_del_tunnel,                                                   \
17543   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
17544 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
17545 _(l2_fib_clear_table, "")                                               \
17546 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
17547 _(l2_interface_vlan_tag_rewrite,                                        \
17548   "<intfc> | sw_if_index <nn> \n"                                       \
17549   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
17550   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
17551 _(create_vhost_user_if,                                                 \
17552         "socket <filename> [server] [renumber <dev_instance>] "         \
17553         "[mac <mac_address>]")                                          \
17554 _(modify_vhost_user_if,                                                 \
17555         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
17556         "[server] [renumber <dev_instance>]")                           \
17557 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
17558 _(sw_interface_vhost_user_dump, "")                                     \
17559 _(show_version, "")                                                     \
17560 _(vxlan_gpe_add_del_tunnel,                                             \
17561   "local <addr> remote <addr> vni <nn>\n"                               \
17562     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
17563   "[next-ethernet] [next-nsh]\n")                                       \
17564 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
17565 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
17566 _(interface_name_renumber,                                              \
17567   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
17568 _(input_acl_set_interface,                                              \
17569   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17570   "  [l2-table <nn>] [del]")                                            \
17571 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
17572 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
17573 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
17574 _(ip_dump, "ipv4 | ipv6")                                               \
17575 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
17576 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
17577   "  spid_id <n> ")                                                     \
17578 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
17579   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
17580   "  integ_alg <alg> integ_key <hex>")                                  \
17581 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
17582   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
17583   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
17584   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
17585 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
17586 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
17587 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
17588   "(auth_data 0x<data> | auth_data <data>)")                            \
17589 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
17590   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
17591 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
17592   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
17593   "(local|remote)")                                                     \
17594 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
17595 _(delete_loopback,"sw_if_index <nn>")                                   \
17596 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
17597 _(map_add_domain,                                                       \
17598   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
17599   "ip6-src <ip6addr> "                                                  \
17600   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
17601 _(map_del_domain, "index <n>")                                          \
17602 _(map_add_del_rule,                                                     \
17603   "index <n> psid <n> dst <ip6addr> [del]")                             \
17604 _(map_domain_dump, "")                                                  \
17605 _(map_rule_dump, "index <map-domain>")                                  \
17606 _(want_interface_events,  "enable|disable")                             \
17607 _(want_stats,"enable|disable")                                          \
17608 _(get_first_msg_id, "client <name>")                                    \
17609 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
17610 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
17611   "fib-id <nn> [ip4][ip6][default]")                                    \
17612 _(get_node_graph, " ")                                                  \
17613 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
17614 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
17615 _(ioam_disable, "")                                                \
17616 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
17617                             " sw_if_index <sw_if_index> p <priority> "  \
17618                             "w <weight>] [del]")                        \
17619 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
17620                         "iface <intf> | sw_if_index <sw_if_index> "     \
17621                         "p <priority> w <weight> [del]")                \
17622 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
17623                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
17624                          "locator-set <locator_name> [del]"             \
17625                          "[key-id sha1|sha256 secret-key <secret-key>]")\
17626 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
17627   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
17628 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
17629 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
17630 _(lisp_gpe_enable_disable, "enable|disable")                            \
17631 _(lisp_enable_disable, "enable|disable")                                \
17632 _(lisp_map_register_enable_disable, "enable|disable")                   \
17633 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
17634 _(lisp_gpe_add_del_iface, "up|down")                                    \
17635 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
17636                                "[seid <seid>] "                         \
17637                                "rloc <locator> p <prio> "               \
17638                                "w <weight> [rloc <loc> ... ] "          \
17639                                "action <action> [del-all]")             \
17640 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
17641                           "<local-eid>")                                \
17642 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
17643 _(lisp_map_request_mode, "src-dst|dst-only")                            \
17644 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
17645 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
17646 _(lisp_locator_set_dump, "[local | remote]")                            \
17647 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
17648 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
17649                        "[local] | [remote]")                            \
17650 _(lisp_eid_table_vni_dump, "")                                          \
17651 _(lisp_eid_table_map_dump, "l2|l3")                                     \
17652 _(lisp_gpe_tunnel_dump, "")                                             \
17653 _(lisp_map_resolver_dump, "")                                           \
17654 _(lisp_map_server_dump, "")                                             \
17655 _(lisp_adjacencies_get, "vni <vni>")                                    \
17656 _(show_lisp_rloc_probe_state, "")                                       \
17657 _(show_lisp_map_register_state, "")                                     \
17658 _(show_lisp_status, "")                                                 \
17659 _(lisp_get_map_request_itr_rlocs, "")                                   \
17660 _(show_lisp_pitr, "")                                                   \
17661 _(show_lisp_map_request_mode, "")                                       \
17662 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
17663 _(af_packet_delete, "name <host interface name>")                       \
17664 _(policer_add_del, "name <policer name> <params> [del]")                \
17665 _(policer_dump, "[name <policer name>]")                                \
17666 _(policer_classify_set_interface,                                       \
17667   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17668   "  [l2-table <nn>] [del]")                                            \
17669 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
17670 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
17671     "[master|slave]")                                                   \
17672 _(netmap_delete, "name <interface name>")                               \
17673 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
17674 _(mpls_fib_dump, "")                                                    \
17675 _(classify_table_ids, "")                                               \
17676 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
17677 _(classify_table_info, "table_id <nn>")                                 \
17678 _(classify_session_dump, "table_id <nn>")                               \
17679 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
17680     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
17681     "[template_interval <nn>] [udp_checksum]")                          \
17682 _(ipfix_exporter_dump, "")                                              \
17683 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17684 _(ipfix_classify_stream_dump, "")                                       \
17685 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
17686 _(ipfix_classify_table_dump, "")                                        \
17687 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
17688 _(sw_interface_span_dump, "")                                           \
17689 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
17690 _(pg_create_interface, "if_id <nn>")                                    \
17691 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
17692 _(pg_enable_disable, "[stream <id>] disable")                           \
17693 _(ip_source_and_port_range_check_add_del,                               \
17694   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
17695 _(ip_source_and_port_range_check_interface_add_del,                     \
17696   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
17697   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
17698 _(ipsec_gre_add_del_tunnel,                                             \
17699   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
17700 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
17701 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
17702 _(l2_interface_pbb_tag_rewrite,                                         \
17703   "<intfc> | sw_if_index <nn> \n"                                       \
17704   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
17705   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
17706 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
17707 _(flow_classify_set_interface,                                          \
17708   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17709 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17710 _(ip_fib_dump, "")                                                      \
17711 _(ip6_fib_dump, "")                                                     \
17712 _(feature_enable_disable, "arc_name <arc_name> "                        \
17713   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
17714 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
17715 "[disable]")                                                            \
17716 _(l2_xconnect_dump, "")                                                 \
17717 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
17718 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
17719 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
17720
17721 /* List of command functions, CLI names map directly to functions */
17722 #define foreach_cli_function                                    \
17723 _(comment, "usage: comment <ignore-rest-of-line>")              \
17724 _(dump_interface_table, "usage: dump_interface_table")          \
17725 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17726 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17727 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17728 _(dump_stats_table, "usage: dump_stats_table")                  \
17729 _(dump_macro_table, "usage: dump_macro_table ")                 \
17730 _(dump_node_table, "usage: dump_node_table")                    \
17731 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17732 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17733 _(echo, "usage: echo <message>")                                \
17734 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17735 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17736 _(help, "usage: help")                                          \
17737 _(q, "usage: quit")                                             \
17738 _(quit, "usage: quit")                                          \
17739 _(search_node_table, "usage: search_node_table <name>...")      \
17740 _(set, "usage: set <variable-name> <value>")                    \
17741 _(script, "usage: script <file-name>")                          \
17742 _(unset, "usage: unset <variable-name>")
17743
17744 #define _(N,n)                                  \
17745     static void vl_api_##n##_t_handler_uni      \
17746     (vl_api_##n##_t * mp)                       \
17747     {                                           \
17748         vat_main_t * vam = &vat_main;           \
17749         if (vam->json_output) {                 \
17750             vl_api_##n##_t_handler_json(mp);    \
17751         } else {                                \
17752             vl_api_##n##_t_handler(mp);         \
17753         }                                       \
17754     }
17755 foreach_vpe_api_reply_msg;
17756 #undef _
17757
17758 void
17759 vat_api_hookup (vat_main_t * vam)
17760 {
17761 #define _(N,n)                                                  \
17762     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17763                            vl_api_##n##_t_handler_uni,          \
17764                            vl_noop_handler,                     \
17765                            vl_api_##n##_t_endian,               \
17766                            vl_api_##n##_t_print,                \
17767                            sizeof(vl_api_##n##_t), 1);
17768   foreach_vpe_api_reply_msg;
17769 #undef _
17770
17771   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17772
17773   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17774
17775   vam->function_by_name = hash_create_string (0, sizeof (uword));
17776
17777   vam->help_by_name = hash_create_string (0, sizeof (uword));
17778
17779   /* API messages we can send */
17780 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17781   foreach_vpe_api_msg;
17782 #undef _
17783
17784   /* Help strings */
17785 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17786   foreach_vpe_api_msg;
17787 #undef _
17788
17789   /* CLI functions */
17790 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17791   foreach_cli_function;
17792 #undef _
17793
17794   /* Help strings */
17795 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17796   foreach_cli_function;
17797 #undef _
17798 }
17799
17800 /*
17801  * fd.io coding-style-patch-verification: ON
17802  *
17803  * Local Variables:
17804  * eval: (c-set-style "gnu")
17805  * End:
17806  */