85821ee287b20202547ee048aec5993272ac6328
[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
10376
10377   if (ipv4_set && ipv6_set)
10378     {
10379       errmsg ("both IPv4 and IPv6 addresses specified");
10380       return -99;
10381     }
10382
10383   if ((vni == 0) || (vni >> 24))
10384     {
10385       errmsg ("vni not specified or out of range\n");
10386       return -99;
10387     }
10388
10389   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10390
10391   if (ipv6_set)
10392     {
10393       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10394       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10395     }
10396   else
10397     {
10398       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10399       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10400     }
10401   mp->encap_vrf_id = ntohl (encap_vrf_id);
10402   mp->decap_next_index = ntohl (decap_next_index);
10403   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10404   mp->vni = ntohl (vni);
10405   mp->is_add = is_add;
10406   mp->is_ipv6 = ipv6_set;
10407
10408   S;
10409   W;
10410   /* NOTREACHED */
10411   return 0;
10412 }
10413
10414 static void vl_api_vxlan_tunnel_details_t_handler
10415   (vl_api_vxlan_tunnel_details_t * mp)
10416 {
10417   vat_main_t *vam = &vat_main;
10418   ip46_address_t src, dst;
10419
10420   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10421   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10422
10423   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d\n",
10424            ntohl (mp->sw_if_index),
10425            format_ip46_address, &src, IP46_TYPE_ANY,
10426            format_ip46_address, &dst, IP46_TYPE_ANY,
10427            ntohl (mp->encap_vrf_id),
10428            ntohl (mp->decap_next_index), ntohl (mp->vni),
10429            ntohl (mp->mcast_sw_if_index));
10430 }
10431
10432 static void vl_api_vxlan_tunnel_details_t_handler_json
10433   (vl_api_vxlan_tunnel_details_t * mp)
10434 {
10435   vat_main_t *vam = &vat_main;
10436   vat_json_node_t *node = NULL;
10437
10438   if (VAT_JSON_ARRAY != vam->json_tree.type)
10439     {
10440       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10441       vat_json_init_array (&vam->json_tree);
10442     }
10443   node = vat_json_array_add (&vam->json_tree);
10444
10445   vat_json_init_object (node);
10446   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10447   if (mp->is_ipv6)
10448     {
10449       struct in6_addr ip6;
10450
10451       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10452       vat_json_object_add_ip6 (node, "src_address", ip6);
10453       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10454       vat_json_object_add_ip6 (node, "dst_address", ip6);
10455     }
10456   else
10457     {
10458       struct in_addr ip4;
10459
10460       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10461       vat_json_object_add_ip4 (node, "src_address", ip4);
10462       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10463       vat_json_object_add_ip4 (node, "dst_address", ip4);
10464     }
10465   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10466   vat_json_object_add_uint (node, "decap_next_index",
10467                             ntohl (mp->decap_next_index));
10468   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10469   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10470   vat_json_object_add_uint (node, "mcast_sw_if_index",
10471                             ntohl (mp->mcast_sw_if_index));
10472 }
10473
10474 static int
10475 api_vxlan_tunnel_dump (vat_main_t * vam)
10476 {
10477   unformat_input_t *i = vam->input;
10478   vl_api_vxlan_tunnel_dump_t *mp;
10479   f64 timeout;
10480   u32 sw_if_index;
10481   u8 sw_if_index_set = 0;
10482
10483   /* Parse args required to build the message */
10484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10485     {
10486       if (unformat (i, "sw_if_index %d", &sw_if_index))
10487         sw_if_index_set = 1;
10488       else
10489         break;
10490     }
10491
10492   if (sw_if_index_set == 0)
10493     {
10494       sw_if_index = ~0;
10495     }
10496
10497   if (!vam->json_output)
10498     {
10499       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s\n",
10500                "sw_if_index", "src_address", "dst_address",
10501                "encap_vrf_id", "decap_next_index", "vni",
10502                "mcast_sw_if_index");
10503     }
10504
10505   /* Get list of vxlan-tunnel interfaces */
10506   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10507
10508   mp->sw_if_index = htonl (sw_if_index);
10509
10510   S;
10511
10512   /* Use a control ping for synchronization */
10513   {
10514     vl_api_control_ping_t *mp;
10515     M (CONTROL_PING, control_ping);
10516     S;
10517   }
10518   W;
10519 }
10520
10521 static int
10522 api_gre_add_del_tunnel (vat_main_t * vam)
10523 {
10524   unformat_input_t *line_input = vam->input;
10525   vl_api_gre_add_del_tunnel_t *mp;
10526   f64 timeout;
10527   ip4_address_t src4, dst4;
10528   u8 is_add = 1;
10529   u8 teb = 0;
10530   u8 src_set = 0;
10531   u8 dst_set = 0;
10532   u32 outer_fib_id = 0;
10533
10534   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10535     {
10536       if (unformat (line_input, "del"))
10537         is_add = 0;
10538       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10539         src_set = 1;
10540       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10541         dst_set = 1;
10542       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10543         ;
10544       else if (unformat (line_input, "teb"))
10545         teb = 1;
10546       else
10547         {
10548           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10549           return -99;
10550         }
10551     }
10552
10553   if (src_set == 0)
10554     {
10555       errmsg ("tunnel src address not specified\n");
10556       return -99;
10557     }
10558   if (dst_set == 0)
10559     {
10560       errmsg ("tunnel dst address not specified\n");
10561       return -99;
10562     }
10563
10564
10565   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10566
10567   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10568   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10569   mp->outer_fib_id = ntohl (outer_fib_id);
10570   mp->is_add = is_add;
10571   mp->teb = teb;
10572
10573   S;
10574   W;
10575   /* NOTREACHED */
10576   return 0;
10577 }
10578
10579 static void vl_api_gre_tunnel_details_t_handler
10580   (vl_api_gre_tunnel_details_t * mp)
10581 {
10582   vat_main_t *vam = &vat_main;
10583
10584   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10585            ntohl (mp->sw_if_index),
10586            format_ip4_address, &mp->src_address,
10587            format_ip4_address, &mp->dst_address,
10588            mp->teb, ntohl (mp->outer_fib_id));
10589 }
10590
10591 static void vl_api_gre_tunnel_details_t_handler_json
10592   (vl_api_gre_tunnel_details_t * mp)
10593 {
10594   vat_main_t *vam = &vat_main;
10595   vat_json_node_t *node = NULL;
10596   struct in_addr ip4;
10597
10598   if (VAT_JSON_ARRAY != vam->json_tree.type)
10599     {
10600       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10601       vat_json_init_array (&vam->json_tree);
10602     }
10603   node = vat_json_array_add (&vam->json_tree);
10604
10605   vat_json_init_object (node);
10606   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10607   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10608   vat_json_object_add_ip4 (node, "src_address", ip4);
10609   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10610   vat_json_object_add_ip4 (node, "dst_address", ip4);
10611   vat_json_object_add_uint (node, "teb", mp->teb);
10612   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10613 }
10614
10615 static int
10616 api_gre_tunnel_dump (vat_main_t * vam)
10617 {
10618   unformat_input_t *i = vam->input;
10619   vl_api_gre_tunnel_dump_t *mp;
10620   f64 timeout;
10621   u32 sw_if_index;
10622   u8 sw_if_index_set = 0;
10623
10624   /* Parse args required to build the message */
10625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10626     {
10627       if (unformat (i, "sw_if_index %d", &sw_if_index))
10628         sw_if_index_set = 1;
10629       else
10630         break;
10631     }
10632
10633   if (sw_if_index_set == 0)
10634     {
10635       sw_if_index = ~0;
10636     }
10637
10638   if (!vam->json_output)
10639     {
10640       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10641                "sw_if_index", "src_address", "dst_address", "teb",
10642                "outer_fib_id");
10643     }
10644
10645   /* Get list of gre-tunnel interfaces */
10646   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10647
10648   mp->sw_if_index = htonl (sw_if_index);
10649
10650   S;
10651
10652   /* Use a control ping for synchronization */
10653   {
10654     vl_api_control_ping_t *mp;
10655     M (CONTROL_PING, control_ping);
10656     S;
10657   }
10658   W;
10659 }
10660
10661 static int
10662 api_l2_fib_clear_table (vat_main_t * vam)
10663 {
10664 //  unformat_input_t * i = vam->input;
10665   vl_api_l2_fib_clear_table_t *mp;
10666   f64 timeout;
10667
10668   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10669
10670   S;
10671   W;
10672   /* NOTREACHED */
10673   return 0;
10674 }
10675
10676 static int
10677 api_l2_interface_efp_filter (vat_main_t * vam)
10678 {
10679   unformat_input_t *i = vam->input;
10680   vl_api_l2_interface_efp_filter_t *mp;
10681   f64 timeout;
10682   u32 sw_if_index;
10683   u8 enable = 1;
10684   u8 sw_if_index_set = 0;
10685
10686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10687     {
10688       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10689         sw_if_index_set = 1;
10690       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10691         sw_if_index_set = 1;
10692       else if (unformat (i, "enable"))
10693         enable = 1;
10694       else if (unformat (i, "disable"))
10695         enable = 0;
10696       else
10697         {
10698           clib_warning ("parse error '%U'", format_unformat_error, i);
10699           return -99;
10700         }
10701     }
10702
10703   if (sw_if_index_set == 0)
10704     {
10705       errmsg ("missing sw_if_index\n");
10706       return -99;
10707     }
10708
10709   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10710
10711   mp->sw_if_index = ntohl (sw_if_index);
10712   mp->enable_disable = enable;
10713
10714   S;
10715   W;
10716   /* NOTREACHED */
10717   return 0;
10718 }
10719
10720 #define foreach_vtr_op                          \
10721 _("disable",  L2_VTR_DISABLED)                  \
10722 _("push-1",  L2_VTR_PUSH_1)                     \
10723 _("push-2",  L2_VTR_PUSH_2)                     \
10724 _("pop-1",  L2_VTR_POP_1)                       \
10725 _("pop-2",  L2_VTR_POP_2)                       \
10726 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10727 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10728 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10729 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10730
10731 static int
10732 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10733 {
10734   unformat_input_t *i = vam->input;
10735   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10736   f64 timeout;
10737   u32 sw_if_index;
10738   u8 sw_if_index_set = 0;
10739   u8 vtr_op_set = 0;
10740   u32 vtr_op = 0;
10741   u32 push_dot1q = 1;
10742   u32 tag1 = ~0;
10743   u32 tag2 = ~0;
10744
10745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10746     {
10747       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10748         sw_if_index_set = 1;
10749       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10750         sw_if_index_set = 1;
10751       else if (unformat (i, "vtr_op %d", &vtr_op))
10752         vtr_op_set = 1;
10753 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10754       foreach_vtr_op
10755 #undef _
10756         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10757         ;
10758       else if (unformat (i, "tag1 %d", &tag1))
10759         ;
10760       else if (unformat (i, "tag2 %d", &tag2))
10761         ;
10762       else
10763         {
10764           clib_warning ("parse error '%U'", format_unformat_error, i);
10765           return -99;
10766         }
10767     }
10768
10769   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10770     {
10771       errmsg ("missing vtr operation or sw_if_index\n");
10772       return -99;
10773     }
10774
10775   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10776     mp->sw_if_index = ntohl (sw_if_index);
10777   mp->vtr_op = ntohl (vtr_op);
10778   mp->push_dot1q = ntohl (push_dot1q);
10779   mp->tag1 = ntohl (tag1);
10780   mp->tag2 = ntohl (tag2);
10781
10782   S;
10783   W;
10784   /* NOTREACHED */
10785   return 0;
10786 }
10787
10788 static int
10789 api_create_vhost_user_if (vat_main_t * vam)
10790 {
10791   unformat_input_t *i = vam->input;
10792   vl_api_create_vhost_user_if_t *mp;
10793   f64 timeout;
10794   u8 *file_name;
10795   u8 is_server = 0;
10796   u8 file_name_set = 0;
10797   u32 custom_dev_instance = ~0;
10798   u8 hwaddr[6];
10799   u8 use_custom_mac = 0;
10800   u8 *tag = 0;
10801
10802   /* Shut up coverity */
10803   memset (hwaddr, 0, sizeof (hwaddr));
10804
10805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10806     {
10807       if (unformat (i, "socket %s", &file_name))
10808         {
10809           file_name_set = 1;
10810         }
10811       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10812         ;
10813       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10814         use_custom_mac = 1;
10815       else if (unformat (i, "server"))
10816         is_server = 1;
10817       else if (unformat (i, "tag %s", &tag))
10818         ;
10819       else
10820         break;
10821     }
10822
10823   if (file_name_set == 0)
10824     {
10825       errmsg ("missing socket file name\n");
10826       return -99;
10827     }
10828
10829   if (vec_len (file_name) > 255)
10830     {
10831       errmsg ("socket file name too long\n");
10832       return -99;
10833     }
10834   vec_add1 (file_name, 0);
10835
10836   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10837
10838   mp->is_server = is_server;
10839   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10840   vec_free (file_name);
10841   if (custom_dev_instance != ~0)
10842     {
10843       mp->renumber = 1;
10844       mp->custom_dev_instance = ntohl (custom_dev_instance);
10845     }
10846   mp->use_custom_mac = use_custom_mac;
10847   clib_memcpy (mp->mac_address, hwaddr, 6);
10848   if (tag)
10849     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10850   vec_free (tag);
10851
10852   S;
10853   W;
10854   /* NOTREACHED */
10855   return 0;
10856 }
10857
10858 static int
10859 api_modify_vhost_user_if (vat_main_t * vam)
10860 {
10861   unformat_input_t *i = vam->input;
10862   vl_api_modify_vhost_user_if_t *mp;
10863   f64 timeout;
10864   u8 *file_name;
10865   u8 is_server = 0;
10866   u8 file_name_set = 0;
10867   u32 custom_dev_instance = ~0;
10868   u8 sw_if_index_set = 0;
10869   u32 sw_if_index = (u32) ~ 0;
10870
10871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10872     {
10873       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10874         sw_if_index_set = 1;
10875       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10876         sw_if_index_set = 1;
10877       else if (unformat (i, "socket %s", &file_name))
10878         {
10879           file_name_set = 1;
10880         }
10881       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10882         ;
10883       else if (unformat (i, "server"))
10884         is_server = 1;
10885       else
10886         break;
10887     }
10888
10889   if (sw_if_index_set == 0)
10890     {
10891       errmsg ("missing sw_if_index or interface name\n");
10892       return -99;
10893     }
10894
10895   if (file_name_set == 0)
10896     {
10897       errmsg ("missing socket file name\n");
10898       return -99;
10899     }
10900
10901   if (vec_len (file_name) > 255)
10902     {
10903       errmsg ("socket file name too long\n");
10904       return -99;
10905     }
10906   vec_add1 (file_name, 0);
10907
10908   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10909
10910   mp->sw_if_index = ntohl (sw_if_index);
10911   mp->is_server = is_server;
10912   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10913   vec_free (file_name);
10914   if (custom_dev_instance != ~0)
10915     {
10916       mp->renumber = 1;
10917       mp->custom_dev_instance = ntohl (custom_dev_instance);
10918     }
10919
10920   S;
10921   W;
10922   /* NOTREACHED */
10923   return 0;
10924 }
10925
10926 static int
10927 api_delete_vhost_user_if (vat_main_t * vam)
10928 {
10929   unformat_input_t *i = vam->input;
10930   vl_api_delete_vhost_user_if_t *mp;
10931   f64 timeout;
10932   u32 sw_if_index = ~0;
10933   u8 sw_if_index_set = 0;
10934
10935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10936     {
10937       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10938         sw_if_index_set = 1;
10939       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10940         sw_if_index_set = 1;
10941       else
10942         break;
10943     }
10944
10945   if (sw_if_index_set == 0)
10946     {
10947       errmsg ("missing sw_if_index or interface name\n");
10948       return -99;
10949     }
10950
10951
10952   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10953
10954   mp->sw_if_index = ntohl (sw_if_index);
10955
10956   S;
10957   W;
10958   /* NOTREACHED */
10959   return 0;
10960 }
10961
10962 static void vl_api_sw_interface_vhost_user_details_t_handler
10963   (vl_api_sw_interface_vhost_user_details_t * mp)
10964 {
10965   vat_main_t *vam = &vat_main;
10966
10967   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10968            (char *) mp->interface_name,
10969            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10970            clib_net_to_host_u64 (mp->features), mp->is_server,
10971            ntohl (mp->num_regions), (char *) mp->sock_filename);
10972   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10973 }
10974
10975 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10976   (vl_api_sw_interface_vhost_user_details_t * mp)
10977 {
10978   vat_main_t *vam = &vat_main;
10979   vat_json_node_t *node = NULL;
10980
10981   if (VAT_JSON_ARRAY != vam->json_tree.type)
10982     {
10983       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10984       vat_json_init_array (&vam->json_tree);
10985     }
10986   node = vat_json_array_add (&vam->json_tree);
10987
10988   vat_json_init_object (node);
10989   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10990   vat_json_object_add_string_copy (node, "interface_name",
10991                                    mp->interface_name);
10992   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10993                             ntohl (mp->virtio_net_hdr_sz));
10994   vat_json_object_add_uint (node, "features",
10995                             clib_net_to_host_u64 (mp->features));
10996   vat_json_object_add_uint (node, "is_server", mp->is_server);
10997   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10998   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10999   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11000 }
11001
11002 static int
11003 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11004 {
11005   vl_api_sw_interface_vhost_user_dump_t *mp;
11006   f64 timeout;
11007   fformat (vam->ofp,
11008            "Interface name           idx hdr_sz features server regions filename\n");
11009
11010   /* Get list of vhost-user interfaces */
11011   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
11012   S;
11013
11014   /* Use a control ping for synchronization */
11015   {
11016     vl_api_control_ping_t *mp;
11017     M (CONTROL_PING, control_ping);
11018     S;
11019   }
11020   W;
11021 }
11022
11023 static int
11024 api_show_version (vat_main_t * vam)
11025 {
11026   vl_api_show_version_t *mp;
11027   f64 timeout;
11028
11029   M (SHOW_VERSION, show_version);
11030
11031   S;
11032   W;
11033   /* NOTREACHED */
11034   return 0;
11035 }
11036
11037
11038 static int
11039 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11040 {
11041   unformat_input_t *line_input = vam->input;
11042   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11043   f64 timeout;
11044   ip4_address_t local4, remote4;
11045   ip6_address_t local6, remote6;
11046   u8 is_add = 1;
11047   u8 ipv4_set = 0, ipv6_set = 0;
11048   u8 local_set = 0;
11049   u8 remote_set = 0;
11050   u32 encap_vrf_id = 0;
11051   u32 decap_vrf_id = 0;
11052   u8 protocol = ~0;
11053   u32 vni;
11054   u8 vni_set = 0;
11055
11056   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11057     {
11058       if (unformat (line_input, "del"))
11059         is_add = 0;
11060       else if (unformat (line_input, "local %U",
11061                          unformat_ip4_address, &local4))
11062         {
11063           local_set = 1;
11064           ipv4_set = 1;
11065         }
11066       else if (unformat (line_input, "remote %U",
11067                          unformat_ip4_address, &remote4))
11068         {
11069           remote_set = 1;
11070           ipv4_set = 1;
11071         }
11072       else if (unformat (line_input, "local %U",
11073                          unformat_ip6_address, &local6))
11074         {
11075           local_set = 1;
11076           ipv6_set = 1;
11077         }
11078       else if (unformat (line_input, "remote %U",
11079                          unformat_ip6_address, &remote6))
11080         {
11081           remote_set = 1;
11082           ipv6_set = 1;
11083         }
11084       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11085         ;
11086       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11087         ;
11088       else if (unformat (line_input, "vni %d", &vni))
11089         vni_set = 1;
11090       else if (unformat (line_input, "next-ip4"))
11091         protocol = 1;
11092       else if (unformat (line_input, "next-ip6"))
11093         protocol = 2;
11094       else if (unformat (line_input, "next-ethernet"))
11095         protocol = 3;
11096       else if (unformat (line_input, "next-nsh"))
11097         protocol = 4;
11098       else
11099         {
11100           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
11101           return -99;
11102         }
11103     }
11104
11105   if (local_set == 0)
11106     {
11107       errmsg ("tunnel local address not specified\n");
11108       return -99;
11109     }
11110   if (remote_set == 0)
11111     {
11112       errmsg ("tunnel remote address not specified\n");
11113       return -99;
11114     }
11115   if (ipv4_set && ipv6_set)
11116     {
11117       errmsg ("both IPv4 and IPv6 addresses specified");
11118       return -99;
11119     }
11120
11121   if (vni_set == 0)
11122     {
11123       errmsg ("vni not specified\n");
11124       return -99;
11125     }
11126
11127   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
11128
11129
11130   if (ipv6_set)
11131     {
11132       clib_memcpy (&mp->local, &local6, sizeof (local6));
11133       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11134     }
11135   else
11136     {
11137       clib_memcpy (&mp->local, &local4, sizeof (local4));
11138       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11139     }
11140
11141   mp->encap_vrf_id = ntohl (encap_vrf_id);
11142   mp->decap_vrf_id = ntohl (decap_vrf_id);
11143   mp->protocol = protocol;
11144   mp->vni = ntohl (vni);
11145   mp->is_add = is_add;
11146   mp->is_ipv6 = ipv6_set;
11147
11148   S;
11149   W;
11150   /* NOTREACHED */
11151   return 0;
11152 }
11153
11154 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11155   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11156 {
11157   vat_main_t *vam = &vat_main;
11158
11159   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
11160            ntohl (mp->sw_if_index),
11161            format_ip46_address, &(mp->local[0]),
11162            format_ip46_address, &(mp->remote[0]),
11163            ntohl (mp->vni),
11164            ntohl (mp->protocol),
11165            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11166 }
11167
11168 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11169   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11170 {
11171   vat_main_t *vam = &vat_main;
11172   vat_json_node_t *node = NULL;
11173   struct in_addr ip4;
11174   struct in6_addr ip6;
11175
11176   if (VAT_JSON_ARRAY != vam->json_tree.type)
11177     {
11178       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11179       vat_json_init_array (&vam->json_tree);
11180     }
11181   node = vat_json_array_add (&vam->json_tree);
11182
11183   vat_json_init_object (node);
11184   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11185   if (mp->is_ipv6)
11186     {
11187       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11188       vat_json_object_add_ip6 (node, "local", ip6);
11189       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11190       vat_json_object_add_ip6 (node, "remote", ip6);
11191     }
11192   else
11193     {
11194       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11195       vat_json_object_add_ip4 (node, "local", ip4);
11196       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11197       vat_json_object_add_ip4 (node, "remote", ip4);
11198     }
11199   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11200   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11201   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11202   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11203   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11204 }
11205
11206 static int
11207 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11208 {
11209   unformat_input_t *i = vam->input;
11210   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11211   f64 timeout;
11212   u32 sw_if_index;
11213   u8 sw_if_index_set = 0;
11214
11215   /* Parse args required to build the message */
11216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11217     {
11218       if (unformat (i, "sw_if_index %d", &sw_if_index))
11219         sw_if_index_set = 1;
11220       else
11221         break;
11222     }
11223
11224   if (sw_if_index_set == 0)
11225     {
11226       sw_if_index = ~0;
11227     }
11228
11229   if (!vam->json_output)
11230     {
11231       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
11232                "sw_if_index", "local", "remote", "vni",
11233                "protocol", "encap_vrf_id", "decap_vrf_id");
11234     }
11235
11236   /* Get list of vxlan-tunnel interfaces */
11237   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11238
11239   mp->sw_if_index = htonl (sw_if_index);
11240
11241   S;
11242
11243   /* Use a control ping for synchronization */
11244   {
11245     vl_api_control_ping_t *mp;
11246     M (CONTROL_PING, control_ping);
11247     S;
11248   }
11249   W;
11250 }
11251
11252 u8 *
11253 format_l2_fib_mac_address (u8 * s, va_list * args)
11254 {
11255   u8 *a = va_arg (*args, u8 *);
11256
11257   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11258                  a[2], a[3], a[4], a[5], a[6], a[7]);
11259 }
11260
11261 static void vl_api_l2_fib_table_entry_t_handler
11262   (vl_api_l2_fib_table_entry_t * mp)
11263 {
11264   vat_main_t *vam = &vat_main;
11265
11266   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11267            "       %d       %d     %d\n",
11268            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11269            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11270            mp->bvi_mac);
11271 }
11272
11273 static void vl_api_l2_fib_table_entry_t_handler_json
11274   (vl_api_l2_fib_table_entry_t * mp)
11275 {
11276   vat_main_t *vam = &vat_main;
11277   vat_json_node_t *node = NULL;
11278
11279   if (VAT_JSON_ARRAY != vam->json_tree.type)
11280     {
11281       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11282       vat_json_init_array (&vam->json_tree);
11283     }
11284   node = vat_json_array_add (&vam->json_tree);
11285
11286   vat_json_init_object (node);
11287   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11288   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11289   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11290   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11291   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11292   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11293 }
11294
11295 static int
11296 api_l2_fib_table_dump (vat_main_t * vam)
11297 {
11298   unformat_input_t *i = vam->input;
11299   vl_api_l2_fib_table_dump_t *mp;
11300   f64 timeout;
11301   u32 bd_id;
11302   u8 bd_id_set = 0;
11303
11304   /* Parse args required to build the message */
11305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11306     {
11307       if (unformat (i, "bd_id %d", &bd_id))
11308         bd_id_set = 1;
11309       else
11310         break;
11311     }
11312
11313   if (bd_id_set == 0)
11314     {
11315       errmsg ("missing bridge domain\n");
11316       return -99;
11317     }
11318
11319   fformat (vam->ofp,
11320            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11321
11322   /* Get list of l2 fib entries */
11323   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11324
11325   mp->bd_id = ntohl (bd_id);
11326   S;
11327
11328   /* Use a control ping for synchronization */
11329   {
11330     vl_api_control_ping_t *mp;
11331     M (CONTROL_PING, control_ping);
11332     S;
11333   }
11334   W;
11335 }
11336
11337
11338 static int
11339 api_interface_name_renumber (vat_main_t * vam)
11340 {
11341   unformat_input_t *line_input = vam->input;
11342   vl_api_interface_name_renumber_t *mp;
11343   u32 sw_if_index = ~0;
11344   f64 timeout;
11345   u32 new_show_dev_instance = ~0;
11346
11347   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11348     {
11349       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11350                     &sw_if_index))
11351         ;
11352       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11353         ;
11354       else if (unformat (line_input, "new_show_dev_instance %d",
11355                          &new_show_dev_instance))
11356         ;
11357       else
11358         break;
11359     }
11360
11361   if (sw_if_index == ~0)
11362     {
11363       errmsg ("missing interface name or sw_if_index\n");
11364       return -99;
11365     }
11366
11367   if (new_show_dev_instance == ~0)
11368     {
11369       errmsg ("missing new_show_dev_instance\n");
11370       return -99;
11371     }
11372
11373   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11374
11375   mp->sw_if_index = ntohl (sw_if_index);
11376   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11377
11378   S;
11379   W;
11380 }
11381
11382 static int
11383 api_want_ip4_arp_events (vat_main_t * vam)
11384 {
11385   unformat_input_t *line_input = vam->input;
11386   vl_api_want_ip4_arp_events_t *mp;
11387   f64 timeout;
11388   ip4_address_t address;
11389   int address_set = 0;
11390   u32 enable_disable = 1;
11391
11392   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11393     {
11394       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11395         address_set = 1;
11396       else if (unformat (line_input, "del"))
11397         enable_disable = 0;
11398       else
11399         break;
11400     }
11401
11402   if (address_set == 0)
11403     {
11404       errmsg ("missing addresses\n");
11405       return -99;
11406     }
11407
11408   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11409   mp->enable_disable = enable_disable;
11410   mp->pid = getpid ();
11411   mp->address = address.as_u32;
11412
11413   S;
11414   W;
11415 }
11416
11417 static int
11418 api_want_ip6_nd_events (vat_main_t * vam)
11419 {
11420   unformat_input_t *line_input = vam->input;
11421   vl_api_want_ip6_nd_events_t *mp;
11422   f64 timeout;
11423   ip6_address_t address;
11424   int address_set = 0;
11425   u32 enable_disable = 1;
11426
11427   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11428     {
11429       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11430         address_set = 1;
11431       else if (unformat (line_input, "del"))
11432         enable_disable = 0;
11433       else
11434         break;
11435     }
11436
11437   if (address_set == 0)
11438     {
11439       errmsg ("missing addresses\n");
11440       return -99;
11441     }
11442
11443   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11444   mp->enable_disable = enable_disable;
11445   mp->pid = getpid ();
11446   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11447
11448   S;
11449   W;
11450 }
11451
11452 static int
11453 api_input_acl_set_interface (vat_main_t * vam)
11454 {
11455   unformat_input_t *i = vam->input;
11456   vl_api_input_acl_set_interface_t *mp;
11457   f64 timeout;
11458   u32 sw_if_index;
11459   int sw_if_index_set;
11460   u32 ip4_table_index = ~0;
11461   u32 ip6_table_index = ~0;
11462   u32 l2_table_index = ~0;
11463   u8 is_add = 1;
11464
11465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11466     {
11467       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11468         sw_if_index_set = 1;
11469       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11470         sw_if_index_set = 1;
11471       else if (unformat (i, "del"))
11472         is_add = 0;
11473       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11474         ;
11475       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11476         ;
11477       else if (unformat (i, "l2-table %d", &l2_table_index))
11478         ;
11479       else
11480         {
11481           clib_warning ("parse error '%U'", format_unformat_error, i);
11482           return -99;
11483         }
11484     }
11485
11486   if (sw_if_index_set == 0)
11487     {
11488       errmsg ("missing interface name or sw_if_index\n");
11489       return -99;
11490     }
11491
11492   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11493
11494   mp->sw_if_index = ntohl (sw_if_index);
11495   mp->ip4_table_index = ntohl (ip4_table_index);
11496   mp->ip6_table_index = ntohl (ip6_table_index);
11497   mp->l2_table_index = ntohl (l2_table_index);
11498   mp->is_add = is_add;
11499
11500   S;
11501   W;
11502   /* NOTREACHED */
11503   return 0;
11504 }
11505
11506 static int
11507 api_ip_address_dump (vat_main_t * vam)
11508 {
11509   unformat_input_t *i = vam->input;
11510   vl_api_ip_address_dump_t *mp;
11511   u32 sw_if_index = ~0;
11512   u8 sw_if_index_set = 0;
11513   u8 ipv4_set = 0;
11514   u8 ipv6_set = 0;
11515   f64 timeout;
11516
11517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11518     {
11519       if (unformat (i, "sw_if_index %d", &sw_if_index))
11520         sw_if_index_set = 1;
11521       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11522         sw_if_index_set = 1;
11523       else if (unformat (i, "ipv4"))
11524         ipv4_set = 1;
11525       else if (unformat (i, "ipv6"))
11526         ipv6_set = 1;
11527       else
11528         break;
11529     }
11530
11531   if (ipv4_set && ipv6_set)
11532     {
11533       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11534       return -99;
11535     }
11536
11537   if ((!ipv4_set) && (!ipv6_set))
11538     {
11539       errmsg ("no ipv4 nor ipv6 flag set\n");
11540       return -99;
11541     }
11542
11543   if (sw_if_index_set == 0)
11544     {
11545       errmsg ("missing interface name or sw_if_index\n");
11546       return -99;
11547     }
11548
11549   vam->current_sw_if_index = sw_if_index;
11550   vam->is_ipv6 = ipv6_set;
11551
11552   M (IP_ADDRESS_DUMP, ip_address_dump);
11553   mp->sw_if_index = ntohl (sw_if_index);
11554   mp->is_ipv6 = ipv6_set;
11555   S;
11556
11557   /* Use a control ping for synchronization */
11558   {
11559     vl_api_control_ping_t *mp;
11560     M (CONTROL_PING, control_ping);
11561     S;
11562   }
11563   W;
11564 }
11565
11566 static int
11567 api_ip_dump (vat_main_t * vam)
11568 {
11569   vl_api_ip_dump_t *mp;
11570   unformat_input_t *in = vam->input;
11571   int ipv4_set = 0;
11572   int ipv6_set = 0;
11573   int is_ipv6;
11574   f64 timeout;
11575   int i;
11576
11577   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11578     {
11579       if (unformat (in, "ipv4"))
11580         ipv4_set = 1;
11581       else if (unformat (in, "ipv6"))
11582         ipv6_set = 1;
11583       else
11584         break;
11585     }
11586
11587   if (ipv4_set && ipv6_set)
11588     {
11589       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11590       return -99;
11591     }
11592
11593   if ((!ipv4_set) && (!ipv6_set))
11594     {
11595       errmsg ("no ipv4 nor ipv6 flag set\n");
11596       return -99;
11597     }
11598
11599   is_ipv6 = ipv6_set;
11600   vam->is_ipv6 = is_ipv6;
11601
11602   /* free old data */
11603   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11604     {
11605       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11606     }
11607   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11608
11609   M (IP_DUMP, ip_dump);
11610   mp->is_ipv6 = ipv6_set;
11611   S;
11612
11613   /* Use a control ping for synchronization */
11614   {
11615     vl_api_control_ping_t *mp;
11616     M (CONTROL_PING, control_ping);
11617     S;
11618   }
11619   W;
11620 }
11621
11622 static int
11623 api_ipsec_spd_add_del (vat_main_t * vam)
11624 {
11625   unformat_input_t *i = vam->input;
11626   vl_api_ipsec_spd_add_del_t *mp;
11627   f64 timeout;
11628   u32 spd_id = ~0;
11629   u8 is_add = 1;
11630
11631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11632     {
11633       if (unformat (i, "spd_id %d", &spd_id))
11634         ;
11635       else if (unformat (i, "del"))
11636         is_add = 0;
11637       else
11638         {
11639           clib_warning ("parse error '%U'", format_unformat_error, i);
11640           return -99;
11641         }
11642     }
11643   if (spd_id == ~0)
11644     {
11645       errmsg ("spd_id must be set\n");
11646       return -99;
11647     }
11648
11649   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11650
11651   mp->spd_id = ntohl (spd_id);
11652   mp->is_add = is_add;
11653
11654   S;
11655   W;
11656   /* NOTREACHED */
11657   return 0;
11658 }
11659
11660 static int
11661 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11662 {
11663   unformat_input_t *i = vam->input;
11664   vl_api_ipsec_interface_add_del_spd_t *mp;
11665   f64 timeout;
11666   u32 sw_if_index;
11667   u8 sw_if_index_set = 0;
11668   u32 spd_id = (u32) ~ 0;
11669   u8 is_add = 1;
11670
11671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11672     {
11673       if (unformat (i, "del"))
11674         is_add = 0;
11675       else if (unformat (i, "spd_id %d", &spd_id))
11676         ;
11677       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11678         sw_if_index_set = 1;
11679       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11680         sw_if_index_set = 1;
11681       else
11682         {
11683           clib_warning ("parse error '%U'", format_unformat_error, i);
11684           return -99;
11685         }
11686
11687     }
11688
11689   if (spd_id == (u32) ~ 0)
11690     {
11691       errmsg ("spd_id must be set\n");
11692       return -99;
11693     }
11694
11695   if (sw_if_index_set == 0)
11696     {
11697       errmsg ("missing interface name or sw_if_index\n");
11698       return -99;
11699     }
11700
11701   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11702
11703   mp->spd_id = ntohl (spd_id);
11704   mp->sw_if_index = ntohl (sw_if_index);
11705   mp->is_add = is_add;
11706
11707   S;
11708   W;
11709   /* NOTREACHED */
11710   return 0;
11711 }
11712
11713 static int
11714 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11715 {
11716   unformat_input_t *i = vam->input;
11717   vl_api_ipsec_spd_add_del_entry_t *mp;
11718   f64 timeout;
11719   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11720   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11721   i32 priority = 0;
11722   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11723   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11724   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11725   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11726
11727   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11728   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11729   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11730   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11731   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11732   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11733
11734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11735     {
11736       if (unformat (i, "del"))
11737         is_add = 0;
11738       if (unformat (i, "outbound"))
11739         is_outbound = 1;
11740       if (unformat (i, "inbound"))
11741         is_outbound = 0;
11742       else if (unformat (i, "spd_id %d", &spd_id))
11743         ;
11744       else if (unformat (i, "sa_id %d", &sa_id))
11745         ;
11746       else if (unformat (i, "priority %d", &priority))
11747         ;
11748       else if (unformat (i, "protocol %d", &protocol))
11749         ;
11750       else if (unformat (i, "lport_start %d", &lport_start))
11751         ;
11752       else if (unformat (i, "lport_stop %d", &lport_stop))
11753         ;
11754       else if (unformat (i, "rport_start %d", &rport_start))
11755         ;
11756       else if (unformat (i, "rport_stop %d", &rport_stop))
11757         ;
11758       else
11759         if (unformat
11760             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11761         {
11762           is_ipv6 = 0;
11763           is_ip_any = 0;
11764         }
11765       else
11766         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11767         {
11768           is_ipv6 = 0;
11769           is_ip_any = 0;
11770         }
11771       else
11772         if (unformat
11773             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11774         {
11775           is_ipv6 = 0;
11776           is_ip_any = 0;
11777         }
11778       else
11779         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11780         {
11781           is_ipv6 = 0;
11782           is_ip_any = 0;
11783         }
11784       else
11785         if (unformat
11786             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11787         {
11788           is_ipv6 = 1;
11789           is_ip_any = 0;
11790         }
11791       else
11792         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11793         {
11794           is_ipv6 = 1;
11795           is_ip_any = 0;
11796         }
11797       else
11798         if (unformat
11799             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11800         {
11801           is_ipv6 = 1;
11802           is_ip_any = 0;
11803         }
11804       else
11805         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11806         {
11807           is_ipv6 = 1;
11808           is_ip_any = 0;
11809         }
11810       else
11811         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11812         {
11813           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11814             {
11815               clib_warning ("unsupported action: 'resolve'");
11816               return -99;
11817             }
11818         }
11819       else
11820         {
11821           clib_warning ("parse error '%U'", format_unformat_error, i);
11822           return -99;
11823         }
11824
11825     }
11826
11827   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11828
11829   mp->spd_id = ntohl (spd_id);
11830   mp->priority = ntohl (priority);
11831   mp->is_outbound = is_outbound;
11832
11833   mp->is_ipv6 = is_ipv6;
11834   if (is_ipv6 || is_ip_any)
11835     {
11836       clib_memcpy (mp->remote_address_start, &raddr6_start,
11837                    sizeof (ip6_address_t));
11838       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11839                    sizeof (ip6_address_t));
11840       clib_memcpy (mp->local_address_start, &laddr6_start,
11841                    sizeof (ip6_address_t));
11842       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11843                    sizeof (ip6_address_t));
11844     }
11845   else
11846     {
11847       clib_memcpy (mp->remote_address_start, &raddr4_start,
11848                    sizeof (ip4_address_t));
11849       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11850                    sizeof (ip4_address_t));
11851       clib_memcpy (mp->local_address_start, &laddr4_start,
11852                    sizeof (ip4_address_t));
11853       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11854                    sizeof (ip4_address_t));
11855     }
11856   mp->protocol = (u8) protocol;
11857   mp->local_port_start = ntohs ((u16) lport_start);
11858   mp->local_port_stop = ntohs ((u16) lport_stop);
11859   mp->remote_port_start = ntohs ((u16) rport_start);
11860   mp->remote_port_stop = ntohs ((u16) rport_stop);
11861   mp->policy = (u8) policy;
11862   mp->sa_id = ntohl (sa_id);
11863   mp->is_add = is_add;
11864   mp->is_ip_any = is_ip_any;
11865   S;
11866   W;
11867   /* NOTREACHED */
11868   return 0;
11869 }
11870
11871 static int
11872 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11873 {
11874   unformat_input_t *i = vam->input;
11875   vl_api_ipsec_sad_add_del_entry_t *mp;
11876   f64 timeout;
11877   u32 sad_id = 0, spi = 0;
11878   u8 *ck = 0, *ik = 0;
11879   u8 is_add = 1;
11880
11881   u8 protocol = IPSEC_PROTOCOL_AH;
11882   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11883   u32 crypto_alg = 0, integ_alg = 0;
11884   ip4_address_t tun_src4;
11885   ip4_address_t tun_dst4;
11886   ip6_address_t tun_src6;
11887   ip6_address_t tun_dst6;
11888
11889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11890     {
11891       if (unformat (i, "del"))
11892         is_add = 0;
11893       else if (unformat (i, "sad_id %d", &sad_id))
11894         ;
11895       else if (unformat (i, "spi %d", &spi))
11896         ;
11897       else if (unformat (i, "esp"))
11898         protocol = IPSEC_PROTOCOL_ESP;
11899       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11900         {
11901           is_tunnel = 1;
11902           is_tunnel_ipv6 = 0;
11903         }
11904       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11905         {
11906           is_tunnel = 1;
11907           is_tunnel_ipv6 = 0;
11908         }
11909       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11910         {
11911           is_tunnel = 1;
11912           is_tunnel_ipv6 = 1;
11913         }
11914       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11915         {
11916           is_tunnel = 1;
11917           is_tunnel_ipv6 = 1;
11918         }
11919       else
11920         if (unformat
11921             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11922         {
11923           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11924               crypto_alg >= IPSEC_CRYPTO_N_ALG)
11925             {
11926               clib_warning ("unsupported crypto-alg: '%U'",
11927                             format_ipsec_crypto_alg, crypto_alg);
11928               return -99;
11929             }
11930         }
11931       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11932         ;
11933       else
11934         if (unformat
11935             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11936         {
11937 #if DPDK_CRYPTO==1
11938           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
11939 #else
11940           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11941 #endif
11942               integ_alg >= IPSEC_INTEG_N_ALG)
11943             {
11944               clib_warning ("unsupported integ-alg: '%U'",
11945                             format_ipsec_integ_alg, integ_alg);
11946               return -99;
11947             }
11948         }
11949       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11950         ;
11951       else
11952         {
11953           clib_warning ("parse error '%U'", format_unformat_error, i);
11954           return -99;
11955         }
11956
11957     }
11958
11959 #if DPDK_CRYPTO==1
11960   /*Special cases, aes-gcm-128 encryption */
11961   if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
11962     {
11963       if (integ_alg != IPSEC_INTEG_ALG_NONE
11964           && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
11965         {
11966           clib_warning
11967             ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
11968           return -99;
11969         }
11970       else                      /*set integ-alg internally to aes-gcm-128 */
11971         integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
11972     }
11973   else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
11974     {
11975       clib_warning ("unsupported integ-alg: aes-gcm-128");
11976       return -99;
11977     }
11978   else if (integ_alg == IPSEC_INTEG_ALG_NONE)
11979     {
11980       clib_warning ("unsupported integ-alg: none");
11981       return -99;
11982     }
11983 #endif
11984
11985
11986   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11987
11988   mp->sad_id = ntohl (sad_id);
11989   mp->is_add = is_add;
11990   mp->protocol = protocol;
11991   mp->spi = ntohl (spi);
11992   mp->is_tunnel = is_tunnel;
11993   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11994   mp->crypto_algorithm = crypto_alg;
11995   mp->integrity_algorithm = integ_alg;
11996   mp->crypto_key_length = vec_len (ck);
11997   mp->integrity_key_length = vec_len (ik);
11998
11999   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12000     mp->crypto_key_length = sizeof (mp->crypto_key);
12001
12002   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12003     mp->integrity_key_length = sizeof (mp->integrity_key);
12004
12005   if (ck)
12006     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12007   if (ik)
12008     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12009
12010   if (is_tunnel)
12011     {
12012       if (is_tunnel_ipv6)
12013         {
12014           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12015                        sizeof (ip6_address_t));
12016           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12017                        sizeof (ip6_address_t));
12018         }
12019       else
12020         {
12021           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12022                        sizeof (ip4_address_t));
12023           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12024                        sizeof (ip4_address_t));
12025         }
12026     }
12027
12028   S;
12029   W;
12030   /* NOTREACHED */
12031   return 0;
12032 }
12033
12034 static int
12035 api_ipsec_sa_set_key (vat_main_t * vam)
12036 {
12037   unformat_input_t *i = vam->input;
12038   vl_api_ipsec_sa_set_key_t *mp;
12039   f64 timeout;
12040   u32 sa_id;
12041   u8 *ck = 0, *ik = 0;
12042
12043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12044     {
12045       if (unformat (i, "sa_id %d", &sa_id))
12046         ;
12047       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12048         ;
12049       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12050         ;
12051       else
12052         {
12053           clib_warning ("parse error '%U'", format_unformat_error, i);
12054           return -99;
12055         }
12056     }
12057
12058   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
12059
12060   mp->sa_id = ntohl (sa_id);
12061   mp->crypto_key_length = vec_len (ck);
12062   mp->integrity_key_length = vec_len (ik);
12063
12064   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12065     mp->crypto_key_length = sizeof (mp->crypto_key);
12066
12067   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12068     mp->integrity_key_length = sizeof (mp->integrity_key);
12069
12070   if (ck)
12071     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12072   if (ik)
12073     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12074
12075   S;
12076   W;
12077   /* NOTREACHED */
12078   return 0;
12079 }
12080
12081 static int
12082 api_ikev2_profile_add_del (vat_main_t * vam)
12083 {
12084   unformat_input_t *i = vam->input;
12085   vl_api_ikev2_profile_add_del_t *mp;
12086   f64 timeout;
12087   u8 is_add = 1;
12088   u8 *name = 0;
12089
12090   const char *valid_chars = "a-zA-Z0-9_";
12091
12092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12093     {
12094       if (unformat (i, "del"))
12095         is_add = 0;
12096       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12097         vec_add1 (name, 0);
12098       else
12099         {
12100           errmsg ("parse error '%U'", format_unformat_error, i);
12101           return -99;
12102         }
12103     }
12104
12105   if (!vec_len (name))
12106     {
12107       errmsg ("profile name must be specified");
12108       return -99;
12109     }
12110
12111   if (vec_len (name) > 64)
12112     {
12113       errmsg ("profile name too long");
12114       return -99;
12115     }
12116
12117   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
12118
12119   clib_memcpy (mp->name, name, vec_len (name));
12120   mp->is_add = is_add;
12121   vec_free (name);
12122
12123   S;
12124   W;
12125   /* NOTREACHED */
12126   return 0;
12127 }
12128
12129 static int
12130 api_ikev2_profile_set_auth (vat_main_t * vam)
12131 {
12132   unformat_input_t *i = vam->input;
12133   vl_api_ikev2_profile_set_auth_t *mp;
12134   f64 timeout;
12135   u8 *name = 0;
12136   u8 *data = 0;
12137   u32 auth_method = 0;
12138   u8 is_hex = 0;
12139
12140   const char *valid_chars = "a-zA-Z0-9_";
12141
12142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12143     {
12144       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12145         vec_add1 (name, 0);
12146       else if (unformat (i, "auth_method %U",
12147                          unformat_ikev2_auth_method, &auth_method))
12148         ;
12149       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12150         is_hex = 1;
12151       else if (unformat (i, "auth_data %v", &data))
12152         ;
12153       else
12154         {
12155           errmsg ("parse error '%U'", format_unformat_error, i);
12156           return -99;
12157         }
12158     }
12159
12160   if (!vec_len (name))
12161     {
12162       errmsg ("profile name must be specified");
12163       return -99;
12164     }
12165
12166   if (vec_len (name) > 64)
12167     {
12168       errmsg ("profile name too long");
12169       return -99;
12170     }
12171
12172   if (!vec_len (data))
12173     {
12174       errmsg ("auth_data must be specified");
12175       return -99;
12176     }
12177
12178   if (!auth_method)
12179     {
12180       errmsg ("auth_method must be specified");
12181       return -99;
12182     }
12183
12184   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12185
12186   mp->is_hex = is_hex;
12187   mp->auth_method = (u8) auth_method;
12188   mp->data_len = vec_len (data);
12189   clib_memcpy (mp->name, name, vec_len (name));
12190   clib_memcpy (mp->data, data, vec_len (data));
12191   vec_free (name);
12192   vec_free (data);
12193
12194   S;
12195   W;
12196   /* NOTREACHED */
12197   return 0;
12198 }
12199
12200 static int
12201 api_ikev2_profile_set_id (vat_main_t * vam)
12202 {
12203   unformat_input_t *i = vam->input;
12204   vl_api_ikev2_profile_set_id_t *mp;
12205   f64 timeout;
12206   u8 *name = 0;
12207   u8 *data = 0;
12208   u8 is_local = 0;
12209   u32 id_type = 0;
12210   ip4_address_t ip4;
12211
12212   const char *valid_chars = "a-zA-Z0-9_";
12213
12214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12215     {
12216       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12217         vec_add1 (name, 0);
12218       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12219         ;
12220       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12221         {
12222           data = vec_new (u8, 4);
12223           clib_memcpy (data, ip4.as_u8, 4);
12224         }
12225       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12226         ;
12227       else if (unformat (i, "id_data %v", &data))
12228         ;
12229       else if (unformat (i, "local"))
12230         is_local = 1;
12231       else if (unformat (i, "remote"))
12232         is_local = 0;
12233       else
12234         {
12235           errmsg ("parse error '%U'", format_unformat_error, i);
12236           return -99;
12237         }
12238     }
12239
12240   if (!vec_len (name))
12241     {
12242       errmsg ("profile name must be specified");
12243       return -99;
12244     }
12245
12246   if (vec_len (name) > 64)
12247     {
12248       errmsg ("profile name too long");
12249       return -99;
12250     }
12251
12252   if (!vec_len (data))
12253     {
12254       errmsg ("id_data must be specified");
12255       return -99;
12256     }
12257
12258   if (!id_type)
12259     {
12260       errmsg ("id_type must be specified");
12261       return -99;
12262     }
12263
12264   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12265
12266   mp->is_local = is_local;
12267   mp->id_type = (u8) id_type;
12268   mp->data_len = vec_len (data);
12269   clib_memcpy (mp->name, name, vec_len (name));
12270   clib_memcpy (mp->data, data, vec_len (data));
12271   vec_free (name);
12272   vec_free (data);
12273
12274   S;
12275   W;
12276   /* NOTREACHED */
12277   return 0;
12278 }
12279
12280 static int
12281 api_ikev2_profile_set_ts (vat_main_t * vam)
12282 {
12283   unformat_input_t *i = vam->input;
12284   vl_api_ikev2_profile_set_ts_t *mp;
12285   f64 timeout;
12286   u8 *name = 0;
12287   u8 is_local = 0;
12288   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12289   ip4_address_t start_addr, end_addr;
12290
12291   const char *valid_chars = "a-zA-Z0-9_";
12292
12293   start_addr.as_u32 = 0;
12294   end_addr.as_u32 = (u32) ~ 0;
12295
12296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12297     {
12298       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12299         vec_add1 (name, 0);
12300       else if (unformat (i, "protocol %d", &proto))
12301         ;
12302       else if (unformat (i, "start_port %d", &start_port))
12303         ;
12304       else if (unformat (i, "end_port %d", &end_port))
12305         ;
12306       else
12307         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12308         ;
12309       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12310         ;
12311       else if (unformat (i, "local"))
12312         is_local = 1;
12313       else if (unformat (i, "remote"))
12314         is_local = 0;
12315       else
12316         {
12317           errmsg ("parse error '%U'", format_unformat_error, i);
12318           return -99;
12319         }
12320     }
12321
12322   if (!vec_len (name))
12323     {
12324       errmsg ("profile name must be specified");
12325       return -99;
12326     }
12327
12328   if (vec_len (name) > 64)
12329     {
12330       errmsg ("profile name too long");
12331       return -99;
12332     }
12333
12334   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12335
12336   mp->is_local = is_local;
12337   mp->proto = (u8) proto;
12338   mp->start_port = (u16) start_port;
12339   mp->end_port = (u16) end_port;
12340   mp->start_addr = start_addr.as_u32;
12341   mp->end_addr = end_addr.as_u32;
12342   clib_memcpy (mp->name, name, vec_len (name));
12343   vec_free (name);
12344
12345   S;
12346   W;
12347   /* NOTREACHED */
12348   return 0;
12349 }
12350
12351 static int
12352 api_ikev2_set_local_key (vat_main_t * vam)
12353 {
12354   unformat_input_t *i = vam->input;
12355   vl_api_ikev2_set_local_key_t *mp;
12356   f64 timeout;
12357   u8 *file = 0;
12358
12359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12360     {
12361       if (unformat (i, "file %v", &file))
12362         vec_add1 (file, 0);
12363       else
12364         {
12365           errmsg ("parse error '%U'", format_unformat_error, i);
12366           return -99;
12367         }
12368     }
12369
12370   if (!vec_len (file))
12371     {
12372       errmsg ("RSA key file must be specified");
12373       return -99;
12374     }
12375
12376   if (vec_len (file) > 256)
12377     {
12378       errmsg ("file name too long");
12379       return -99;
12380     }
12381
12382   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12383
12384   clib_memcpy (mp->key_file, file, vec_len (file));
12385   vec_free (file);
12386
12387   S;
12388   W;
12389   /* NOTREACHED */
12390   return 0;
12391 }
12392
12393 /*
12394  * MAP
12395  */
12396 static int
12397 api_map_add_domain (vat_main_t * vam)
12398 {
12399   unformat_input_t *i = vam->input;
12400   vl_api_map_add_domain_t *mp;
12401   f64 timeout;
12402
12403   ip4_address_t ip4_prefix;
12404   ip6_address_t ip6_prefix;
12405   ip6_address_t ip6_src;
12406   u32 num_m_args = 0;
12407   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12408     0, psid_length = 0;
12409   u8 is_translation = 0;
12410   u32 mtu = 0;
12411   u32 ip6_src_len = 128;
12412
12413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12414     {
12415       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12416                     &ip4_prefix, &ip4_prefix_len))
12417         num_m_args++;
12418       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12419                          &ip6_prefix, &ip6_prefix_len))
12420         num_m_args++;
12421       else
12422         if (unformat
12423             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12424              &ip6_src_len))
12425         num_m_args++;
12426       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12427         num_m_args++;
12428       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12429         num_m_args++;
12430       else if (unformat (i, "psid-offset %d", &psid_offset))
12431         num_m_args++;
12432       else if (unformat (i, "psid-len %d", &psid_length))
12433         num_m_args++;
12434       else if (unformat (i, "mtu %d", &mtu))
12435         num_m_args++;
12436       else if (unformat (i, "map-t"))
12437         is_translation = 1;
12438       else
12439         {
12440           clib_warning ("parse error '%U'", format_unformat_error, i);
12441           return -99;
12442         }
12443     }
12444
12445   if (num_m_args < 3)
12446     {
12447       errmsg ("mandatory argument(s) missing\n");
12448       return -99;
12449     }
12450
12451   /* Construct the API message */
12452   M (MAP_ADD_DOMAIN, map_add_domain);
12453
12454   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12455   mp->ip4_prefix_len = ip4_prefix_len;
12456
12457   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12458   mp->ip6_prefix_len = ip6_prefix_len;
12459
12460   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12461   mp->ip6_src_prefix_len = ip6_src_len;
12462
12463   mp->ea_bits_len = ea_bits_len;
12464   mp->psid_offset = psid_offset;
12465   mp->psid_length = psid_length;
12466   mp->is_translation = is_translation;
12467   mp->mtu = htons (mtu);
12468
12469   /* send it... */
12470   S;
12471
12472   /* Wait for a reply, return good/bad news  */
12473   W;
12474 }
12475
12476 static int
12477 api_map_del_domain (vat_main_t * vam)
12478 {
12479   unformat_input_t *i = vam->input;
12480   vl_api_map_del_domain_t *mp;
12481   f64 timeout;
12482
12483   u32 num_m_args = 0;
12484   u32 index;
12485
12486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12487     {
12488       if (unformat (i, "index %d", &index))
12489         num_m_args++;
12490       else
12491         {
12492           clib_warning ("parse error '%U'", format_unformat_error, i);
12493           return -99;
12494         }
12495     }
12496
12497   if (num_m_args != 1)
12498     {
12499       errmsg ("mandatory argument(s) missing\n");
12500       return -99;
12501     }
12502
12503   /* Construct the API message */
12504   M (MAP_DEL_DOMAIN, map_del_domain);
12505
12506   mp->index = ntohl (index);
12507
12508   /* send it... */
12509   S;
12510
12511   /* Wait for a reply, return good/bad news  */
12512   W;
12513 }
12514
12515 static int
12516 api_map_add_del_rule (vat_main_t * vam)
12517 {
12518   unformat_input_t *i = vam->input;
12519   vl_api_map_add_del_rule_t *mp;
12520   f64 timeout;
12521   u8 is_add = 1;
12522   ip6_address_t ip6_dst;
12523   u32 num_m_args = 0, index, psid = 0;
12524
12525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12526     {
12527       if (unformat (i, "index %d", &index))
12528         num_m_args++;
12529       else if (unformat (i, "psid %d", &psid))
12530         num_m_args++;
12531       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12532         num_m_args++;
12533       else if (unformat (i, "del"))
12534         {
12535           is_add = 0;
12536         }
12537       else
12538         {
12539           clib_warning ("parse error '%U'", format_unformat_error, i);
12540           return -99;
12541         }
12542     }
12543
12544   /* Construct the API message */
12545   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12546
12547   mp->index = ntohl (index);
12548   mp->is_add = is_add;
12549   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12550   mp->psid = ntohs (psid);
12551
12552   /* send it... */
12553   S;
12554
12555   /* Wait for a reply, return good/bad news  */
12556   W;
12557 }
12558
12559 static int
12560 api_map_domain_dump (vat_main_t * vam)
12561 {
12562   vl_api_map_domain_dump_t *mp;
12563   f64 timeout;
12564
12565   /* Construct the API message */
12566   M (MAP_DOMAIN_DUMP, map_domain_dump);
12567
12568   /* send it... */
12569   S;
12570
12571   /* Use a control ping for synchronization */
12572   {
12573     vl_api_control_ping_t *mp;
12574     M (CONTROL_PING, control_ping);
12575     S;
12576   }
12577   W;
12578 }
12579
12580 static int
12581 api_map_rule_dump (vat_main_t * vam)
12582 {
12583   unformat_input_t *i = vam->input;
12584   vl_api_map_rule_dump_t *mp;
12585   f64 timeout;
12586   u32 domain_index = ~0;
12587
12588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12589     {
12590       if (unformat (i, "index %u", &domain_index))
12591         ;
12592       else
12593         break;
12594     }
12595
12596   if (domain_index == ~0)
12597     {
12598       clib_warning ("parse error: domain index expected");
12599       return -99;
12600     }
12601
12602   /* Construct the API message */
12603   M (MAP_RULE_DUMP, map_rule_dump);
12604
12605   mp->domain_index = htonl (domain_index);
12606
12607   /* send it... */
12608   S;
12609
12610   /* Use a control ping for synchronization */
12611   {
12612     vl_api_control_ping_t *mp;
12613     M (CONTROL_PING, control_ping);
12614     S;
12615   }
12616   W;
12617 }
12618
12619 static void vl_api_map_add_domain_reply_t_handler
12620   (vl_api_map_add_domain_reply_t * mp)
12621 {
12622   vat_main_t *vam = &vat_main;
12623   i32 retval = ntohl (mp->retval);
12624
12625   if (vam->async_mode)
12626     {
12627       vam->async_errors += (retval < 0);
12628     }
12629   else
12630     {
12631       vam->retval = retval;
12632       vam->result_ready = 1;
12633     }
12634 }
12635
12636 static void vl_api_map_add_domain_reply_t_handler_json
12637   (vl_api_map_add_domain_reply_t * mp)
12638 {
12639   vat_main_t *vam = &vat_main;
12640   vat_json_node_t node;
12641
12642   vat_json_init_object (&node);
12643   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12644   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12645
12646   vat_json_print (vam->ofp, &node);
12647   vat_json_free (&node);
12648
12649   vam->retval = ntohl (mp->retval);
12650   vam->result_ready = 1;
12651 }
12652
12653 static int
12654 api_get_first_msg_id (vat_main_t * vam)
12655 {
12656   vl_api_get_first_msg_id_t *mp;
12657   f64 timeout;
12658   unformat_input_t *i = vam->input;
12659   u8 *name;
12660   u8 name_set = 0;
12661
12662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12663     {
12664       if (unformat (i, "client %s", &name))
12665         name_set = 1;
12666       else
12667         break;
12668     }
12669
12670   if (name_set == 0)
12671     {
12672       errmsg ("missing client name\n");
12673       return -99;
12674     }
12675   vec_add1 (name, 0);
12676
12677   if (vec_len (name) > 63)
12678     {
12679       errmsg ("client name too long\n");
12680       return -99;
12681     }
12682
12683   M (GET_FIRST_MSG_ID, get_first_msg_id);
12684   clib_memcpy (mp->name, name, vec_len (name));
12685   S;
12686   W;
12687   /* NOTREACHED */
12688   return 0;
12689 }
12690
12691 static int
12692 api_cop_interface_enable_disable (vat_main_t * vam)
12693 {
12694   unformat_input_t *line_input = vam->input;
12695   vl_api_cop_interface_enable_disable_t *mp;
12696   f64 timeout;
12697   u32 sw_if_index = ~0;
12698   u8 enable_disable = 1;
12699
12700   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12701     {
12702       if (unformat (line_input, "disable"))
12703         enable_disable = 0;
12704       if (unformat (line_input, "enable"))
12705         enable_disable = 1;
12706       else if (unformat (line_input, "%U", unformat_sw_if_index,
12707                          vam, &sw_if_index))
12708         ;
12709       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12710         ;
12711       else
12712         break;
12713     }
12714
12715   if (sw_if_index == ~0)
12716     {
12717       errmsg ("missing interface name or sw_if_index\n");
12718       return -99;
12719     }
12720
12721   /* Construct the API message */
12722   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12723   mp->sw_if_index = ntohl (sw_if_index);
12724   mp->enable_disable = enable_disable;
12725
12726   /* send it... */
12727   S;
12728   /* Wait for the reply */
12729   W;
12730 }
12731
12732 static int
12733 api_cop_whitelist_enable_disable (vat_main_t * vam)
12734 {
12735   unformat_input_t *line_input = vam->input;
12736   vl_api_cop_whitelist_enable_disable_t *mp;
12737   f64 timeout;
12738   u32 sw_if_index = ~0;
12739   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12740   u32 fib_id = 0;
12741
12742   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12743     {
12744       if (unformat (line_input, "ip4"))
12745         ip4 = 1;
12746       else if (unformat (line_input, "ip6"))
12747         ip6 = 1;
12748       else if (unformat (line_input, "default"))
12749         default_cop = 1;
12750       else if (unformat (line_input, "%U", unformat_sw_if_index,
12751                          vam, &sw_if_index))
12752         ;
12753       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12754         ;
12755       else if (unformat (line_input, "fib-id %d", &fib_id))
12756         ;
12757       else
12758         break;
12759     }
12760
12761   if (sw_if_index == ~0)
12762     {
12763       errmsg ("missing interface name or sw_if_index\n");
12764       return -99;
12765     }
12766
12767   /* Construct the API message */
12768   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12769   mp->sw_if_index = ntohl (sw_if_index);
12770   mp->fib_id = ntohl (fib_id);
12771   mp->ip4 = ip4;
12772   mp->ip6 = ip6;
12773   mp->default_cop = default_cop;
12774
12775   /* send it... */
12776   S;
12777   /* Wait for the reply */
12778   W;
12779 }
12780
12781 static int
12782 api_get_node_graph (vat_main_t * vam)
12783 {
12784   vl_api_get_node_graph_t *mp;
12785   f64 timeout;
12786
12787   M (GET_NODE_GRAPH, get_node_graph);
12788
12789   /* send it... */
12790   S;
12791   /* Wait for the reply */
12792   W;
12793 }
12794
12795 /* *INDENT-OFF* */
12796 /** Used for parsing LISP eids */
12797 typedef CLIB_PACKED(struct{
12798   u8 addr[16];   /**< eid address */
12799   u32 len;       /**< prefix length if IP */
12800   u8 type;      /**< type of eid */
12801 }) lisp_eid_vat_t;
12802 /* *INDENT-ON* */
12803
12804 static uword
12805 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12806 {
12807   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12808
12809   memset (a, 0, sizeof (a[0]));
12810
12811   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12812     {
12813       a->type = 0;              /* ipv4 type */
12814     }
12815   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12816     {
12817       a->type = 1;              /* ipv6 type */
12818     }
12819   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12820     {
12821       a->type = 2;              /* mac type */
12822     }
12823   else
12824     {
12825       return 0;
12826     }
12827
12828   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12829     {
12830       return 0;
12831     }
12832
12833   return 1;
12834 }
12835
12836 static int
12837 lisp_eid_size_vat (u8 type)
12838 {
12839   switch (type)
12840     {
12841     case 0:
12842       return 4;
12843     case 1:
12844       return 16;
12845     case 2:
12846       return 6;
12847     }
12848   return 0;
12849 }
12850
12851 static void
12852 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12853 {
12854   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12855 }
12856
12857 /* *INDENT-OFF* */
12858 /** Used for transferring locators via VPP API */
12859 typedef CLIB_PACKED(struct
12860 {
12861   u32 sw_if_index; /**< locator sw_if_index */
12862   u8 priority; /**< locator priority */
12863   u8 weight;   /**< locator weight */
12864 }) ls_locator_t;
12865 /* *INDENT-ON* */
12866
12867 static int
12868 api_lisp_add_del_locator_set (vat_main_t * vam)
12869 {
12870   unformat_input_t *input = vam->input;
12871   vl_api_lisp_add_del_locator_set_t *mp;
12872   f64 timeout = ~0;
12873   u8 is_add = 1;
12874   u8 *locator_set_name = NULL;
12875   u8 locator_set_name_set = 0;
12876   ls_locator_t locator, *locators = 0;
12877   u32 sw_if_index, priority, weight;
12878   u32 data_len = 0;
12879
12880   /* Parse args required to build the message */
12881   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12882     {
12883       if (unformat (input, "del"))
12884         {
12885           is_add = 0;
12886         }
12887       else if (unformat (input, "locator-set %s", &locator_set_name))
12888         {
12889           locator_set_name_set = 1;
12890         }
12891       else if (unformat (input, "sw_if_index %u p %u w %u",
12892                          &sw_if_index, &priority, &weight))
12893         {
12894           locator.sw_if_index = htonl (sw_if_index);
12895           locator.priority = priority;
12896           locator.weight = weight;
12897           vec_add1 (locators, locator);
12898         }
12899       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12900                          vam, &sw_if_index, &priority, &weight))
12901         {
12902           locator.sw_if_index = htonl (sw_if_index);
12903           locator.priority = priority;
12904           locator.weight = weight;
12905           vec_add1 (locators, locator);
12906         }
12907       else
12908         break;
12909     }
12910
12911   if (locator_set_name_set == 0)
12912     {
12913       errmsg ("missing locator-set name");
12914       vec_free (locators);
12915       return -99;
12916     }
12917
12918   if (vec_len (locator_set_name) > 64)
12919     {
12920       errmsg ("locator-set name too long\n");
12921       vec_free (locator_set_name);
12922       vec_free (locators);
12923       return -99;
12924     }
12925   vec_add1 (locator_set_name, 0);
12926
12927   data_len = sizeof (ls_locator_t) * vec_len (locators);
12928
12929   /* Construct the API message */
12930   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12931
12932   mp->is_add = is_add;
12933   clib_memcpy (mp->locator_set_name, locator_set_name,
12934                vec_len (locator_set_name));
12935   vec_free (locator_set_name);
12936
12937   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12938   if (locators)
12939     clib_memcpy (mp->locators, locators, data_len);
12940   vec_free (locators);
12941
12942   /* send it... */
12943   S;
12944
12945   /* Wait for a reply... */
12946   W;
12947
12948   /* NOTREACHED */
12949   return 0;
12950 }
12951
12952 static int
12953 api_lisp_add_del_locator (vat_main_t * vam)
12954 {
12955   unformat_input_t *input = vam->input;
12956   vl_api_lisp_add_del_locator_t *mp;
12957   f64 timeout = ~0;
12958   u32 tmp_if_index = ~0;
12959   u32 sw_if_index = ~0;
12960   u8 sw_if_index_set = 0;
12961   u8 sw_if_index_if_name_set = 0;
12962   u32 priority = ~0;
12963   u8 priority_set = 0;
12964   u32 weight = ~0;
12965   u8 weight_set = 0;
12966   u8 is_add = 1;
12967   u8 *locator_set_name = NULL;
12968   u8 locator_set_name_set = 0;
12969
12970   /* Parse args required to build the message */
12971   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12972     {
12973       if (unformat (input, "del"))
12974         {
12975           is_add = 0;
12976         }
12977       else if (unformat (input, "locator-set %s", &locator_set_name))
12978         {
12979           locator_set_name_set = 1;
12980         }
12981       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12982                          &tmp_if_index))
12983         {
12984           sw_if_index_if_name_set = 1;
12985           sw_if_index = tmp_if_index;
12986         }
12987       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12988         {
12989           sw_if_index_set = 1;
12990           sw_if_index = tmp_if_index;
12991         }
12992       else if (unformat (input, "p %d", &priority))
12993         {
12994           priority_set = 1;
12995         }
12996       else if (unformat (input, "w %d", &weight))
12997         {
12998           weight_set = 1;
12999         }
13000       else
13001         break;
13002     }
13003
13004   if (locator_set_name_set == 0)
13005     {
13006       errmsg ("missing locator-set name");
13007       return -99;
13008     }
13009
13010   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13011     {
13012       errmsg ("missing sw_if_index");
13013       vec_free (locator_set_name);
13014       return -99;
13015     }
13016
13017   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13018     {
13019       errmsg ("cannot use both params interface name and sw_if_index");
13020       vec_free (locator_set_name);
13021       return -99;
13022     }
13023
13024   if (priority_set == 0)
13025     {
13026       errmsg ("missing locator-set priority\n");
13027       vec_free (locator_set_name);
13028       return -99;
13029     }
13030
13031   if (weight_set == 0)
13032     {
13033       errmsg ("missing locator-set weight\n");
13034       vec_free (locator_set_name);
13035       return -99;
13036     }
13037
13038   if (vec_len (locator_set_name) > 64)
13039     {
13040       errmsg ("locator-set name too long\n");
13041       vec_free (locator_set_name);
13042       return -99;
13043     }
13044   vec_add1 (locator_set_name, 0);
13045
13046   /* Construct the API message */
13047   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
13048
13049   mp->is_add = is_add;
13050   mp->sw_if_index = ntohl (sw_if_index);
13051   mp->priority = priority;
13052   mp->weight = weight;
13053   clib_memcpy (mp->locator_set_name, locator_set_name,
13054                vec_len (locator_set_name));
13055   vec_free (locator_set_name);
13056
13057   /* send it... */
13058   S;
13059
13060   /* Wait for a reply... */
13061   W;
13062
13063   /* NOTREACHED */
13064   return 0;
13065 }
13066
13067 uword
13068 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13069 {
13070   u32 *key_id = va_arg (*args, u32 *);
13071   u8 *s = 0;
13072
13073   if (unformat (input, "%s", &s))
13074     {
13075       if (!strcmp ((char *) s, "sha1"))
13076         key_id[0] = HMAC_SHA_1_96;
13077       else if (!strcmp ((char *) s, "sha256"))
13078         key_id[0] = HMAC_SHA_256_128;
13079       else
13080         {
13081           clib_warning ("invalid key_id: '%s'", s);
13082           key_id[0] = HMAC_NO_KEY;
13083         }
13084     }
13085   else
13086     return 0;
13087
13088   vec_free (s);
13089   return 1;
13090 }
13091
13092 static int
13093 api_lisp_add_del_local_eid (vat_main_t * vam)
13094 {
13095   unformat_input_t *input = vam->input;
13096   vl_api_lisp_add_del_local_eid_t *mp;
13097   f64 timeout = ~0;
13098   u8 is_add = 1;
13099   u8 eid_set = 0;
13100   lisp_eid_vat_t _eid, *eid = &_eid;
13101   u8 *locator_set_name = 0;
13102   u8 locator_set_name_set = 0;
13103   u32 vni = 0;
13104   u16 key_id = 0;
13105   u8 *key = 0;
13106
13107   /* Parse args required to build the message */
13108   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13109     {
13110       if (unformat (input, "del"))
13111         {
13112           is_add = 0;
13113         }
13114       else if (unformat (input, "vni %d", &vni))
13115         {
13116           ;
13117         }
13118       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13119         {
13120           eid_set = 1;
13121         }
13122       else if (unformat (input, "locator-set %s", &locator_set_name))
13123         {
13124           locator_set_name_set = 1;
13125         }
13126       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13127         ;
13128       else if (unformat (input, "secret-key %_%v%_", &key))
13129         ;
13130       else
13131         break;
13132     }
13133
13134   if (locator_set_name_set == 0)
13135     {
13136       errmsg ("missing locator-set name\n");
13137       return -99;
13138     }
13139
13140   if (0 == eid_set)
13141     {
13142       errmsg ("EID address not set!");
13143       vec_free (locator_set_name);
13144       return -99;
13145     }
13146
13147   if (key && (0 == key_id))
13148     {
13149       errmsg ("invalid key_id!");
13150       return -99;
13151     }
13152
13153   if (vec_len (key) > 64)
13154     {
13155       errmsg ("key too long");
13156       vec_free (key);
13157       return -99;
13158     }
13159
13160   if (vec_len (locator_set_name) > 64)
13161     {
13162       errmsg ("locator-set name too long\n");
13163       vec_free (locator_set_name);
13164       return -99;
13165     }
13166   vec_add1 (locator_set_name, 0);
13167
13168   /* Construct the API message */
13169   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
13170
13171   mp->is_add = is_add;
13172   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13173   mp->eid_type = eid->type;
13174   mp->prefix_len = eid->len;
13175   mp->vni = clib_host_to_net_u32 (vni);
13176   mp->key_id = clib_host_to_net_u16 (key_id);
13177   clib_memcpy (mp->locator_set_name, locator_set_name,
13178                vec_len (locator_set_name));
13179   clib_memcpy (mp->key, key, vec_len (key));
13180
13181   vec_free (locator_set_name);
13182   vec_free (key);
13183
13184   /* send it... */
13185   S;
13186
13187   /* Wait for a reply... */
13188   W;
13189
13190   /* NOTREACHED */
13191   return 0;
13192 }
13193
13194 /* *INDENT-OFF* */
13195 /** Used for transferring locators via VPP API */
13196 typedef CLIB_PACKED(struct
13197 {
13198   u8 is_ip4; /**< is locator an IPv4 address? */
13199   u8 priority; /**< locator priority */
13200   u8 weight;   /**< locator weight */
13201   u8 addr[16]; /**< IPv4/IPv6 address */
13202 }) rloc_t;
13203 /* *INDENT-ON* */
13204
13205 static int
13206 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13207 {
13208   unformat_input_t *input = vam->input;
13209   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13210   f64 timeout = ~0;
13211   u8 is_add = 1;
13212   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13213   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13214   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13215   u32 action = ~0, p, w;
13216   ip4_address_t rmt_rloc4, lcl_rloc4;
13217   ip6_address_t rmt_rloc6, lcl_rloc6;
13218   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13219
13220   memset (&rloc, 0, sizeof (rloc));
13221
13222   /* Parse args required to build the message */
13223   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13224     {
13225       if (unformat (input, "del"))
13226         {
13227           is_add = 0;
13228         }
13229       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
13230         {
13231           rmt_eid_set = 1;
13232         }
13233       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
13234         {
13235           lcl_eid_set = 1;
13236         }
13237       else if (unformat (input, "p %d w %d", &p, &w))
13238         {
13239           if (!curr_rloc)
13240             {
13241               errmsg ("No RLOC configured for setting priority/weight!");
13242               return -99;
13243             }
13244           curr_rloc->priority = p;
13245           curr_rloc->weight = w;
13246         }
13247       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13248                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13249         {
13250           rloc.is_ip4 = 1;
13251
13252           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13253           rloc.priority = rloc.weight = 0;
13254           vec_add1 (lcl_locs, rloc);
13255
13256           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13257           vec_add1 (rmt_locs, rloc);
13258           /* priority and weight saved in rmt loc */
13259           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13260         }
13261       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13262                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13263         {
13264           rloc.is_ip4 = 0;
13265           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13266           rloc.priority = rloc.weight = 0;
13267           vec_add1 (lcl_locs, rloc);
13268
13269           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13270           vec_add1 (rmt_locs, rloc);
13271           /* priority and weight saved in rmt loc */
13272           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13273         }
13274       else if (unformat (input, "action %d", &action))
13275         {
13276           ;
13277         }
13278       else
13279         {
13280           clib_warning ("parse error '%U'", format_unformat_error, input);
13281           return -99;
13282         }
13283     }
13284
13285   if (!rmt_eid_set)
13286     {
13287       errmsg ("remote eid addresses not set\n");
13288       return -99;
13289     }
13290
13291   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13292     {
13293       errmsg ("eid types don't match\n");
13294       return -99;
13295     }
13296
13297   if (0 == rmt_locs && (u32) ~ 0 == action)
13298     {
13299       errmsg ("action not set for negative mapping\n");
13300       return -99;
13301     }
13302
13303   /* Construct the API message */
13304   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13305
13306   mp->is_add = is_add;
13307   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13308   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13309   mp->eid_type = rmt_eid->type;
13310   mp->rmt_len = rmt_eid->len;
13311   mp->lcl_len = lcl_eid->len;
13312   mp->action = action;
13313
13314   if (0 != rmt_locs && 0 != lcl_locs)
13315     {
13316       mp->loc_num = vec_len (rmt_locs);
13317       clib_memcpy (mp->lcl_locs, lcl_locs,
13318                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13319       clib_memcpy (mp->rmt_locs, rmt_locs,
13320                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13321     }
13322   vec_free (lcl_locs);
13323   vec_free (rmt_locs);
13324
13325   /* send it... */
13326   S;
13327
13328   /* Wait for a reply... */
13329   W;
13330
13331   /* NOTREACHED */
13332   return 0;
13333 }
13334
13335 static int
13336 api_lisp_add_del_map_server (vat_main_t * vam)
13337 {
13338   unformat_input_t *input = vam->input;
13339   vl_api_lisp_add_del_map_server_t *mp;
13340   f64 timeout = ~0;
13341   u8 is_add = 1;
13342   u8 ipv4_set = 0;
13343   u8 ipv6_set = 0;
13344   ip4_address_t ipv4;
13345   ip6_address_t ipv6;
13346
13347   /* Parse args required to build the message */
13348   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13349     {
13350       if (unformat (input, "del"))
13351         {
13352           is_add = 0;
13353         }
13354       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13355         {
13356           ipv4_set = 1;
13357         }
13358       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13359         {
13360           ipv6_set = 1;
13361         }
13362       else
13363         break;
13364     }
13365
13366   if (ipv4_set && ipv6_set)
13367     {
13368       errmsg ("both eid v4 and v6 addresses set\n");
13369       return -99;
13370     }
13371
13372   if (!ipv4_set && !ipv6_set)
13373     {
13374       errmsg ("eid addresses not set\n");
13375       return -99;
13376     }
13377
13378   /* Construct the API message */
13379   M (LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server);
13380
13381   mp->is_add = is_add;
13382   if (ipv6_set)
13383     {
13384       mp->is_ipv6 = 1;
13385       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13386     }
13387   else
13388     {
13389       mp->is_ipv6 = 0;
13390       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13391     }
13392
13393   /* send it... */
13394   S;
13395
13396   /* Wait for a reply... */
13397   W;
13398
13399   /* NOTREACHED */
13400   return 0;
13401 }
13402
13403 static int
13404 api_lisp_add_del_map_resolver (vat_main_t * vam)
13405 {
13406   unformat_input_t *input = vam->input;
13407   vl_api_lisp_add_del_map_resolver_t *mp;
13408   f64 timeout = ~0;
13409   u8 is_add = 1;
13410   u8 ipv4_set = 0;
13411   u8 ipv6_set = 0;
13412   ip4_address_t ipv4;
13413   ip6_address_t ipv6;
13414
13415   /* Parse args required to build the message */
13416   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13417     {
13418       if (unformat (input, "del"))
13419         {
13420           is_add = 0;
13421         }
13422       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13423         {
13424           ipv4_set = 1;
13425         }
13426       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13427         {
13428           ipv6_set = 1;
13429         }
13430       else
13431         break;
13432     }
13433
13434   if (ipv4_set && ipv6_set)
13435     {
13436       errmsg ("both eid v4 and v6 addresses set\n");
13437       return -99;
13438     }
13439
13440   if (!ipv4_set && !ipv6_set)
13441     {
13442       errmsg ("eid addresses not set\n");
13443       return -99;
13444     }
13445
13446   /* Construct the API message */
13447   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13448
13449   mp->is_add = is_add;
13450   if (ipv6_set)
13451     {
13452       mp->is_ipv6 = 1;
13453       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13454     }
13455   else
13456     {
13457       mp->is_ipv6 = 0;
13458       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13459     }
13460
13461   /* send it... */
13462   S;
13463
13464   /* Wait for a reply... */
13465   W;
13466
13467   /* NOTREACHED */
13468   return 0;
13469 }
13470
13471 static int
13472 api_lisp_gpe_enable_disable (vat_main_t * vam)
13473 {
13474   unformat_input_t *input = vam->input;
13475   vl_api_lisp_gpe_enable_disable_t *mp;
13476   f64 timeout = ~0;
13477   u8 is_set = 0;
13478   u8 is_en = 1;
13479
13480   /* Parse args required to build the message */
13481   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13482     {
13483       if (unformat (input, "enable"))
13484         {
13485           is_set = 1;
13486           is_en = 1;
13487         }
13488       else if (unformat (input, "disable"))
13489         {
13490           is_set = 1;
13491           is_en = 0;
13492         }
13493       else
13494         break;
13495     }
13496
13497   if (is_set == 0)
13498     {
13499       errmsg ("Value not set\n");
13500       return -99;
13501     }
13502
13503   /* Construct the API message */
13504   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13505
13506   mp->is_en = is_en;
13507
13508   /* send it... */
13509   S;
13510
13511   /* Wait for a reply... */
13512   W;
13513
13514   /* NOTREACHED */
13515   return 0;
13516 }
13517
13518 static int
13519 api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
13520 {
13521   unformat_input_t *input = vam->input;
13522   vl_api_lisp_rloc_probe_enable_disable_t *mp;
13523   f64 timeout = ~0;
13524   u8 is_set = 0;
13525   u8 is_en = 0;
13526
13527   /* Parse args required to build the message */
13528   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13529     {
13530       if (unformat (input, "enable"))
13531         {
13532           is_set = 1;
13533           is_en = 1;
13534         }
13535       else if (unformat (input, "disable"))
13536         is_set = 1;
13537       else
13538         break;
13539     }
13540
13541   if (!is_set)
13542     {
13543       errmsg ("Value not set\n");
13544       return -99;
13545     }
13546
13547   /* Construct the API message */
13548   M (LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable);
13549
13550   mp->is_enabled = is_en;
13551
13552   /* send it... */
13553   S;
13554
13555   /* Wait for a reply... */
13556   W;
13557
13558   /* NOTREACHED */
13559   return 0;
13560 }
13561
13562 static int
13563 api_lisp_map_register_enable_disable (vat_main_t * vam)
13564 {
13565   unformat_input_t *input = vam->input;
13566   vl_api_lisp_map_register_enable_disable_t *mp;
13567   f64 timeout = ~0;
13568   u8 is_set = 0;
13569   u8 is_en = 0;
13570
13571   /* Parse args required to build the message */
13572   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13573     {
13574       if (unformat (input, "enable"))
13575         {
13576           is_set = 1;
13577           is_en = 1;
13578         }
13579       else if (unformat (input, "disable"))
13580         is_set = 1;
13581       else
13582         break;
13583     }
13584
13585   if (!is_set)
13586     {
13587       errmsg ("Value not set\n");
13588       return -99;
13589     }
13590
13591   /* Construct the API message */
13592   M (LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable);
13593
13594   mp->is_enabled = is_en;
13595
13596   /* send it... */
13597   S;
13598
13599   /* Wait for a reply... */
13600   W;
13601
13602   /* NOTREACHED */
13603   return 0;
13604 }
13605
13606 static int
13607 api_lisp_enable_disable (vat_main_t * vam)
13608 {
13609   unformat_input_t *input = vam->input;
13610   vl_api_lisp_enable_disable_t *mp;
13611   f64 timeout = ~0;
13612   u8 is_set = 0;
13613   u8 is_en = 0;
13614
13615   /* Parse args required to build the message */
13616   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13617     {
13618       if (unformat (input, "enable"))
13619         {
13620           is_set = 1;
13621           is_en = 1;
13622         }
13623       else if (unformat (input, "disable"))
13624         {
13625           is_set = 1;
13626         }
13627       else
13628         break;
13629     }
13630
13631   if (!is_set)
13632     {
13633       errmsg ("Value not set\n");
13634       return -99;
13635     }
13636
13637   /* Construct the API message */
13638   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13639
13640   mp->is_en = is_en;
13641
13642   /* send it... */
13643   S;
13644
13645   /* Wait for a reply... */
13646   W;
13647
13648   /* NOTREACHED */
13649   return 0;
13650 }
13651
13652 static int
13653 api_show_lisp_map_register_state (vat_main_t * vam)
13654 {
13655   f64 timeout = ~0;
13656   vl_api_show_lisp_map_register_state_t *mp;
13657
13658   M (SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state);
13659
13660   /* send */
13661   S;
13662
13663   /* wait for reply */
13664   W;
13665
13666   return 0;
13667 }
13668
13669 static int
13670 api_show_lisp_rloc_probe_state (vat_main_t * vam)
13671 {
13672   f64 timeout = ~0;
13673   vl_api_show_lisp_rloc_probe_state_t *mp;
13674
13675   M (SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state);
13676
13677   /* send */
13678   S;
13679
13680   /* wait for reply */
13681   W;
13682
13683   return 0;
13684 }
13685
13686 static int
13687 api_show_lisp_map_request_mode (vat_main_t * vam)
13688 {
13689   f64 timeout = ~0;
13690   vl_api_show_lisp_map_request_mode_t *mp;
13691
13692   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13693
13694   /* send */
13695   S;
13696
13697   /* wait for reply */
13698   W;
13699
13700   return 0;
13701 }
13702
13703 static int
13704 api_lisp_map_request_mode (vat_main_t * vam)
13705 {
13706   f64 timeout = ~0;
13707   unformat_input_t *input = vam->input;
13708   vl_api_lisp_map_request_mode_t *mp;
13709   u8 mode = 0;
13710
13711   /* Parse args required to build the message */
13712   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13713     {
13714       if (unformat (input, "dst-only"))
13715         mode = 0;
13716       else if (unformat (input, "src-dst"))
13717         mode = 1;
13718       else
13719         {
13720           errmsg ("parse error '%U'", format_unformat_error, input);
13721           return -99;
13722         }
13723     }
13724
13725   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13726
13727   mp->mode = mode;
13728
13729   /* send */
13730   S;
13731
13732   /* wait for reply */
13733   W;
13734
13735   /* notreached */
13736   return 0;
13737 }
13738
13739 /**
13740  * Enable/disable LISP proxy ITR.
13741  *
13742  * @param vam vpp API test context
13743  * @return return code
13744  */
13745 static int
13746 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13747 {
13748   f64 timeout = ~0;
13749   u8 ls_name_set = 0;
13750   unformat_input_t *input = vam->input;
13751   vl_api_lisp_pitr_set_locator_set_t *mp;
13752   u8 is_add = 1;
13753   u8 *ls_name = 0;
13754
13755   /* Parse args required to build the message */
13756   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13757     {
13758       if (unformat (input, "del"))
13759         is_add = 0;
13760       else if (unformat (input, "locator-set %s", &ls_name))
13761         ls_name_set = 1;
13762       else
13763         {
13764           errmsg ("parse error '%U'", format_unformat_error, input);
13765           return -99;
13766         }
13767     }
13768
13769   if (!ls_name_set)
13770     {
13771       errmsg ("locator-set name not set!");
13772       return -99;
13773     }
13774
13775   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13776
13777   mp->is_add = is_add;
13778   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13779   vec_free (ls_name);
13780
13781   /* send */
13782   S;
13783
13784   /* wait for reply */
13785   W;
13786
13787   /* notreached */
13788   return 0;
13789 }
13790
13791 static int
13792 api_show_lisp_pitr (vat_main_t * vam)
13793 {
13794   vl_api_show_lisp_pitr_t *mp;
13795   f64 timeout = ~0;
13796
13797   if (!vam->json_output)
13798     {
13799       fformat (vam->ofp, "%=20s\n", "lisp status:");
13800     }
13801
13802   M (SHOW_LISP_PITR, show_lisp_pitr);
13803   /* send it... */
13804   S;
13805
13806   /* Wait for a reply... */
13807   W;
13808
13809   /* NOTREACHED */
13810   return 0;
13811 }
13812
13813 /**
13814  * Add/delete mapping between vni and vrf
13815  */
13816 static int
13817 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13818 {
13819   f64 timeout = ~0;
13820   unformat_input_t *input = vam->input;
13821   vl_api_lisp_eid_table_add_del_map_t *mp;
13822   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13823   u32 vni, vrf, bd_index;
13824
13825   /* Parse args required to build the message */
13826   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13827     {
13828       if (unformat (input, "del"))
13829         is_add = 0;
13830       else if (unformat (input, "vrf %d", &vrf))
13831         vrf_set = 1;
13832       else if (unformat (input, "bd_index %d", &bd_index))
13833         bd_index_set = 1;
13834       else if (unformat (input, "vni %d", &vni))
13835         vni_set = 1;
13836       else
13837         break;
13838     }
13839
13840   if (!vni_set || (!vrf_set && !bd_index_set))
13841     {
13842       errmsg ("missing arguments!");
13843       return -99;
13844     }
13845
13846   if (vrf_set && bd_index_set)
13847     {
13848       errmsg ("error: both vrf and bd entered!");
13849       return -99;
13850     }
13851
13852   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13853
13854   mp->is_add = is_add;
13855   mp->vni = htonl (vni);
13856   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13857   mp->is_l2 = bd_index_set;
13858
13859   /* send */
13860   S;
13861
13862   /* wait for reply */
13863   W;
13864
13865   /* notreached */
13866   return 0;
13867 }
13868
13869 uword
13870 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13871 {
13872   u32 *action = va_arg (*args, u32 *);
13873   u8 *s = 0;
13874
13875   if (unformat (input, "%s", &s))
13876     {
13877       if (!strcmp ((char *) s, "no-action"))
13878         action[0] = 0;
13879       else if (!strcmp ((char *) s, "natively-forward"))
13880         action[0] = 1;
13881       else if (!strcmp ((char *) s, "send-map-request"))
13882         action[0] = 2;
13883       else if (!strcmp ((char *) s, "drop"))
13884         action[0] = 3;
13885       else
13886         {
13887           clib_warning ("invalid action: '%s'", s);
13888           action[0] = 3;
13889         }
13890     }
13891   else
13892     return 0;
13893
13894   vec_free (s);
13895   return 1;
13896 }
13897
13898 /**
13899  * Add/del remote mapping to/from LISP control plane
13900  *
13901  * @param vam vpp API test context
13902  * @return return code
13903  */
13904 static int
13905 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13906 {
13907   unformat_input_t *input = vam->input;
13908   vl_api_lisp_add_del_remote_mapping_t *mp;
13909   f64 timeout = ~0;
13910   u32 vni = 0;
13911   lisp_eid_vat_t _eid, *eid = &_eid;
13912   lisp_eid_vat_t _seid, *seid = &_seid;
13913   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13914   u32 action = ~0, p, w, data_len;
13915   ip4_address_t rloc4;
13916   ip6_address_t rloc6;
13917   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13918
13919   memset (&rloc, 0, sizeof (rloc));
13920
13921   /* Parse args required to build the message */
13922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13923     {
13924       if (unformat (input, "del-all"))
13925         {
13926           del_all = 1;
13927         }
13928       else if (unformat (input, "del"))
13929         {
13930           is_add = 0;
13931         }
13932       else if (unformat (input, "add"))
13933         {
13934           is_add = 1;
13935         }
13936       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13937         {
13938           eid_set = 1;
13939         }
13940       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13941         {
13942           seid_set = 1;
13943         }
13944       else if (unformat (input, "vni %d", &vni))
13945         {
13946           ;
13947         }
13948       else if (unformat (input, "p %d w %d", &p, &w))
13949         {
13950           if (!curr_rloc)
13951             {
13952               errmsg ("No RLOC configured for setting priority/weight!");
13953               return -99;
13954             }
13955           curr_rloc->priority = p;
13956           curr_rloc->weight = w;
13957         }
13958       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13959         {
13960           rloc.is_ip4 = 1;
13961           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13962           vec_add1 (rlocs, rloc);
13963           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13964         }
13965       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13966         {
13967           rloc.is_ip4 = 0;
13968           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13969           vec_add1 (rlocs, rloc);
13970           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13971         }
13972       else if (unformat (input, "action %U",
13973                          unformat_negative_mapping_action, &action))
13974         {
13975           ;
13976         }
13977       else
13978         {
13979           clib_warning ("parse error '%U'", format_unformat_error, input);
13980           return -99;
13981         }
13982     }
13983
13984   if (0 == eid_set)
13985     {
13986       errmsg ("missing params!");
13987       return -99;
13988     }
13989
13990   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13991     {
13992       errmsg ("no action set for negative map-reply!");
13993       return -99;
13994     }
13995
13996   data_len = vec_len (rlocs) * sizeof (rloc_t);
13997
13998   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13999   mp->is_add = is_add;
14000   mp->vni = htonl (vni);
14001   mp->action = (u8) action;
14002   mp->is_src_dst = seid_set;
14003   mp->eid_len = eid->len;
14004   mp->seid_len = seid->len;
14005   mp->del_all = del_all;
14006   mp->eid_type = eid->type;
14007   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14008   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14009
14010   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14011   clib_memcpy (mp->rlocs, rlocs, data_len);
14012   vec_free (rlocs);
14013
14014   /* send it... */
14015   S;
14016
14017   /* Wait for a reply... */
14018   W;
14019
14020   /* NOTREACHED */
14021   return 0;
14022 }
14023
14024 /**
14025  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14026  * forwarding entries in data-plane accordingly.
14027  *
14028  * @param vam vpp API test context
14029  * @return return code
14030  */
14031 static int
14032 api_lisp_add_del_adjacency (vat_main_t * vam)
14033 {
14034   unformat_input_t *input = vam->input;
14035   vl_api_lisp_add_del_adjacency_t *mp;
14036   f64 timeout = ~0;
14037   u32 vni = 0;
14038   ip4_address_t leid4, reid4;
14039   ip6_address_t leid6, reid6;
14040   u8 reid_mac[6] = { 0 };
14041   u8 leid_mac[6] = { 0 };
14042   u8 reid_type, leid_type;
14043   u32 leid_len = 0, reid_len = 0, len;
14044   u8 is_add = 1;
14045
14046   leid_type = reid_type = (u8) ~ 0;
14047
14048   /* Parse args required to build the message */
14049   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14050     {
14051       if (unformat (input, "del"))
14052         {
14053           is_add = 0;
14054         }
14055       else if (unformat (input, "add"))
14056         {
14057           is_add = 1;
14058         }
14059       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14060                          &reid4, &len))
14061         {
14062           reid_type = 0;        /* ipv4 */
14063           reid_len = len;
14064         }
14065       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14066                          &reid6, &len))
14067         {
14068           reid_type = 1;        /* ipv6 */
14069           reid_len = len;
14070         }
14071       else if (unformat (input, "reid %U", unformat_ethernet_address,
14072                          reid_mac))
14073         {
14074           reid_type = 2;        /* mac */
14075         }
14076       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14077                          &leid4, &len))
14078         {
14079           leid_type = 0;        /* ipv4 */
14080           leid_len = len;
14081         }
14082       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14083                          &leid6, &len))
14084         {
14085           leid_type = 1;        /* ipv6 */
14086           leid_len = len;
14087         }
14088       else if (unformat (input, "leid %U", unformat_ethernet_address,
14089                          leid_mac))
14090         {
14091           leid_type = 2;        /* mac */
14092         }
14093       else if (unformat (input, "vni %d", &vni))
14094         {
14095           ;
14096         }
14097       else
14098         {
14099           errmsg ("parse error '%U'", format_unformat_error, input);
14100           return -99;
14101         }
14102     }
14103
14104   if ((u8) ~ 0 == reid_type)
14105     {
14106       errmsg ("missing params!");
14107       return -99;
14108     }
14109
14110   if (leid_type != reid_type)
14111     {
14112       errmsg ("remote and local EIDs are of different types!");
14113       return -99;
14114     }
14115
14116   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
14117   mp->is_add = is_add;
14118   mp->vni = htonl (vni);
14119   mp->leid_len = leid_len;
14120   mp->reid_len = reid_len;
14121   mp->eid_type = reid_type;
14122
14123   switch (mp->eid_type)
14124     {
14125     case 0:
14126       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14127       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14128       break;
14129     case 1:
14130       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14131       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14132       break;
14133     case 2:
14134       clib_memcpy (mp->leid, leid_mac, 6);
14135       clib_memcpy (mp->reid, reid_mac, 6);
14136       break;
14137     default:
14138       errmsg ("unknown EID type %d!", mp->eid_type);
14139       return 0;
14140     }
14141
14142   /* send it... */
14143   S;
14144
14145   /* Wait for a reply... */
14146   W;
14147
14148   /* NOTREACHED */
14149   return 0;
14150 }
14151
14152 static int
14153 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14154 {
14155   unformat_input_t *input = vam->input;
14156   vl_api_lisp_gpe_add_del_iface_t *mp;
14157   f64 timeout = ~0;
14158   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14159   u32 dp_table = 0, vni = 0;
14160
14161   /* Parse args required to build the message */
14162   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14163     {
14164       if (unformat (input, "up"))
14165         {
14166           action_set = 1;
14167           is_add = 1;
14168         }
14169       else if (unformat (input, "down"))
14170         {
14171           action_set = 1;
14172           is_add = 0;
14173         }
14174       else if (unformat (input, "table_id %d", &dp_table))
14175         {
14176           dp_table_set = 1;
14177         }
14178       else if (unformat (input, "bd_id %d", &dp_table))
14179         {
14180           dp_table_set = 1;
14181           is_l2 = 1;
14182         }
14183       else if (unformat (input, "vni %d", &vni))
14184         {
14185           vni_set = 1;
14186         }
14187       else
14188         break;
14189     }
14190
14191   if (action_set == 0)
14192     {
14193       errmsg ("Action not set\n");
14194       return -99;
14195     }
14196   if (dp_table_set == 0 || vni_set == 0)
14197     {
14198       errmsg ("vni and dp_table must be set\n");
14199       return -99;
14200     }
14201
14202   /* Construct the API message */
14203   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
14204
14205   mp->is_add = is_add;
14206   mp->dp_table = dp_table;
14207   mp->is_l2 = is_l2;
14208   mp->vni = vni;
14209
14210   /* send it... */
14211   S;
14212
14213   /* Wait for a reply... */
14214   W;
14215
14216   /* NOTREACHED */
14217   return 0;
14218 }
14219
14220 /**
14221  * Add/del map request itr rlocs from LISP control plane and updates
14222  *
14223  * @param vam vpp API test context
14224  * @return return code
14225  */
14226 static int
14227 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14228 {
14229   unformat_input_t *input = vam->input;
14230   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14231   f64 timeout = ~0;
14232   u8 *locator_set_name = 0;
14233   u8 locator_set_name_set = 0;
14234   u8 is_add = 1;
14235
14236   /* Parse args required to build the message */
14237   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14238     {
14239       if (unformat (input, "del"))
14240         {
14241           is_add = 0;
14242         }
14243       else if (unformat (input, "%_%v%_", &locator_set_name))
14244         {
14245           locator_set_name_set = 1;
14246         }
14247       else
14248         {
14249           clib_warning ("parse error '%U'", format_unformat_error, input);
14250           return -99;
14251         }
14252     }
14253
14254   if (is_add && !locator_set_name_set)
14255     {
14256       errmsg ("itr-rloc is not set!");
14257       return -99;
14258     }
14259
14260   if (is_add && vec_len (locator_set_name) > 64)
14261     {
14262       errmsg ("itr-rloc locator-set name too long\n");
14263       vec_free (locator_set_name);
14264       return -99;
14265     }
14266
14267   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
14268   mp->is_add = is_add;
14269   if (is_add)
14270     {
14271       clib_memcpy (mp->locator_set_name, locator_set_name,
14272                    vec_len (locator_set_name));
14273     }
14274   else
14275     {
14276       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14277     }
14278   vec_free (locator_set_name);
14279
14280   /* send it... */
14281   S;
14282
14283   /* Wait for a reply... */
14284   W;
14285
14286   /* NOTREACHED */
14287   return 0;
14288 }
14289
14290 static int
14291 api_lisp_locator_dump (vat_main_t * vam)
14292 {
14293   unformat_input_t *input = vam->input;
14294   vl_api_lisp_locator_dump_t *mp;
14295   f64 timeout = ~0;
14296   u8 is_index_set = 0, is_name_set = 0;
14297   u8 *ls_name = 0;
14298   u32 ls_index = ~0;
14299
14300   /* Parse args required to build the message */
14301   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14302     {
14303       if (unformat (input, "ls_name %_%v%_", &ls_name))
14304         {
14305           is_name_set = 1;
14306         }
14307       else if (unformat (input, "ls_index %d", &ls_index))
14308         {
14309           is_index_set = 1;
14310         }
14311       else
14312         {
14313           errmsg ("parse error '%U'", format_unformat_error, input);
14314           return -99;
14315         }
14316     }
14317
14318   if (!is_index_set && !is_name_set)
14319     {
14320       errmsg ("error: expected one of index or name!\n");
14321       return -99;
14322     }
14323
14324   if (is_index_set && is_name_set)
14325     {
14326       errmsg ("error: only one param expected!\n");
14327       return -99;
14328     }
14329
14330   if (vec_len (ls_name) > 62)
14331     {
14332       errmsg ("error: locator set name too long!");
14333       return -99;
14334     }
14335
14336   if (!vam->json_output)
14337     {
14338       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
14339                "weight");
14340     }
14341
14342   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
14343   mp->is_index_set = is_index_set;
14344
14345   if (is_index_set)
14346     mp->ls_index = clib_host_to_net_u32 (ls_index);
14347   else
14348     {
14349       vec_add1 (ls_name, 0);
14350       strncpy ((char *) mp->ls_name, (char *) ls_name,
14351                sizeof (mp->ls_name) - 1);
14352     }
14353
14354   /* send it... */
14355   S;
14356
14357   /* Use a control ping for synchronization */
14358   {
14359     vl_api_control_ping_t *mp;
14360     M (CONTROL_PING, control_ping);
14361     S;
14362   }
14363   /* Wait for a reply... */
14364   W;
14365
14366   /* NOTREACHED */
14367   return 0;
14368 }
14369
14370 static int
14371 api_lisp_locator_set_dump (vat_main_t * vam)
14372 {
14373   vl_api_lisp_locator_set_dump_t *mp;
14374   unformat_input_t *input = vam->input;
14375   f64 timeout = ~0;
14376   u8 filter = 0;
14377
14378   /* Parse args required to build the message */
14379   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14380     {
14381       if (unformat (input, "local"))
14382         {
14383           filter = 1;
14384         }
14385       else if (unformat (input, "remote"))
14386         {
14387           filter = 2;
14388         }
14389       else
14390         {
14391           errmsg ("parse error '%U'", format_unformat_error, input);
14392           return -99;
14393         }
14394     }
14395
14396   if (!vam->json_output)
14397     {
14398       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
14399     }
14400
14401   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14402
14403   mp->filter = filter;
14404
14405   /* send it... */
14406   S;
14407
14408   /* Use a control ping for synchronization */
14409   {
14410     vl_api_control_ping_t *mp;
14411     M (CONTROL_PING, control_ping);
14412     S;
14413   }
14414   /* Wait for a reply... */
14415   W;
14416
14417   /* NOTREACHED */
14418   return 0;
14419 }
14420
14421 static int
14422 api_lisp_eid_table_map_dump (vat_main_t * vam)
14423 {
14424   u8 is_l2 = 0;
14425   u8 mode_set = 0;
14426   unformat_input_t *input = vam->input;
14427   vl_api_lisp_eid_table_map_dump_t *mp;
14428   f64 timeout = ~0;
14429
14430   /* Parse args required to build the message */
14431   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14432     {
14433       if (unformat (input, "l2"))
14434         {
14435           is_l2 = 1;
14436           mode_set = 1;
14437         }
14438       else if (unformat (input, "l3"))
14439         {
14440           is_l2 = 0;
14441           mode_set = 1;
14442         }
14443       else
14444         {
14445           errmsg ("parse error '%U'", format_unformat_error, input);
14446           return -99;
14447         }
14448     }
14449
14450   if (!mode_set)
14451     {
14452       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
14453       return -99;
14454     }
14455
14456   if (!vam->json_output)
14457     {
14458       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
14459     }
14460
14461   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14462   mp->is_l2 = is_l2;
14463
14464   /* send it... */
14465   S;
14466
14467   /* Use a control ping for synchronization */
14468   {
14469     vl_api_control_ping_t *mp;
14470     M (CONTROL_PING, control_ping);
14471     S;
14472   }
14473   /* Wait for a reply... */
14474   W;
14475
14476   /* NOTREACHED */
14477   return 0;
14478 }
14479
14480 static int
14481 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14482 {
14483   vl_api_lisp_eid_table_vni_dump_t *mp;
14484   f64 timeout = ~0;
14485
14486   if (!vam->json_output)
14487     {
14488       fformat (vam->ofp, "VNI\n");
14489     }
14490
14491   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14492
14493   /* send it... */
14494   S;
14495
14496   /* Use a control ping for synchronization */
14497   {
14498     vl_api_control_ping_t *mp;
14499     M (CONTROL_PING, control_ping);
14500     S;
14501   }
14502   /* Wait for a reply... */
14503   W;
14504
14505   /* NOTREACHED */
14506   return 0;
14507 }
14508
14509 static int
14510 api_lisp_eid_table_dump (vat_main_t * vam)
14511 {
14512   unformat_input_t *i = vam->input;
14513   vl_api_lisp_eid_table_dump_t *mp;
14514   f64 timeout = ~0;
14515   struct in_addr ip4;
14516   struct in6_addr ip6;
14517   u8 mac[6];
14518   u8 eid_type = ~0, eid_set = 0;
14519   u32 prefix_length = ~0, t, vni = 0;
14520   u8 filter = 0;
14521
14522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14523     {
14524       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14525         {
14526           eid_set = 1;
14527           eid_type = 0;
14528           prefix_length = t;
14529         }
14530       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14531         {
14532           eid_set = 1;
14533           eid_type = 1;
14534           prefix_length = t;
14535         }
14536       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14537         {
14538           eid_set = 1;
14539           eid_type = 2;
14540         }
14541       else if (unformat (i, "vni %d", &t))
14542         {
14543           vni = t;
14544         }
14545       else if (unformat (i, "local"))
14546         {
14547           filter = 1;
14548         }
14549       else if (unformat (i, "remote"))
14550         {
14551           filter = 2;
14552         }
14553       else
14554         {
14555           errmsg ("parse error '%U'", format_unformat_error, i);
14556           return -99;
14557         }
14558     }
14559
14560   if (!vam->json_output)
14561     {
14562       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s\n", "EID",
14563                "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14564     }
14565
14566   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14567
14568   mp->filter = filter;
14569   if (eid_set)
14570     {
14571       mp->eid_set = 1;
14572       mp->vni = htonl (vni);
14573       mp->eid_type = eid_type;
14574       switch (eid_type)
14575         {
14576         case 0:
14577           mp->prefix_length = prefix_length;
14578           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14579           break;
14580         case 1:
14581           mp->prefix_length = prefix_length;
14582           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14583           break;
14584         case 2:
14585           clib_memcpy (mp->eid, mac, sizeof (mac));
14586           break;
14587         default:
14588           errmsg ("unknown EID type %d!", eid_type);
14589           return -99;
14590         }
14591     }
14592
14593   /* send it... */
14594   S;
14595
14596   /* Use a control ping for synchronization */
14597   {
14598     vl_api_control_ping_t *mp;
14599     M (CONTROL_PING, control_ping);
14600     S;
14601   }
14602
14603   /* Wait for a reply... */
14604   W;
14605
14606   /* NOTREACHED */
14607   return 0;
14608 }
14609
14610 static int
14611 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14612 {
14613   vl_api_lisp_gpe_tunnel_dump_t *mp;
14614   f64 timeout = ~0;
14615
14616   if (!vam->json_output)
14617     {
14618       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14619                "%=16s%=16s%=16s%=16s%=16s\n",
14620                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14621                "Decap next", "Lisp version", "Flags", "Next protocol",
14622                "ver_res", "res", "iid");
14623     }
14624
14625   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14626   /* send it... */
14627   S;
14628
14629   /* Use a control ping for synchronization */
14630   {
14631     vl_api_control_ping_t *mp;
14632     M (CONTROL_PING, control_ping);
14633     S;
14634   }
14635   /* Wait for a reply... */
14636   W;
14637
14638   /* NOTREACHED */
14639   return 0;
14640 }
14641
14642 static int
14643 api_lisp_adjacencies_get (vat_main_t * vam)
14644 {
14645   unformat_input_t *i = vam->input;
14646   vl_api_lisp_adjacencies_get_t *mp;
14647   f64 timeout = ~0;
14648   u8 vni_set = 0;
14649   u32 vni = ~0;
14650
14651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14652     {
14653       if (unformat (i, "vni %d", &vni))
14654         {
14655           vni_set = 1;
14656         }
14657       else
14658         {
14659           errmsg ("parse error '%U'\n", format_unformat_error, i);
14660           return -99;
14661         }
14662     }
14663
14664   if (!vni_set)
14665     {
14666       errmsg ("vni not set!\n");
14667       return -99;
14668     }
14669
14670   if (!vam->json_output)
14671     {
14672       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14673     }
14674
14675   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14676   mp->vni = clib_host_to_net_u32 (vni);
14677
14678   /* send it... */
14679   S;
14680
14681   /* Wait for a reply... */
14682   W;
14683
14684   /* NOTREACHED */
14685   return 0;
14686 }
14687
14688 static int
14689 api_lisp_map_server_dump (vat_main_t * vam)
14690 {
14691   vl_api_lisp_map_server_dump_t *mp;
14692   f64 timeout = ~0;
14693
14694   if (!vam->json_output)
14695     {
14696       fformat (vam->ofp, "%=20s\n", "Map server");
14697     }
14698
14699   M (LISP_MAP_SERVER_DUMP, lisp_map_server_dump);
14700   /* send it... */
14701   S;
14702
14703   /* Use a control ping for synchronization */
14704   {
14705     vl_api_control_ping_t *mp;
14706     M (CONTROL_PING, control_ping);
14707     S;
14708   }
14709   /* Wait for a reply... */
14710   W;
14711
14712   /* NOTREACHED */
14713   return 0;
14714 }
14715
14716 static int
14717 api_lisp_map_resolver_dump (vat_main_t * vam)
14718 {
14719   vl_api_lisp_map_resolver_dump_t *mp;
14720   f64 timeout = ~0;
14721
14722   if (!vam->json_output)
14723     {
14724       fformat (vam->ofp, "%=20s\n", "Map resolver");
14725     }
14726
14727   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14728   /* send it... */
14729   S;
14730
14731   /* Use a control ping for synchronization */
14732   {
14733     vl_api_control_ping_t *mp;
14734     M (CONTROL_PING, control_ping);
14735     S;
14736   }
14737   /* Wait for a reply... */
14738   W;
14739
14740   /* NOTREACHED */
14741   return 0;
14742 }
14743
14744 static int
14745 api_show_lisp_status (vat_main_t * vam)
14746 {
14747   vl_api_show_lisp_status_t *mp;
14748   f64 timeout = ~0;
14749
14750   if (!vam->json_output)
14751     {
14752       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14753     }
14754
14755   M (SHOW_LISP_STATUS, show_lisp_status);
14756   /* send it... */
14757   S;
14758   /* Wait for a reply... */
14759   W;
14760
14761   /* NOTREACHED */
14762   return 0;
14763 }
14764
14765 static int
14766 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14767 {
14768   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14769   f64 timeout = ~0;
14770
14771   if (!vam->json_output)
14772     {
14773       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14774     }
14775
14776   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14777   /* send it... */
14778   S;
14779   /* Wait for a reply... */
14780   W;
14781
14782   /* NOTREACHED */
14783   return 0;
14784 }
14785
14786 static int
14787 api_af_packet_create (vat_main_t * vam)
14788 {
14789   unformat_input_t *i = vam->input;
14790   vl_api_af_packet_create_t *mp;
14791   f64 timeout;
14792   u8 *host_if_name = 0;
14793   u8 hw_addr[6];
14794   u8 random_hw_addr = 1;
14795
14796   memset (hw_addr, 0, sizeof (hw_addr));
14797
14798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14799     {
14800       if (unformat (i, "name %s", &host_if_name))
14801         vec_add1 (host_if_name, 0);
14802       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14803         random_hw_addr = 0;
14804       else
14805         break;
14806     }
14807
14808   if (!vec_len (host_if_name))
14809     {
14810       errmsg ("host-interface name must be specified");
14811       return -99;
14812     }
14813
14814   if (vec_len (host_if_name) > 64)
14815     {
14816       errmsg ("host-interface name too long");
14817       return -99;
14818     }
14819
14820   M (AF_PACKET_CREATE, af_packet_create);
14821
14822   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14823   clib_memcpy (mp->hw_addr, hw_addr, 6);
14824   mp->use_random_hw_addr = random_hw_addr;
14825   vec_free (host_if_name);
14826
14827   S;
14828   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14829   /* NOTREACHED */
14830   return 0;
14831 }
14832
14833 static int
14834 api_af_packet_delete (vat_main_t * vam)
14835 {
14836   unformat_input_t *i = vam->input;
14837   vl_api_af_packet_delete_t *mp;
14838   f64 timeout;
14839   u8 *host_if_name = 0;
14840
14841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14842     {
14843       if (unformat (i, "name %s", &host_if_name))
14844         vec_add1 (host_if_name, 0);
14845       else
14846         break;
14847     }
14848
14849   if (!vec_len (host_if_name))
14850     {
14851       errmsg ("host-interface name must be specified");
14852       return -99;
14853     }
14854
14855   if (vec_len (host_if_name) > 64)
14856     {
14857       errmsg ("host-interface name too long");
14858       return -99;
14859     }
14860
14861   M (AF_PACKET_DELETE, af_packet_delete);
14862
14863   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14864   vec_free (host_if_name);
14865
14866   S;
14867   W;
14868   /* NOTREACHED */
14869   return 0;
14870 }
14871
14872 static int
14873 api_policer_add_del (vat_main_t * vam)
14874 {
14875   unformat_input_t *i = vam->input;
14876   vl_api_policer_add_del_t *mp;
14877   f64 timeout;
14878   u8 is_add = 1;
14879   u8 *name = 0;
14880   u32 cir = 0;
14881   u32 eir = 0;
14882   u64 cb = 0;
14883   u64 eb = 0;
14884   u8 rate_type = 0;
14885   u8 round_type = 0;
14886   u8 type = 0;
14887   u8 color_aware = 0;
14888   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14889
14890   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14891   conform_action.dscp = 0;
14892   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14893   exceed_action.dscp = 0;
14894   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14895   violate_action.dscp = 0;
14896
14897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14898     {
14899       if (unformat (i, "del"))
14900         is_add = 0;
14901       else if (unformat (i, "name %s", &name))
14902         vec_add1 (name, 0);
14903       else if (unformat (i, "cir %u", &cir))
14904         ;
14905       else if (unformat (i, "eir %u", &eir))
14906         ;
14907       else if (unformat (i, "cb %u", &cb))
14908         ;
14909       else if (unformat (i, "eb %u", &eb))
14910         ;
14911       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14912                          &rate_type))
14913         ;
14914       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14915                          &round_type))
14916         ;
14917       else if (unformat (i, "type %U", unformat_policer_type, &type))
14918         ;
14919       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14920                          &conform_action))
14921         ;
14922       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14923                          &exceed_action))
14924         ;
14925       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14926                          &violate_action))
14927         ;
14928       else if (unformat (i, "color-aware"))
14929         color_aware = 1;
14930       else
14931         break;
14932     }
14933
14934   if (!vec_len (name))
14935     {
14936       errmsg ("policer name must be specified");
14937       return -99;
14938     }
14939
14940   if (vec_len (name) > 64)
14941     {
14942       errmsg ("policer name too long");
14943       return -99;
14944     }
14945
14946   M (POLICER_ADD_DEL, policer_add_del);
14947
14948   clib_memcpy (mp->name, name, vec_len (name));
14949   vec_free (name);
14950   mp->is_add = is_add;
14951   mp->cir = cir;
14952   mp->eir = eir;
14953   mp->cb = cb;
14954   mp->eb = eb;
14955   mp->rate_type = rate_type;
14956   mp->round_type = round_type;
14957   mp->type = type;
14958   mp->conform_action_type = conform_action.action_type;
14959   mp->conform_dscp = conform_action.dscp;
14960   mp->exceed_action_type = exceed_action.action_type;
14961   mp->exceed_dscp = exceed_action.dscp;
14962   mp->violate_action_type = violate_action.action_type;
14963   mp->violate_dscp = violate_action.dscp;
14964   mp->color_aware = color_aware;
14965
14966   S;
14967   W;
14968   /* NOTREACHED */
14969   return 0;
14970 }
14971
14972 static int
14973 api_policer_dump (vat_main_t * vam)
14974 {
14975   unformat_input_t *i = vam->input;
14976   vl_api_policer_dump_t *mp;
14977   f64 timeout = ~0;
14978   u8 *match_name = 0;
14979   u8 match_name_valid = 0;
14980
14981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14982     {
14983       if (unformat (i, "name %s", &match_name))
14984         {
14985           vec_add1 (match_name, 0);
14986           match_name_valid = 1;
14987         }
14988       else
14989         break;
14990     }
14991
14992   M (POLICER_DUMP, policer_dump);
14993   mp->match_name_valid = match_name_valid;
14994   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14995   vec_free (match_name);
14996   /* send it... */
14997   S;
14998
14999   /* Use a control ping for synchronization */
15000   {
15001     vl_api_control_ping_t *mp;
15002     M (CONTROL_PING, control_ping);
15003     S;
15004   }
15005   /* Wait for a reply... */
15006   W;
15007
15008   /* NOTREACHED */
15009   return 0;
15010 }
15011
15012 static int
15013 api_policer_classify_set_interface (vat_main_t * vam)
15014 {
15015   unformat_input_t *i = vam->input;
15016   vl_api_policer_classify_set_interface_t *mp;
15017   f64 timeout;
15018   u32 sw_if_index;
15019   int sw_if_index_set;
15020   u32 ip4_table_index = ~0;
15021   u32 ip6_table_index = ~0;
15022   u32 l2_table_index = ~0;
15023   u8 is_add = 1;
15024
15025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15026     {
15027       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15028         sw_if_index_set = 1;
15029       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15030         sw_if_index_set = 1;
15031       else if (unformat (i, "del"))
15032         is_add = 0;
15033       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15034         ;
15035       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15036         ;
15037       else if (unformat (i, "l2-table %d", &l2_table_index))
15038         ;
15039       else
15040         {
15041           clib_warning ("parse error '%U'", format_unformat_error, i);
15042           return -99;
15043         }
15044     }
15045
15046   if (sw_if_index_set == 0)
15047     {
15048       errmsg ("missing interface name or sw_if_index\n");
15049       return -99;
15050     }
15051
15052   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
15053
15054   mp->sw_if_index = ntohl (sw_if_index);
15055   mp->ip4_table_index = ntohl (ip4_table_index);
15056   mp->ip6_table_index = ntohl (ip6_table_index);
15057   mp->l2_table_index = ntohl (l2_table_index);
15058   mp->is_add = is_add;
15059
15060   S;
15061   W;
15062   /* NOTREACHED */
15063   return 0;
15064 }
15065
15066 static int
15067 api_policer_classify_dump (vat_main_t * vam)
15068 {
15069   unformat_input_t *i = vam->input;
15070   vl_api_policer_classify_dump_t *mp;
15071   f64 timeout = ~0;
15072   u8 type = POLICER_CLASSIFY_N_TABLES;
15073
15074   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15075     ;
15076   else
15077     {
15078       errmsg ("classify table type must be specified\n");
15079       return -99;
15080     }
15081
15082   if (!vam->json_output)
15083     {
15084       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
15085     }
15086
15087   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
15088   mp->type = type;
15089   /* send it... */
15090   S;
15091
15092   /* Use a control ping for synchronization */
15093   {
15094     vl_api_control_ping_t *mp;
15095     M (CONTROL_PING, control_ping);
15096     S;
15097   }
15098   /* Wait for a reply... */
15099   W;
15100
15101   /* NOTREACHED */
15102   return 0;
15103 }
15104
15105 static int
15106 api_netmap_create (vat_main_t * vam)
15107 {
15108   unformat_input_t *i = vam->input;
15109   vl_api_netmap_create_t *mp;
15110   f64 timeout;
15111   u8 *if_name = 0;
15112   u8 hw_addr[6];
15113   u8 random_hw_addr = 1;
15114   u8 is_pipe = 0;
15115   u8 is_master = 0;
15116
15117   memset (hw_addr, 0, sizeof (hw_addr));
15118
15119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15120     {
15121       if (unformat (i, "name %s", &if_name))
15122         vec_add1 (if_name, 0);
15123       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15124         random_hw_addr = 0;
15125       else if (unformat (i, "pipe"))
15126         is_pipe = 1;
15127       else if (unformat (i, "master"))
15128         is_master = 1;
15129       else if (unformat (i, "slave"))
15130         is_master = 0;
15131       else
15132         break;
15133     }
15134
15135   if (!vec_len (if_name))
15136     {
15137       errmsg ("interface name must be specified");
15138       return -99;
15139     }
15140
15141   if (vec_len (if_name) > 64)
15142     {
15143       errmsg ("interface name too long");
15144       return -99;
15145     }
15146
15147   M (NETMAP_CREATE, netmap_create);
15148
15149   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15150   clib_memcpy (mp->hw_addr, hw_addr, 6);
15151   mp->use_random_hw_addr = random_hw_addr;
15152   mp->is_pipe = is_pipe;
15153   mp->is_master = is_master;
15154   vec_free (if_name);
15155
15156   S;
15157   W;
15158   /* NOTREACHED */
15159   return 0;
15160 }
15161
15162 static int
15163 api_netmap_delete (vat_main_t * vam)
15164 {
15165   unformat_input_t *i = vam->input;
15166   vl_api_netmap_delete_t *mp;
15167   f64 timeout;
15168   u8 *if_name = 0;
15169
15170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15171     {
15172       if (unformat (i, "name %s", &if_name))
15173         vec_add1 (if_name, 0);
15174       else
15175         break;
15176     }
15177
15178   if (!vec_len (if_name))
15179     {
15180       errmsg ("interface name must be specified");
15181       return -99;
15182     }
15183
15184   if (vec_len (if_name) > 64)
15185     {
15186       errmsg ("interface name too long");
15187       return -99;
15188     }
15189
15190   M (NETMAP_DELETE, netmap_delete);
15191
15192   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15193   vec_free (if_name);
15194
15195   S;
15196   W;
15197   /* NOTREACHED */
15198   return 0;
15199 }
15200
15201 static void vl_api_mpls_tunnel_details_t_handler
15202   (vl_api_mpls_tunnel_details_t * mp)
15203 {
15204   vat_main_t *vam = &vat_main;
15205   i32 len = mp->mt_next_hop_n_labels;
15206   i32 i;
15207
15208   fformat (vam->ofp, "[%d]: via %U %d labels ",
15209            mp->tunnel_index,
15210            format_ip4_address, mp->mt_next_hop,
15211            ntohl (mp->mt_next_hop_sw_if_index));
15212   for (i = 0; i < len; i++)
15213     {
15214       fformat (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15215     }
15216   fformat (vam->ofp, "\n");
15217 }
15218
15219 static void vl_api_mpls_tunnel_details_t_handler_json
15220   (vl_api_mpls_tunnel_details_t * mp)
15221 {
15222   vat_main_t *vam = &vat_main;
15223   vat_json_node_t *node = NULL;
15224   struct in_addr ip4;
15225   i32 i;
15226   i32 len = mp->mt_next_hop_n_labels;
15227
15228   if (VAT_JSON_ARRAY != vam->json_tree.type)
15229     {
15230       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15231       vat_json_init_array (&vam->json_tree);
15232     }
15233   node = vat_json_array_add (&vam->json_tree);
15234
15235   vat_json_init_object (node);
15236   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15237   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15238   vat_json_object_add_ip4 (node, "next_hop", ip4);
15239   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15240                             ntohl (mp->mt_next_hop_sw_if_index));
15241   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15242   vat_json_object_add_uint (node, "label_count", len);
15243   for (i = 0; i < len; i++)
15244     {
15245       vat_json_object_add_uint (node, "label",
15246                                 ntohl (mp->mt_next_hop_out_labels[i]));
15247     }
15248 }
15249
15250 static int
15251 api_mpls_tunnel_dump (vat_main_t * vam)
15252 {
15253   vl_api_mpls_tunnel_dump_t *mp;
15254   f64 timeout;
15255   i32 index = -1;
15256
15257   /* Parse args required to build the message */
15258   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15259     {
15260       if (!unformat (vam->input, "tunnel_index %d", &index))
15261         {
15262           index = -1;
15263           break;
15264         }
15265     }
15266
15267   fformat (vam->ofp, "  tunnel_index %d\n", index);
15268
15269   M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
15270   mp->tunnel_index = htonl (index);
15271   S;
15272
15273   /* Use a control ping for synchronization */
15274   {
15275     vl_api_control_ping_t *mp;
15276     M (CONTROL_PING, control_ping);
15277     S;
15278   }
15279   W;
15280 }
15281
15282 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15283 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15284
15285 static void
15286 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15287 {
15288   vat_main_t *vam = &vat_main;
15289   int count = ntohl (mp->count);
15290   vl_api_fib_path2_t *fp;
15291   int i;
15292
15293   fformat (vam->ofp,
15294            "table-id %d, label %u, ess_bit %u\n",
15295            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15296   fp = mp->path;
15297   for (i = 0; i < count; i++)
15298     {
15299       if (fp->afi == IP46_TYPE_IP6)
15300         fformat (vam->ofp,
15301                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15302                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15303                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15304                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15305                  format_ip6_address, fp->next_hop);
15306       else if (fp->afi == IP46_TYPE_IP4)
15307         fformat (vam->ofp,
15308                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15309                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15310                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15311                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15312                  format_ip4_address, fp->next_hop);
15313       fp++;
15314     }
15315 }
15316
15317 static void vl_api_mpls_fib_details_t_handler_json
15318   (vl_api_mpls_fib_details_t * mp)
15319 {
15320   vat_main_t *vam = &vat_main;
15321   int count = ntohl (mp->count);
15322   vat_json_node_t *node = NULL;
15323   struct in_addr ip4;
15324   struct in6_addr ip6;
15325   vl_api_fib_path2_t *fp;
15326   int i;
15327
15328   if (VAT_JSON_ARRAY != vam->json_tree.type)
15329     {
15330       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15331       vat_json_init_array (&vam->json_tree);
15332     }
15333   node = vat_json_array_add (&vam->json_tree);
15334
15335   vat_json_init_object (node);
15336   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15337   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15338   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15339   vat_json_object_add_uint (node, "path_count", count);
15340   fp = mp->path;
15341   for (i = 0; i < count; i++)
15342     {
15343       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15344       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15345       vat_json_object_add_uint (node, "is_local", fp->is_local);
15346       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15347       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15348       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15349       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15350       if (fp->afi == IP46_TYPE_IP4)
15351         {
15352           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15353           vat_json_object_add_ip4 (node, "next_hop", ip4);
15354         }
15355       else if (fp->afi == IP46_TYPE_IP6)
15356         {
15357           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15358           vat_json_object_add_ip6 (node, "next_hop", ip6);
15359         }
15360     }
15361 }
15362
15363 static int
15364 api_mpls_fib_dump (vat_main_t * vam)
15365 {
15366   vl_api_mpls_fib_dump_t *mp;
15367   f64 timeout;
15368
15369   M (MPLS_FIB_DUMP, mpls_fib_dump);
15370   S;
15371
15372   /* Use a control ping for synchronization */
15373   {
15374     vl_api_control_ping_t *mp;
15375     M (CONTROL_PING, control_ping);
15376     S;
15377   }
15378   W;
15379 }
15380
15381 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15382 #define vl_api_ip_fib_details_t_print vl_noop_handler
15383
15384 static void
15385 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15386 {
15387   vat_main_t *vam = &vat_main;
15388   int count = ntohl (mp->count);
15389   vl_api_fib_path_t *fp;
15390   int i;
15391
15392   fformat (vam->ofp,
15393            "table-id %d, prefix %U/%d\n",
15394            ntohl (mp->table_id), format_ip4_address, mp->address,
15395            mp->address_length);
15396   fp = mp->path;
15397   for (i = 0; i < count; i++)
15398     {
15399       if (fp->afi == IP46_TYPE_IP6)
15400         fformat (vam->ofp,
15401                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15402                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15403                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15404                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15405                  format_ip6_address, fp->next_hop);
15406       else if (fp->afi == IP46_TYPE_IP4)
15407         fformat (vam->ofp,
15408                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15409                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15410                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15411                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15412                  format_ip4_address, fp->next_hop);
15413       fp++;
15414     }
15415 }
15416
15417 static void vl_api_ip_fib_details_t_handler_json
15418   (vl_api_ip_fib_details_t * mp)
15419 {
15420   vat_main_t *vam = &vat_main;
15421   int count = ntohl (mp->count);
15422   vat_json_node_t *node = NULL;
15423   struct in_addr ip4;
15424   struct in6_addr ip6;
15425   vl_api_fib_path_t *fp;
15426   int i;
15427
15428   if (VAT_JSON_ARRAY != vam->json_tree.type)
15429     {
15430       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15431       vat_json_init_array (&vam->json_tree);
15432     }
15433   node = vat_json_array_add (&vam->json_tree);
15434
15435   vat_json_init_object (node);
15436   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15437   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15438   vat_json_object_add_ip4 (node, "prefix", ip4);
15439   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15440   vat_json_object_add_uint (node, "path_count", count);
15441   fp = mp->path;
15442   for (i = 0; i < count; i++)
15443     {
15444       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15445       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15446       vat_json_object_add_uint (node, "is_local", fp->is_local);
15447       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15448       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15449       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15450       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15451       if (fp->afi == IP46_TYPE_IP4)
15452         {
15453           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15454           vat_json_object_add_ip4 (node, "next_hop", ip4);
15455         }
15456       else if (fp->afi == IP46_TYPE_IP6)
15457         {
15458           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15459           vat_json_object_add_ip6 (node, "next_hop", ip6);
15460         }
15461     }
15462 }
15463
15464 static int
15465 api_ip_fib_dump (vat_main_t * vam)
15466 {
15467   vl_api_ip_fib_dump_t *mp;
15468   f64 timeout;
15469
15470   M (IP_FIB_DUMP, ip_fib_dump);
15471   S;
15472
15473   /* Use a control ping for synchronization */
15474   {
15475     vl_api_control_ping_t *mp;
15476     M (CONTROL_PING, control_ping);
15477     S;
15478   }
15479   W;
15480 }
15481
15482 static void vl_api_ip_neighbor_details_t_handler
15483   (vl_api_ip_neighbor_details_t * mp)
15484 {
15485   vat_main_t *vam = &vat_main;
15486
15487   fformat (vam->ofp, "%c %U %U\n",
15488            (mp->is_static) ? 'S' : 'D',
15489            format_ethernet_address, &mp->mac_address,
15490            (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15491            &mp->ip_address);
15492 }
15493
15494 static void vl_api_ip_neighbor_details_t_handler_json
15495   (vl_api_ip_neighbor_details_t * mp)
15496 {
15497
15498   vat_main_t *vam = &vat_main;
15499   vat_json_node_t *node;
15500   struct in_addr ip4;
15501   struct in6_addr ip6;
15502
15503   if (VAT_JSON_ARRAY != vam->json_tree.type)
15504     {
15505       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15506       vat_json_init_array (&vam->json_tree);
15507     }
15508   node = vat_json_array_add (&vam->json_tree);
15509
15510   vat_json_init_object (node);
15511   vat_json_object_add_string_copy (node, "flag",
15512                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15513                                    "dynamic");
15514
15515   vat_json_object_add_string_copy (node, "link_layer",
15516                                    format (0, "%U", format_ethernet_address,
15517                                            &mp->mac_address));
15518
15519   if (mp->is_ipv6)
15520     {
15521       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15522       vat_json_object_add_ip6 (node, "ip_address", ip6);
15523     }
15524   else
15525     {
15526       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15527       vat_json_object_add_ip4 (node, "ip_address", ip4);
15528     }
15529 }
15530
15531 static int
15532 api_ip_neighbor_dump (vat_main_t * vam)
15533 {
15534   unformat_input_t *i = vam->input;
15535   vl_api_ip_neighbor_dump_t *mp;
15536   f64 timeout;
15537   u8 is_ipv6 = 0;
15538   u32 sw_if_index = ~0;
15539
15540   /* Parse args required to build the message */
15541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15542     {
15543       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15544         ;
15545       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15546         ;
15547       else if (unformat (i, "ip6"))
15548         is_ipv6 = 1;
15549       else
15550         break;
15551     }
15552
15553   if (sw_if_index == ~0)
15554     {
15555       errmsg ("missing interface name or sw_if_index\n");
15556       return -99;
15557     }
15558
15559   M (IP_NEIGHBOR_DUMP, ip_neighbor_dump);
15560   mp->is_ipv6 = (u8) is_ipv6;
15561   mp->sw_if_index = ntohl (sw_if_index);
15562   S;
15563
15564   /* Use a control ping for synchronization */
15565   {
15566     vl_api_control_ping_t *mp;
15567     M (CONTROL_PING, control_ping);
15568     S;
15569   }
15570   W;
15571 }
15572
15573 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15574 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15575
15576 static void
15577 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15578 {
15579   vat_main_t *vam = &vat_main;
15580   int count = ntohl (mp->count);
15581   vl_api_fib_path_t *fp;
15582   int i;
15583
15584   fformat (vam->ofp,
15585            "table-id %d, prefix %U/%d\n",
15586            ntohl (mp->table_id), format_ip6_address, mp->address,
15587            mp->address_length);
15588   fp = mp->path;
15589   for (i = 0; i < count; i++)
15590     {
15591       if (fp->afi == IP46_TYPE_IP6)
15592         fformat (vam->ofp,
15593                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15594                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15595                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15596                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15597                  format_ip6_address, fp->next_hop);
15598       else if (fp->afi == IP46_TYPE_IP4)
15599         fformat (vam->ofp,
15600                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15601                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15602                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15603                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15604                  format_ip4_address, fp->next_hop);
15605       fp++;
15606     }
15607 }
15608
15609 static void vl_api_ip6_fib_details_t_handler_json
15610   (vl_api_ip6_fib_details_t * mp)
15611 {
15612   vat_main_t *vam = &vat_main;
15613   int count = ntohl (mp->count);
15614   vat_json_node_t *node = NULL;
15615   struct in_addr ip4;
15616   struct in6_addr ip6;
15617   vl_api_fib_path_t *fp;
15618   int i;
15619
15620   if (VAT_JSON_ARRAY != vam->json_tree.type)
15621     {
15622       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15623       vat_json_init_array (&vam->json_tree);
15624     }
15625   node = vat_json_array_add (&vam->json_tree);
15626
15627   vat_json_init_object (node);
15628   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15629   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15630   vat_json_object_add_ip6 (node, "prefix", ip6);
15631   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15632   vat_json_object_add_uint (node, "path_count", count);
15633   fp = mp->path;
15634   for (i = 0; i < count; i++)
15635     {
15636       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15637       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15638       vat_json_object_add_uint (node, "is_local", fp->is_local);
15639       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15640       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15641       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15642       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15643       if (fp->afi == IP46_TYPE_IP4)
15644         {
15645           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15646           vat_json_object_add_ip4 (node, "next_hop", ip4);
15647         }
15648       else if (fp->afi == IP46_TYPE_IP6)
15649         {
15650           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15651           vat_json_object_add_ip6 (node, "next_hop", ip6);
15652         }
15653     }
15654 }
15655
15656 static int
15657 api_ip6_fib_dump (vat_main_t * vam)
15658 {
15659   vl_api_ip6_fib_dump_t *mp;
15660   f64 timeout;
15661
15662   M (IP6_FIB_DUMP, ip6_fib_dump);
15663   S;
15664
15665   /* Use a control ping for synchronization */
15666   {
15667     vl_api_control_ping_t *mp;
15668     M (CONTROL_PING, control_ping);
15669     S;
15670   }
15671   W;
15672 }
15673
15674 int
15675 api_classify_table_ids (vat_main_t * vam)
15676 {
15677   vl_api_classify_table_ids_t *mp;
15678   f64 timeout;
15679
15680   /* Construct the API message */
15681   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15682   mp->context = 0;
15683
15684   S;
15685   W;
15686   /* NOTREACHED */
15687   return 0;
15688 }
15689
15690 int
15691 api_classify_table_by_interface (vat_main_t * vam)
15692 {
15693   unformat_input_t *input = vam->input;
15694   vl_api_classify_table_by_interface_t *mp;
15695   f64 timeout;
15696
15697   u32 sw_if_index = ~0;
15698   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15699     {
15700       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15701         ;
15702       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15703         ;
15704       else
15705         break;
15706     }
15707   if (sw_if_index == ~0)
15708     {
15709       errmsg ("missing interface name or sw_if_index\n");
15710       return -99;
15711     }
15712
15713   /* Construct the API message */
15714   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15715   mp->context = 0;
15716   mp->sw_if_index = ntohl (sw_if_index);
15717
15718   S;
15719   W;
15720   /* NOTREACHED */
15721   return 0;
15722 }
15723
15724 int
15725 api_classify_table_info (vat_main_t * vam)
15726 {
15727   unformat_input_t *input = vam->input;
15728   vl_api_classify_table_info_t *mp;
15729   f64 timeout;
15730
15731   u32 table_id = ~0;
15732   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15733     {
15734       if (unformat (input, "table_id %d", &table_id))
15735         ;
15736       else
15737         break;
15738     }
15739   if (table_id == ~0)
15740     {
15741       errmsg ("missing table id\n");
15742       return -99;
15743     }
15744
15745   /* Construct the API message */
15746   M (CLASSIFY_TABLE_INFO, classify_table_info);
15747   mp->context = 0;
15748   mp->table_id = ntohl (table_id);
15749
15750   S;
15751   W;
15752   /* NOTREACHED */
15753   return 0;
15754 }
15755
15756 int
15757 api_classify_session_dump (vat_main_t * vam)
15758 {
15759   unformat_input_t *input = vam->input;
15760   vl_api_classify_session_dump_t *mp;
15761   f64 timeout;
15762
15763   u32 table_id = ~0;
15764   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15765     {
15766       if (unformat (input, "table_id %d", &table_id))
15767         ;
15768       else
15769         break;
15770     }
15771   if (table_id == ~0)
15772     {
15773       errmsg ("missing table id\n");
15774       return -99;
15775     }
15776
15777   /* Construct the API message */
15778   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15779   mp->context = 0;
15780   mp->table_id = ntohl (table_id);
15781   S;
15782
15783   /* Use a control ping for synchronization */
15784   {
15785     vl_api_control_ping_t *mp;
15786     M (CONTROL_PING, control_ping);
15787     S;
15788   }
15789   W;
15790   /* NOTREACHED */
15791   return 0;
15792 }
15793
15794 static void
15795 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15796 {
15797   vat_main_t *vam = &vat_main;
15798
15799   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15800            "src_address %U, vrf_id %d, path_mtu %u, "
15801            "template_interval %u, udp_checksum %d\n",
15802            format_ip4_address, mp->collector_address,
15803            ntohs (mp->collector_port),
15804            format_ip4_address, mp->src_address,
15805            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15806            ntohl (mp->template_interval), mp->udp_checksum);
15807
15808   vam->retval = 0;
15809   vam->result_ready = 1;
15810 }
15811
15812 static void
15813   vl_api_ipfix_exporter_details_t_handler_json
15814   (vl_api_ipfix_exporter_details_t * mp)
15815 {
15816   vat_main_t *vam = &vat_main;
15817   vat_json_node_t node;
15818   struct in_addr collector_address;
15819   struct in_addr src_address;
15820
15821   vat_json_init_object (&node);
15822   clib_memcpy (&collector_address, &mp->collector_address,
15823                sizeof (collector_address));
15824   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15825   vat_json_object_add_uint (&node, "collector_port",
15826                             ntohs (mp->collector_port));
15827   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15828   vat_json_object_add_ip4 (&node, "src_address", src_address);
15829   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15830   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15831   vat_json_object_add_uint (&node, "template_interval",
15832                             ntohl (mp->template_interval));
15833   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15834
15835   vat_json_print (vam->ofp, &node);
15836   vat_json_free (&node);
15837   vam->retval = 0;
15838   vam->result_ready = 1;
15839 }
15840
15841 int
15842 api_ipfix_exporter_dump (vat_main_t * vam)
15843 {
15844   vl_api_ipfix_exporter_dump_t *mp;
15845   f64 timeout;
15846
15847   /* Construct the API message */
15848   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15849   mp->context = 0;
15850
15851   S;
15852   W;
15853   /* NOTREACHED */
15854   return 0;
15855 }
15856
15857 static int
15858 api_ipfix_classify_stream_dump (vat_main_t * vam)
15859 {
15860   vl_api_ipfix_classify_stream_dump_t *mp;
15861   f64 timeout;
15862
15863   /* Construct the API message */
15864   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15865   mp->context = 0;
15866
15867   S;
15868   W;
15869   /* NOTREACHED */
15870   return 0;
15871 }
15872
15873 static void
15874   vl_api_ipfix_classify_stream_details_t_handler
15875   (vl_api_ipfix_classify_stream_details_t * mp)
15876 {
15877   vat_main_t *vam = &vat_main;
15878   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15879            ntohl (mp->domain_id), ntohs (mp->src_port));
15880   vam->retval = 0;
15881   vam->result_ready = 1;
15882 }
15883
15884 static void
15885   vl_api_ipfix_classify_stream_details_t_handler_json
15886   (vl_api_ipfix_classify_stream_details_t * mp)
15887 {
15888   vat_main_t *vam = &vat_main;
15889   vat_json_node_t node;
15890
15891   vat_json_init_object (&node);
15892   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15893   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15894
15895   vat_json_print (vam->ofp, &node);
15896   vat_json_free (&node);
15897   vam->retval = 0;
15898   vam->result_ready = 1;
15899 }
15900
15901 static int
15902 api_ipfix_classify_table_dump (vat_main_t * vam)
15903 {
15904   vl_api_ipfix_classify_table_dump_t *mp;
15905   f64 timeout;
15906
15907   if (!vam->json_output)
15908     {
15909       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15910                "transport_protocol");
15911     }
15912
15913   /* Construct the API message */
15914   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15915
15916   /* send it... */
15917   S;
15918
15919   /* Use a control ping for synchronization */
15920   {
15921     vl_api_control_ping_t *mp;
15922     M (CONTROL_PING, control_ping);
15923     S;
15924   }
15925   W;
15926 }
15927
15928 static void
15929   vl_api_ipfix_classify_table_details_t_handler
15930   (vl_api_ipfix_classify_table_details_t * mp)
15931 {
15932   vat_main_t *vam = &vat_main;
15933   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15934            mp->transport_protocol);
15935 }
15936
15937 static void
15938   vl_api_ipfix_classify_table_details_t_handler_json
15939   (vl_api_ipfix_classify_table_details_t * mp)
15940 {
15941   vat_json_node_t *node = NULL;
15942   vat_main_t *vam = &vat_main;
15943
15944   if (VAT_JSON_ARRAY != vam->json_tree.type)
15945     {
15946       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15947       vat_json_init_array (&vam->json_tree);
15948     }
15949
15950   node = vat_json_array_add (&vam->json_tree);
15951   vat_json_init_object (node);
15952
15953   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15954   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15955   vat_json_object_add_uint (node, "transport_protocol",
15956                             mp->transport_protocol);
15957 }
15958
15959 static int
15960 api_sw_interface_span_enable_disable (vat_main_t * vam)
15961 {
15962   unformat_input_t *i = vam->input;
15963   vl_api_sw_interface_span_enable_disable_t *mp;
15964   f64 timeout;
15965   u32 src_sw_if_index = ~0;
15966   u32 dst_sw_if_index = ~0;
15967   u8 state = 3;
15968
15969   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15970     {
15971       if (unformat (i, "src %U", unformat_sw_if_index, vam, &src_sw_if_index))
15972         ;
15973       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15974         ;
15975       else
15976         if (unformat
15977             (i, "dst %U", unformat_sw_if_index, vam, &dst_sw_if_index))
15978         ;
15979       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15980         ;
15981       else if (unformat (i, "disable"))
15982         state = 0;
15983       else if (unformat (i, "rx"))
15984         state = 1;
15985       else if (unformat (i, "tx"))
15986         state = 2;
15987       else if (unformat (i, "both"))
15988         state = 3;
15989       else
15990         break;
15991     }
15992
15993   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
15994
15995   mp->sw_if_index_from = htonl (src_sw_if_index);
15996   mp->sw_if_index_to = htonl (dst_sw_if_index);
15997   mp->state = state;
15998
15999   S;
16000   W;
16001   /* NOTREACHED */
16002   return 0;
16003 }
16004
16005 static void
16006 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16007                                             * mp)
16008 {
16009   vat_main_t *vam = &vat_main;
16010   u8 *sw_if_from_name = 0;
16011   u8 *sw_if_to_name = 0;
16012   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16013   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16014   char *states[] = { "none", "rx", "tx", "both" };
16015   hash_pair_t *p;
16016
16017   /* *INDENT-OFF* */
16018   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16019   ({
16020     if ((u32) p->value[0] == sw_if_index_from)
16021       {
16022         sw_if_from_name = (u8 *)(p->key);
16023         if (sw_if_to_name)
16024           break;
16025       }
16026     if ((u32) p->value[0] == sw_if_index_to)
16027       {
16028         sw_if_to_name = (u8 *)(p->key);
16029         if (sw_if_from_name)
16030           break;
16031       }
16032   }));
16033   /* *INDENT-ON* */
16034   fformat (vam->ofp, "%20s => %20s (%s)\n",
16035            sw_if_from_name, sw_if_to_name, states[mp->state]);
16036 }
16037
16038 static void
16039   vl_api_sw_interface_span_details_t_handler_json
16040   (vl_api_sw_interface_span_details_t * mp)
16041 {
16042   vat_main_t *vam = &vat_main;
16043   vat_json_node_t *node = NULL;
16044   u8 *sw_if_from_name = 0;
16045   u8 *sw_if_to_name = 0;
16046   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16047   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16048   hash_pair_t *p;
16049
16050   /* *INDENT-OFF* */
16051   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16052   ({
16053     if ((u32) p->value[0] == sw_if_index_from)
16054       {
16055         sw_if_from_name = (u8 *)(p->key);
16056         if (sw_if_to_name)
16057           break;
16058       }
16059     if ((u32) p->value[0] == sw_if_index_to)
16060       {
16061         sw_if_to_name = (u8 *)(p->key);
16062         if (sw_if_from_name)
16063           break;
16064       }
16065   }));
16066   /* *INDENT-ON* */
16067
16068   if (VAT_JSON_ARRAY != vam->json_tree.type)
16069     {
16070       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16071       vat_json_init_array (&vam->json_tree);
16072     }
16073   node = vat_json_array_add (&vam->json_tree);
16074
16075   vat_json_init_object (node);
16076   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16077   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16078   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16079   vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16080   vat_json_object_add_uint (node, "state", mp->state);
16081 }
16082
16083 static int
16084 api_sw_interface_span_dump (vat_main_t * vam)
16085 {
16086   vl_api_sw_interface_span_dump_t *mp;
16087   f64 timeout;
16088
16089   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
16090   S;
16091
16092   /* Use a control ping for synchronization */
16093   {
16094     vl_api_control_ping_t *mp;
16095     M (CONTROL_PING, control_ping);
16096     S;
16097   }
16098   W;
16099 }
16100
16101 int
16102 api_pg_create_interface (vat_main_t * vam)
16103 {
16104   unformat_input_t *input = vam->input;
16105   vl_api_pg_create_interface_t *mp;
16106   f64 timeout;
16107
16108   u32 if_id = ~0;
16109   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16110     {
16111       if (unformat (input, "if_id %d", &if_id))
16112         ;
16113       else
16114         break;
16115     }
16116   if (if_id == ~0)
16117     {
16118       errmsg ("missing pg interface index\n");
16119       return -99;
16120     }
16121
16122   /* Construct the API message */
16123   M (PG_CREATE_INTERFACE, pg_create_interface);
16124   mp->context = 0;
16125   mp->interface_id = ntohl (if_id);
16126
16127   S;
16128   W;
16129   /* NOTREACHED */
16130   return 0;
16131 }
16132
16133 int
16134 api_pg_capture (vat_main_t * vam)
16135 {
16136   unformat_input_t *input = vam->input;
16137   vl_api_pg_capture_t *mp;
16138   f64 timeout;
16139
16140   u32 if_id = ~0;
16141   u8 enable = 1;
16142   u32 count = 1;
16143   u8 pcap_file_set = 0;
16144   u8 *pcap_file = 0;
16145   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16146     {
16147       if (unformat (input, "if_id %d", &if_id))
16148         ;
16149       else if (unformat (input, "pcap %s", &pcap_file))
16150         pcap_file_set = 1;
16151       else if (unformat (input, "count %d", &count))
16152         ;
16153       else if (unformat (input, "disable"))
16154         enable = 0;
16155       else
16156         break;
16157     }
16158   if (if_id == ~0)
16159     {
16160       errmsg ("missing pg interface index\n");
16161       return -99;
16162     }
16163   if (pcap_file_set > 0)
16164     {
16165       if (vec_len (pcap_file) > 255)
16166         {
16167           errmsg ("pcap file name is too long\n");
16168           return -99;
16169         }
16170     }
16171
16172   u32 name_len = vec_len (pcap_file);
16173   /* Construct the API message */
16174   M (PG_CAPTURE, pg_capture);
16175   mp->context = 0;
16176   mp->interface_id = ntohl (if_id);
16177   mp->is_enabled = enable;
16178   mp->count = ntohl (count);
16179   mp->pcap_name_length = ntohl (name_len);
16180   if (pcap_file_set != 0)
16181     {
16182       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16183     }
16184   vec_free (pcap_file);
16185
16186   S;
16187   W;
16188   /* NOTREACHED */
16189   return 0;
16190 }
16191
16192 int
16193 api_pg_enable_disable (vat_main_t * vam)
16194 {
16195   unformat_input_t *input = vam->input;
16196   vl_api_pg_enable_disable_t *mp;
16197   f64 timeout;
16198
16199   u8 enable = 1;
16200   u8 stream_name_set = 0;
16201   u8 *stream_name = 0;
16202   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16203     {
16204       if (unformat (input, "stream %s", &stream_name))
16205         stream_name_set = 1;
16206       else if (unformat (input, "disable"))
16207         enable = 0;
16208       else
16209         break;
16210     }
16211
16212   if (stream_name_set > 0)
16213     {
16214       if (vec_len (stream_name) > 255)
16215         {
16216           errmsg ("stream name too long\n");
16217           return -99;
16218         }
16219     }
16220
16221   u32 name_len = vec_len (stream_name);
16222   /* Construct the API message */
16223   M (PG_ENABLE_DISABLE, pg_enable_disable);
16224   mp->context = 0;
16225   mp->is_enabled = enable;
16226   if (stream_name_set != 0)
16227     {
16228       mp->stream_name_length = ntohl (name_len);
16229       clib_memcpy (mp->stream_name, stream_name, name_len);
16230     }
16231   vec_free (stream_name);
16232
16233   S;
16234   W;
16235   /* NOTREACHED */
16236   return 0;
16237 }
16238
16239 int
16240 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16241 {
16242   unformat_input_t *input = vam->input;
16243   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16244   f64 timeout;
16245
16246   u16 *low_ports = 0;
16247   u16 *high_ports = 0;
16248   u16 this_low;
16249   u16 this_hi;
16250   ip4_address_t ip4_addr;
16251   ip6_address_t ip6_addr;
16252   u32 length;
16253   u32 tmp, tmp2;
16254   u8 prefix_set = 0;
16255   u32 vrf_id = ~0;
16256   u8 is_add = 1;
16257   u8 is_ipv6 = 0;
16258
16259   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16260     {
16261       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16262         {
16263           prefix_set = 1;
16264         }
16265       else
16266         if (unformat
16267             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16268         {
16269           prefix_set = 1;
16270           is_ipv6 = 1;
16271         }
16272       else if (unformat (input, "vrf %d", &vrf_id))
16273         ;
16274       else if (unformat (input, "del"))
16275         is_add = 0;
16276       else if (unformat (input, "port %d", &tmp))
16277         {
16278           if (tmp == 0 || tmp > 65535)
16279             {
16280               errmsg ("port %d out of range", tmp);
16281               return -99;
16282             }
16283           this_low = tmp;
16284           this_hi = this_low + 1;
16285           vec_add1 (low_ports, this_low);
16286           vec_add1 (high_ports, this_hi);
16287         }
16288       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16289         {
16290           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16291             {
16292               errmsg ("incorrect range parameters\n");
16293               return -99;
16294             }
16295           this_low = tmp;
16296           /* Note: in debug CLI +1 is added to high before
16297              passing to real fn that does "the work"
16298              (ip_source_and_port_range_check_add_del).
16299              This fn is a wrapper around the binary API fn a
16300              control plane will call, which expects this increment
16301              to have occurred. Hence letting the binary API control
16302              plane fn do the increment for consistency between VAT
16303              and other control planes.
16304            */
16305           this_hi = tmp2;
16306           vec_add1 (low_ports, this_low);
16307           vec_add1 (high_ports, this_hi);
16308         }
16309       else
16310         break;
16311     }
16312
16313   if (prefix_set == 0)
16314     {
16315       errmsg ("<address>/<mask> not specified\n");
16316       return -99;
16317     }
16318
16319   if (vrf_id == ~0)
16320     {
16321       errmsg ("VRF ID required, not specified\n");
16322       return -99;
16323     }
16324
16325   if (vrf_id == 0)
16326     {
16327       errmsg
16328         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
16329       return -99;
16330     }
16331
16332   if (vec_len (low_ports) == 0)
16333     {
16334       errmsg ("At least one port or port range required\n");
16335       return -99;
16336     }
16337
16338   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
16339      ip_source_and_port_range_check_add_del);
16340
16341   mp->is_add = is_add;
16342
16343   if (is_ipv6)
16344     {
16345       mp->is_ipv6 = 1;
16346       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16347     }
16348   else
16349     {
16350       mp->is_ipv6 = 0;
16351       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16352     }
16353
16354   mp->mask_length = length;
16355   mp->number_of_ranges = vec_len (low_ports);
16356
16357   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16358   vec_free (low_ports);
16359
16360   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16361   vec_free (high_ports);
16362
16363   mp->vrf_id = ntohl (vrf_id);
16364
16365   S;
16366   W;
16367   /* NOTREACHED */
16368   return 0;
16369 }
16370
16371 int
16372 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16373 {
16374   unformat_input_t *input = vam->input;
16375   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16376   f64 timeout;
16377   u32 sw_if_index = ~0;
16378   int vrf_set = 0;
16379   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16380   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16381   u8 is_add = 1;
16382
16383   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16384     {
16385       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
16386         ;
16387       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16388         ;
16389       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16390         vrf_set = 1;
16391       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16392         vrf_set = 1;
16393       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16394         vrf_set = 1;
16395       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16396         vrf_set = 1;
16397       else if (unformat (input, "del"))
16398         is_add = 0;
16399       else
16400         break;
16401     }
16402
16403   if (sw_if_index == ~0)
16404     {
16405       errmsg ("Interface required but not specified\n");
16406       return -99;
16407     }
16408
16409   if (vrf_set == 0)
16410     {
16411       errmsg ("VRF ID required but not specified\n");
16412       return -99;
16413     }
16414
16415   if (tcp_out_vrf_id == 0
16416       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16417     {
16418       errmsg
16419         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
16420       return -99;
16421     }
16422
16423   /* Construct the API message */
16424   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
16425      ip_source_and_port_range_check_interface_add_del);
16426
16427   mp->sw_if_index = ntohl (sw_if_index);
16428   mp->is_add = is_add;
16429   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16430   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16431   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16432   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16433
16434   /* send it... */
16435   S;
16436
16437   /* Wait for a reply... */
16438   W;
16439 }
16440
16441 static int
16442 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16443 {
16444   unformat_input_t *i = vam->input;
16445   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16446   f64 timeout;
16447   u32 local_sa_id = 0;
16448   u32 remote_sa_id = 0;
16449   ip4_address_t src_address;
16450   ip4_address_t dst_address;
16451   u8 is_add = 1;
16452
16453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16454     {
16455       if (unformat (i, "local_sa %d", &local_sa_id))
16456         ;
16457       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16458         ;
16459       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16460         ;
16461       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16462         ;
16463       else if (unformat (i, "del"))
16464         is_add = 0;
16465       else
16466         {
16467           clib_warning ("parse error '%U'", format_unformat_error, i);
16468           return -99;
16469         }
16470     }
16471
16472   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
16473
16474   mp->local_sa_id = ntohl (local_sa_id);
16475   mp->remote_sa_id = ntohl (remote_sa_id);
16476   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16477   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16478   mp->is_add = is_add;
16479
16480   S;
16481   W;
16482   /* NOTREACHED */
16483   return 0;
16484 }
16485
16486 static int
16487 api_punt (vat_main_t * vam)
16488 {
16489   unformat_input_t *i = vam->input;
16490   vl_api_punt_t *mp;
16491   f64 timeout;
16492   u32 ipv = ~0;
16493   u32 protocol = ~0;
16494   u32 port = ~0;
16495   int is_add = 1;
16496
16497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16498     {
16499       if (unformat (i, "ip %d", &ipv))
16500         ;
16501       else if (unformat (i, "protocol %d", &protocol))
16502         ;
16503       else if (unformat (i, "port %d", &port))
16504         ;
16505       else if (unformat (i, "del"))
16506         is_add = 0;
16507       else
16508         {
16509           clib_warning ("parse error '%U'", format_unformat_error, i);
16510           return -99;
16511         }
16512     }
16513
16514   M (PUNT, punt);
16515
16516   mp->is_add = (u8) is_add;
16517   mp->ipv = (u8) ipv;
16518   mp->l4_protocol = (u8) protocol;
16519   mp->l4_port = htons ((u16) port);
16520
16521   S;
16522   W;
16523   /* NOTREACHED */
16524   return 0;
16525 }
16526
16527 static void vl_api_ipsec_gre_tunnel_details_t_handler
16528   (vl_api_ipsec_gre_tunnel_details_t * mp)
16529 {
16530   vat_main_t *vam = &vat_main;
16531
16532   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
16533            ntohl (mp->sw_if_index),
16534            format_ip4_address, &mp->src_address,
16535            format_ip4_address, &mp->dst_address,
16536            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16537 }
16538
16539 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16540   (vl_api_ipsec_gre_tunnel_details_t * mp)
16541 {
16542   vat_main_t *vam = &vat_main;
16543   vat_json_node_t *node = NULL;
16544   struct in_addr ip4;
16545
16546   if (VAT_JSON_ARRAY != vam->json_tree.type)
16547     {
16548       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16549       vat_json_init_array (&vam->json_tree);
16550     }
16551   node = vat_json_array_add (&vam->json_tree);
16552
16553   vat_json_init_object (node);
16554   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16555   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16556   vat_json_object_add_ip4 (node, "src_address", ip4);
16557   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16558   vat_json_object_add_ip4 (node, "dst_address", ip4);
16559   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16560   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16561 }
16562
16563 static int
16564 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16565 {
16566   unformat_input_t *i = vam->input;
16567   vl_api_ipsec_gre_tunnel_dump_t *mp;
16568   f64 timeout;
16569   u32 sw_if_index;
16570   u8 sw_if_index_set = 0;
16571
16572   /* Parse args required to build the message */
16573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16574     {
16575       if (unformat (i, "sw_if_index %d", &sw_if_index))
16576         sw_if_index_set = 1;
16577       else
16578         break;
16579     }
16580
16581   if (sw_if_index_set == 0)
16582     {
16583       sw_if_index = ~0;
16584     }
16585
16586   if (!vam->json_output)
16587     {
16588       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
16589                "sw_if_index", "src_address", "dst_address",
16590                "local_sa_id", "remote_sa_id");
16591     }
16592
16593   /* Get list of gre-tunnel interfaces */
16594   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16595
16596   mp->sw_if_index = htonl (sw_if_index);
16597
16598   S;
16599
16600   /* Use a control ping for synchronization */
16601   {
16602     vl_api_control_ping_t *mp;
16603     M (CONTROL_PING, control_ping);
16604     S;
16605   }
16606   W;
16607 }
16608
16609 static int
16610 api_delete_subif (vat_main_t * vam)
16611 {
16612   unformat_input_t *i = vam->input;
16613   vl_api_delete_subif_t *mp;
16614   f64 timeout;
16615   u32 sw_if_index = ~0;
16616
16617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16618     {
16619       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16620         ;
16621       if (unformat (i, "sw_if_index %d", &sw_if_index))
16622         ;
16623       else
16624         break;
16625     }
16626
16627   if (sw_if_index == ~0)
16628     {
16629       errmsg ("missing sw_if_index\n");
16630       return -99;
16631     }
16632
16633   /* Construct the API message */
16634   M (DELETE_SUBIF, delete_subif);
16635   mp->sw_if_index = ntohl (sw_if_index);
16636
16637   S;
16638   W;
16639 }
16640
16641 #define foreach_pbb_vtr_op      \
16642 _("disable",  L2_VTR_DISABLED)  \
16643 _("pop",  L2_VTR_POP_2)         \
16644 _("push",  L2_VTR_PUSH_2)
16645
16646 static int
16647 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16648 {
16649   unformat_input_t *i = vam->input;
16650   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16651   f64 timeout;
16652   u32 sw_if_index = ~0, vtr_op = ~0;
16653   u16 outer_tag = ~0;
16654   u8 dmac[6], smac[6];
16655   u8 dmac_set = 0, smac_set = 0;
16656   u16 vlanid = 0;
16657   u32 sid = ~0;
16658   u32 tmp;
16659
16660   /* Shut up coverity */
16661   memset (dmac, 0, sizeof (dmac));
16662   memset (smac, 0, sizeof (smac));
16663
16664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16665     {
16666       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16667         ;
16668       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16669         ;
16670       else if (unformat (i, "vtr_op %d", &vtr_op))
16671         ;
16672 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16673       foreach_pbb_vtr_op
16674 #undef _
16675         else if (unformat (i, "translate_pbb_stag"))
16676         {
16677           if (unformat (i, "%d", &tmp))
16678             {
16679               vtr_op = L2_VTR_TRANSLATE_2_1;
16680               outer_tag = tmp;
16681             }
16682           else
16683             {
16684               errmsg
16685                 ("translate_pbb_stag operation requires outer tag definition\n");
16686               return -99;
16687             }
16688         }
16689       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16690         dmac_set++;
16691       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16692         smac_set++;
16693       else if (unformat (i, "sid %d", &sid))
16694         ;
16695       else if (unformat (i, "vlanid %d", &tmp))
16696         vlanid = tmp;
16697       else
16698         {
16699           clib_warning ("parse error '%U'", format_unformat_error, i);
16700           return -99;
16701         }
16702     }
16703
16704   if ((sw_if_index == ~0) || (vtr_op == ~0))
16705     {
16706       errmsg ("missing sw_if_index or vtr operation\n");
16707       return -99;
16708     }
16709   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16710       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16711     {
16712       errmsg
16713         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
16714       return -99;
16715     }
16716
16717   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16718   mp->sw_if_index = ntohl (sw_if_index);
16719   mp->vtr_op = ntohl (vtr_op);
16720   mp->outer_tag = ntohs (outer_tag);
16721   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16722   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16723   mp->b_vlanid = ntohs (vlanid);
16724   mp->i_sid = ntohl (sid);
16725
16726   S;
16727   W;
16728   /* NOTREACHED */
16729   return 0;
16730 }
16731
16732 static int
16733 api_flow_classify_set_interface (vat_main_t * vam)
16734 {
16735   unformat_input_t *i = vam->input;
16736   vl_api_flow_classify_set_interface_t *mp;
16737   f64 timeout;
16738   u32 sw_if_index;
16739   int sw_if_index_set;
16740   u32 ip4_table_index = ~0;
16741   u32 ip6_table_index = ~0;
16742   u8 is_add = 1;
16743
16744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16745     {
16746       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16747         sw_if_index_set = 1;
16748       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16749         sw_if_index_set = 1;
16750       else if (unformat (i, "del"))
16751         is_add = 0;
16752       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16753         ;
16754       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16755         ;
16756       else
16757         {
16758           clib_warning ("parse error '%U'", format_unformat_error, i);
16759           return -99;
16760         }
16761     }
16762
16763   if (sw_if_index_set == 0)
16764     {
16765       errmsg ("missing interface name or sw_if_index\n");
16766       return -99;
16767     }
16768
16769   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16770
16771   mp->sw_if_index = ntohl (sw_if_index);
16772   mp->ip4_table_index = ntohl (ip4_table_index);
16773   mp->ip6_table_index = ntohl (ip6_table_index);
16774   mp->is_add = is_add;
16775
16776   S;
16777   W;
16778   /* NOTREACHED */
16779   return 0;
16780 }
16781
16782 static int
16783 api_flow_classify_dump (vat_main_t * vam)
16784 {
16785   unformat_input_t *i = vam->input;
16786   vl_api_flow_classify_dump_t *mp;
16787   f64 timeout = ~0;
16788   u8 type = FLOW_CLASSIFY_N_TABLES;
16789
16790   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16791     ;
16792   else
16793     {
16794       errmsg ("classify table type must be specified\n");
16795       return -99;
16796     }
16797
16798   if (!vam->json_output)
16799     {
16800       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
16801     }
16802
16803   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16804   mp->type = type;
16805   /* send it... */
16806   S;
16807
16808   /* Use a control ping for synchronization */
16809   {
16810     vl_api_control_ping_t *mp;
16811     M (CONTROL_PING, control_ping);
16812     S;
16813   }
16814   /* Wait for a reply... */
16815   W;
16816
16817   /* NOTREACHED */
16818   return 0;
16819 }
16820
16821 static int
16822 api_feature_enable_disable (vat_main_t * vam)
16823 {
16824   unformat_input_t *i = vam->input;
16825   vl_api_feature_enable_disable_t *mp;
16826   f64 timeout;
16827   u8 *arc_name = 0;
16828   u8 *feature_name = 0;
16829   u32 sw_if_index = ~0;
16830   u8 enable = 1;
16831
16832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16833     {
16834       if (unformat (i, "arc_name %s", &arc_name))
16835         ;
16836       else if (unformat (i, "feature_name %s", &feature_name))
16837         ;
16838       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16839         ;
16840       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16841         ;
16842       else if (unformat (i, "disable"))
16843         enable = 0;
16844       else
16845         break;
16846     }
16847
16848   if (arc_name == 0)
16849     {
16850       errmsg ("missing arc name\n");
16851       return -99;
16852     }
16853   if (vec_len (arc_name) > 63)
16854     {
16855       errmsg ("arc name too long\n");
16856     }
16857
16858   if (feature_name == 0)
16859     {
16860       errmsg ("missing feature name\n");
16861       return -99;
16862     }
16863   if (vec_len (feature_name) > 63)
16864     {
16865       errmsg ("feature name too long\n");
16866     }
16867
16868   if (sw_if_index == ~0)
16869     {
16870       errmsg ("missing interface name or sw_if_index\n");
16871       return -99;
16872     }
16873
16874   /* Construct the API message */
16875   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16876   mp->sw_if_index = ntohl (sw_if_index);
16877   mp->enable = enable;
16878   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16879   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16880   vec_free (arc_name);
16881   vec_free (feature_name);
16882
16883   S;
16884   W;
16885 }
16886
16887 static int
16888 api_sw_interface_tag_add_del (vat_main_t * vam)
16889 {
16890   unformat_input_t *i = vam->input;
16891   vl_api_sw_interface_tag_add_del_t *mp;
16892   f64 timeout;
16893   u32 sw_if_index = ~0;
16894   u8 *tag = 0;
16895   u8 enable = 1;
16896
16897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16898     {
16899       if (unformat (i, "tag %s", &tag))
16900         ;
16901       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16902         ;
16903       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16904         ;
16905       else if (unformat (i, "del"))
16906         enable = 0;
16907       else
16908         break;
16909     }
16910
16911   if (sw_if_index == ~0)
16912     {
16913       errmsg ("missing interface name or sw_if_index\n");
16914       return -99;
16915     }
16916
16917   if (enable && (tag == 0))
16918     {
16919       errmsg ("no tag specified\n");
16920       return -99;
16921     }
16922
16923   /* Construct the API message */
16924   M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
16925   mp->sw_if_index = ntohl (sw_if_index);
16926   mp->is_add = enable;
16927   if (enable)
16928     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
16929   vec_free (tag);
16930
16931   S;
16932   W;
16933 }
16934
16935 static void vl_api_l2_xconnect_details_t_handler
16936   (vl_api_l2_xconnect_details_t * mp)
16937 {
16938   vat_main_t *vam = &vat_main;
16939
16940   fformat (vam->ofp, "%15d%15d\n",
16941            ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
16942 }
16943
16944 static void vl_api_l2_xconnect_details_t_handler_json
16945   (vl_api_l2_xconnect_details_t * mp)
16946 {
16947   vat_main_t *vam = &vat_main;
16948   vat_json_node_t *node = NULL;
16949
16950   if (VAT_JSON_ARRAY != vam->json_tree.type)
16951     {
16952       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16953       vat_json_init_array (&vam->json_tree);
16954     }
16955   node = vat_json_array_add (&vam->json_tree);
16956
16957   vat_json_init_object (node);
16958   vat_json_object_add_uint (node, "rx_sw_if_index",
16959                             ntohl (mp->rx_sw_if_index));
16960   vat_json_object_add_uint (node, "tx_sw_if_index",
16961                             ntohl (mp->tx_sw_if_index));
16962 }
16963
16964 static int
16965 api_l2_xconnect_dump (vat_main_t * vam)
16966 {
16967   vl_api_l2_xconnect_dump_t *mp;
16968   f64 timeout;
16969
16970   if (!vam->json_output)
16971     {
16972       fformat (vam->ofp, "%15s%15s\n", "rx_sw_if_index", "tx_sw_if_index");
16973     }
16974
16975   M (L2_XCONNECT_DUMP, l2_xconnect_dump);
16976
16977   S;
16978
16979   /* Use a control ping for synchronization */
16980   {
16981     vl_api_control_ping_t *mp;
16982     M (CONTROL_PING, control_ping);
16983     S;
16984   }
16985   W;
16986 }
16987
16988 static int
16989 api_sw_interface_set_mtu (vat_main_t * vam)
16990 {
16991   unformat_input_t *i = vam->input;
16992   vl_api_sw_interface_set_mtu_t *mp;
16993   f64 timeout;
16994   u32 sw_if_index = ~0;
16995   u32 mtu = 0;
16996
16997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16998     {
16999       if (unformat (i, "mtu %d", &mtu))
17000         ;
17001       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
17002         ;
17003       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17004         ;
17005       else
17006         break;
17007     }
17008
17009   if (sw_if_index == ~0)
17010     {
17011       errmsg ("missing interface name or sw_if_index\n");
17012       return -99;
17013     }
17014
17015   if (mtu == 0)
17016     {
17017       errmsg ("no mtu specified\n");
17018       return -99;
17019     }
17020
17021   /* Construct the API message */
17022   M (SW_INTERFACE_SET_MTU, sw_interface_set_mtu);
17023   mp->sw_if_index = ntohl (sw_if_index);
17024   mp->mtu = ntohs ((u16) mtu);
17025
17026   S;
17027   W;
17028 }
17029
17030
17031 static int
17032 q_or_quit (vat_main_t * vam)
17033 {
17034   longjmp (vam->jump_buf, 1);
17035   return 0;                     /* not so much */
17036 }
17037
17038 static int
17039 q (vat_main_t * vam)
17040 {
17041   return q_or_quit (vam);
17042 }
17043
17044 static int
17045 quit (vat_main_t * vam)
17046 {
17047   return q_or_quit (vam);
17048 }
17049
17050 static int
17051 comment (vat_main_t * vam)
17052 {
17053   return 0;
17054 }
17055
17056 static int
17057 cmd_cmp (void *a1, void *a2)
17058 {
17059   u8 **c1 = a1;
17060   u8 **c2 = a2;
17061
17062   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17063 }
17064
17065 static int
17066 help (vat_main_t * vam)
17067 {
17068   u8 **cmds = 0;
17069   u8 *name = 0;
17070   hash_pair_t *p;
17071   unformat_input_t *i = vam->input;
17072   int j;
17073
17074   if (unformat (i, "%s", &name))
17075     {
17076       uword *hs;
17077
17078       vec_add1 (name, 0);
17079
17080       hs = hash_get_mem (vam->help_by_name, name);
17081       if (hs)
17082         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
17083       else
17084         fformat (vam->ofp, "No such msg / command '%s'\n", name);
17085       vec_free (name);
17086       return 0;
17087     }
17088
17089   fformat (vam->ofp, "Help is available for the following:\n");
17090
17091     /* *INDENT-OFF* */
17092     hash_foreach_pair (p, vam->function_by_name,
17093     ({
17094       vec_add1 (cmds, (u8 *)(p->key));
17095     }));
17096     /* *INDENT-ON* */
17097
17098   vec_sort_with_function (cmds, cmd_cmp);
17099
17100   for (j = 0; j < vec_len (cmds); j++)
17101     fformat (vam->ofp, "%s\n", cmds[j]);
17102
17103   vec_free (cmds);
17104   return 0;
17105 }
17106
17107 static int
17108 set (vat_main_t * vam)
17109 {
17110   u8 *name = 0, *value = 0;
17111   unformat_input_t *i = vam->input;
17112
17113   if (unformat (i, "%s", &name))
17114     {
17115       /* The input buffer is a vector, not a string. */
17116       value = vec_dup (i->buffer);
17117       vec_delete (value, i->index, 0);
17118       /* Almost certainly has a trailing newline */
17119       if (value[vec_len (value) - 1] == '\n')
17120         value[vec_len (value) - 1] = 0;
17121       /* Make sure it's a proper string, one way or the other */
17122       vec_add1 (value, 0);
17123       (void) clib_macro_set_value (&vam->macro_main,
17124                                    (char *) name, (char *) value);
17125     }
17126   else
17127     errmsg ("usage: set <name> <value>\n");
17128
17129   vec_free (name);
17130   vec_free (value);
17131   return 0;
17132 }
17133
17134 static int
17135 unset (vat_main_t * vam)
17136 {
17137   u8 *name = 0;
17138
17139   if (unformat (vam->input, "%s", &name))
17140     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17141       errmsg ("unset: %s wasn't set\n", name);
17142   vec_free (name);
17143   return 0;
17144 }
17145
17146 typedef struct
17147 {
17148   u8 *name;
17149   u8 *value;
17150 } macro_sort_t;
17151
17152
17153 static int
17154 macro_sort_cmp (void *a1, void *a2)
17155 {
17156   macro_sort_t *s1 = a1;
17157   macro_sort_t *s2 = a2;
17158
17159   return strcmp ((char *) (s1->name), (char *) (s2->name));
17160 }
17161
17162 static int
17163 dump_macro_table (vat_main_t * vam)
17164 {
17165   macro_sort_t *sort_me = 0, *sm;
17166   int i;
17167   hash_pair_t *p;
17168
17169     /* *INDENT-OFF* */
17170     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17171     ({
17172       vec_add2 (sort_me, sm, 1);
17173       sm->name = (u8 *)(p->key);
17174       sm->value = (u8 *) (p->value[0]);
17175     }));
17176     /* *INDENT-ON* */
17177
17178   vec_sort_with_function (sort_me, macro_sort_cmp);
17179
17180   if (vec_len (sort_me))
17181     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
17182   else
17183     fformat (vam->ofp, "The macro table is empty...\n");
17184
17185   for (i = 0; i < vec_len (sort_me); i++)
17186     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
17187   return 0;
17188 }
17189
17190 static int
17191 dump_node_table (vat_main_t * vam)
17192 {
17193   int i, j;
17194   vlib_node_t *node, *next_node;
17195
17196   if (vec_len (vam->graph_nodes) == 0)
17197     {
17198       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
17199       return 0;
17200     }
17201
17202   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17203     {
17204       node = vam->graph_nodes[i];
17205       fformat (vam->ofp, "[%d] %s\n", i, node->name);
17206       for (j = 0; j < vec_len (node->next_nodes); j++)
17207         {
17208           if (node->next_nodes[j] != ~0)
17209             {
17210               next_node = vam->graph_nodes[node->next_nodes[j]];
17211               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
17212             }
17213         }
17214     }
17215   return 0;
17216 }
17217
17218 static int
17219 value_sort_cmp (void *a1, void *a2)
17220 {
17221   name_sort_t *n1 = a1;
17222   name_sort_t *n2 = a2;
17223
17224   if (n1->value < n2->value)
17225     return -1;
17226   if (n1->value > n2->value)
17227     return 1;
17228   return 0;
17229 }
17230
17231
17232 static int
17233 dump_msg_api_table (vat_main_t * vam)
17234 {
17235   api_main_t *am = &api_main;
17236   name_sort_t *nses = 0, *ns;
17237   hash_pair_t *hp;
17238   int i;
17239
17240   /* *INDENT-OFF* */
17241   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17242   ({
17243     vec_add2 (nses, ns, 1);
17244     ns->name = (u8 *)(hp->key);
17245     ns->value = (u32) hp->value[0];
17246   }));
17247   /* *INDENT-ON* */
17248
17249   vec_sort_with_function (nses, value_sort_cmp);
17250
17251   for (i = 0; i < vec_len (nses); i++)
17252     fformat (vam->ofp, " [%d]: %s\n", nses[i].value, nses[i].name);
17253   vec_free (nses);
17254   return 0;
17255 }
17256
17257 static int
17258 get_msg_id (vat_main_t * vam)
17259 {
17260   u8 *name_and_crc;
17261   u32 message_index;
17262
17263   if (unformat (vam->input, "%s", &name_and_crc))
17264     {
17265       message_index = vl_api_get_msg_index (name_and_crc);
17266       if (message_index == ~0)
17267         {
17268           fformat (vam->ofp, " '%s' not found\n", name_and_crc);
17269           return 0;
17270         }
17271       fformat (vam->ofp, " '%s' has message index %d\n",
17272                name_and_crc, message_index);
17273       return 0;
17274     }
17275   errmsg ("name_and_crc required...\n");
17276   return 0;
17277 }
17278
17279 static int
17280 search_node_table (vat_main_t * vam)
17281 {
17282   unformat_input_t *line_input = vam->input;
17283   u8 *node_to_find;
17284   int j;
17285   vlib_node_t *node, *next_node;
17286   uword *p;
17287
17288   if (vam->graph_node_index_by_name == 0)
17289     {
17290       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
17291       return 0;
17292     }
17293
17294   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17295     {
17296       if (unformat (line_input, "%s", &node_to_find))
17297         {
17298           vec_add1 (node_to_find, 0);
17299           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17300           if (p == 0)
17301             {
17302               fformat (vam->ofp, "%s not found...\n", node_to_find);
17303               goto out;
17304             }
17305           node = vam->graph_nodes[p[0]];
17306           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
17307           for (j = 0; j < vec_len (node->next_nodes); j++)
17308             {
17309               if (node->next_nodes[j] != ~0)
17310                 {
17311                   next_node = vam->graph_nodes[node->next_nodes[j]];
17312                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
17313                 }
17314             }
17315         }
17316
17317       else
17318         {
17319           clib_warning ("parse error '%U'", format_unformat_error,
17320                         line_input);
17321           return -99;
17322         }
17323
17324     out:
17325       vec_free (node_to_find);
17326
17327     }
17328
17329   return 0;
17330 }
17331
17332
17333 static int
17334 script (vat_main_t * vam)
17335 {
17336   u8 *s = 0;
17337   char *save_current_file;
17338   unformat_input_t save_input;
17339   jmp_buf save_jump_buf;
17340   u32 save_line_number;
17341
17342   FILE *new_fp, *save_ifp;
17343
17344   if (unformat (vam->input, "%s", &s))
17345     {
17346       new_fp = fopen ((char *) s, "r");
17347       if (new_fp == 0)
17348         {
17349           errmsg ("Couldn't open script file %s\n", s);
17350           vec_free (s);
17351           return -99;
17352         }
17353     }
17354   else
17355     {
17356       errmsg ("Missing script name\n");
17357       return -99;
17358     }
17359
17360   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17361   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17362   save_ifp = vam->ifp;
17363   save_line_number = vam->input_line_number;
17364   save_current_file = (char *) vam->current_file;
17365
17366   vam->input_line_number = 0;
17367   vam->ifp = new_fp;
17368   vam->current_file = s;
17369   do_one_file (vam);
17370
17371   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17372   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17373   vam->ifp = save_ifp;
17374   vam->input_line_number = save_line_number;
17375   vam->current_file = (u8 *) save_current_file;
17376   vec_free (s);
17377
17378   return 0;
17379 }
17380
17381 static int
17382 echo (vat_main_t * vam)
17383 {
17384   fformat (vam->ofp, "%v", vam->input->buffer);
17385   return 0;
17386 }
17387
17388 /* List of API message constructors, CLI names map to api_xxx */
17389 #define foreach_vpe_api_msg                                             \
17390 _(create_loopback,"[mac <mac-addr>]")                                   \
17391 _(sw_interface_dump,"")                                                 \
17392 _(sw_interface_set_flags,                                               \
17393   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17394 _(sw_interface_add_del_address,                                         \
17395   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17396 _(sw_interface_set_table,                                               \
17397   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17398 _(sw_interface_set_mpls_enable,                                                \
17399   "<intfc> | sw_if_index [disable | dis]")                                \
17400 _(sw_interface_set_vpath,                                               \
17401   "<intfc> | sw_if_index <id> enable | disable")                        \
17402 _(sw_interface_set_vxlan_bypass,                                               \
17403   "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable")                        \
17404 _(sw_interface_set_l2_xconnect,                                         \
17405   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17406   "enable | disable")                                                   \
17407 _(sw_interface_set_l2_bridge,                                           \
17408   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
17409   "[shg <split-horizon-group>] [bvi]\n"                                 \
17410   "enable | disable")                                                   \
17411 _(sw_interface_set_dpdk_hqos_pipe,                                      \
17412   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
17413   "profile <profile-id>\n")                                             \
17414 _(sw_interface_set_dpdk_hqos_subport,                                   \
17415   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
17416   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
17417 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
17418   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
17419 _(bridge_domain_add_del,                                                \
17420   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
17421 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
17422 _(l2fib_add_del,                                                        \
17423   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17424 _(l2_flags,                                                             \
17425   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
17426 _(bridge_flags,                                                         \
17427   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17428 _(tap_connect,                                                          \
17429   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17430 _(tap_modify,                                                           \
17431   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17432 _(tap_delete,                                                           \
17433   "<vpp-if-name> | sw_if_index <id>")                                   \
17434 _(sw_interface_tap_dump, "")                                            \
17435 _(ip_add_del_route,                                                     \
17436   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17437   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17438   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17439   "[multipath] [count <n>]")                                            \
17440 _(mpls_route_add_del,                                                   \
17441   "<label> <eos> 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_ip_bind_unbind,                                                  \
17446   "<label> <addr/len>")                                                 \
17447 _(mpls_tunnel_add_del,                                                  \
17448   " via <addr> [table-id <n>]\n"                                        \
17449   "sw_if_index <id>] [l2]  [del]")                                      \
17450 _(proxy_arp_add_del,                                                    \
17451   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17452 _(proxy_arp_intfc_enable_disable,                                       \
17453   "<intfc> | sw_if_index <id> enable | disable")                        \
17454 _(sw_interface_set_unnumbered,                                          \
17455   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17456 _(ip_neighbor_add_del,                                                  \
17457   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17458   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17459 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17460 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17461 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17462   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17463   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17464   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17465 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17466 _(reset_fib, "vrf <n> [ipv6]")                                          \
17467 _(dhcp_proxy_config,                                                    \
17468   "svr <v46-address> src <v46-address>\n"                               \
17469    "insert-cid <n> [del]")                                              \
17470 _(dhcp_proxy_config_2,                                                  \
17471   "svr <v46-address> src <v46-address>\n"                               \
17472    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
17473 _(dhcp_proxy_set_vss,                                                   \
17474   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17475 _(dhcp_client_config,                                                   \
17476   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17477 _(set_ip_flow_hash,                                                     \
17478   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17479 _(sw_interface_ip6_enable_disable,                                      \
17480   "<intfc> | sw_if_index <id> enable | disable")                        \
17481 _(sw_interface_ip6_set_link_local_address,                              \
17482   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17483 _(sw_interface_ip6nd_ra_prefix,                                         \
17484   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17485   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17486   "[nolink] [isno]")                                                    \
17487 _(sw_interface_ip6nd_ra_config,                                         \
17488   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17489   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17490   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17491 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17492 _(l2_patch_add_del,                                                     \
17493   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17494   "enable | disable")                                                   \
17495 _(sr_tunnel_add_del,                                                    \
17496   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
17497   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
17498   "[policy <policy_name>]")                                             \
17499 _(sr_policy_add_del,                                                    \
17500   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
17501 _(sr_multicast_map_add_del,                                             \
17502   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
17503 _(classify_add_del_table,                                               \
17504   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17505   " [del] [del-chain] mask <mask-value>\n"                              \
17506   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17507   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17508 _(classify_add_del_session,                                             \
17509   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17510   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17511   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17512   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17513 _(classify_set_interface_ip_table,                                      \
17514   "<intfc> | sw_if_index <nn> table <nn>")                              \
17515 _(classify_set_interface_l2_tables,                                     \
17516   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17517   "  [other-table <nn>]")                                               \
17518 _(get_node_index, "node <node-name")                                    \
17519 _(add_node_next, "node <node-name> next <next-node-name>")              \
17520 _(l2tpv3_create_tunnel,                                                 \
17521   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17522   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
17523   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17524 _(l2tpv3_set_tunnel_cookies,                                            \
17525   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17526   "[new_remote_cookie <nn>]\n")                                         \
17527 _(l2tpv3_interface_enable_disable,                                      \
17528   "<intfc> | sw_if_index <nn> enable | disable")                        \
17529 _(l2tpv3_set_lookup_key,                                                \
17530   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
17531 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
17532 _(vxlan_add_del_tunnel,                                                 \
17533   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
17534   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
17535   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
17536 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
17537 _(gre_add_del_tunnel,                                                   \
17538   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
17539 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
17540 _(l2_fib_clear_table, "")                                               \
17541 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
17542 _(l2_interface_vlan_tag_rewrite,                                        \
17543   "<intfc> | sw_if_index <nn> \n"                                       \
17544   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
17545   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
17546 _(create_vhost_user_if,                                                 \
17547         "socket <filename> [server] [renumber <dev_instance>] "         \
17548         "[mac <mac_address>]")                                          \
17549 _(modify_vhost_user_if,                                                 \
17550         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
17551         "[server] [renumber <dev_instance>]")                           \
17552 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
17553 _(sw_interface_vhost_user_dump, "")                                     \
17554 _(show_version, "")                                                     \
17555 _(vxlan_gpe_add_del_tunnel,                                             \
17556   "local <addr> remote <addr> vni <nn>\n"                               \
17557     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
17558   "[next-ethernet] [next-nsh]\n")                                       \
17559 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
17560 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
17561 _(interface_name_renumber,                                              \
17562   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
17563 _(input_acl_set_interface,                                              \
17564   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17565   "  [l2-table <nn>] [del]")                                            \
17566 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
17567 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
17568 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
17569 _(ip_dump, "ipv4 | ipv6")                                               \
17570 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
17571 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
17572   "  spid_id <n> ")                                                     \
17573 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
17574   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
17575   "  integ_alg <alg> integ_key <hex>")                                  \
17576 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
17577   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
17578   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
17579   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
17580 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
17581 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
17582 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
17583   "(auth_data 0x<data> | auth_data <data>)")                            \
17584 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
17585   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
17586 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
17587   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
17588   "(local|remote)")                                                     \
17589 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
17590 _(delete_loopback,"sw_if_index <nn>")                                   \
17591 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
17592 _(map_add_domain,                                                       \
17593   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
17594   "ip6-src <ip6addr> "                                                  \
17595   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
17596 _(map_del_domain, "index <n>")                                          \
17597 _(map_add_del_rule,                                                     \
17598   "index <n> psid <n> dst <ip6addr> [del]")                             \
17599 _(map_domain_dump, "")                                                  \
17600 _(map_rule_dump, "index <map-domain>")                                  \
17601 _(want_interface_events,  "enable|disable")                             \
17602 _(want_stats,"enable|disable")                                          \
17603 _(get_first_msg_id, "client <name>")                                    \
17604 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
17605 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
17606   "fib-id <nn> [ip4][ip6][default]")                                    \
17607 _(get_node_graph, " ")                                                  \
17608 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
17609 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
17610 _(ioam_disable, "")                                                \
17611 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
17612                             " sw_if_index <sw_if_index> p <priority> "  \
17613                             "w <weight>] [del]")                        \
17614 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
17615                         "iface <intf> | sw_if_index <sw_if_index> "     \
17616                         "p <priority> w <weight> [del]")                \
17617 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
17618                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
17619                          "locator-set <locator_name> [del]"             \
17620                          "[key-id sha1|sha256 secret-key <secret-key>]")\
17621 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
17622   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
17623 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
17624 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
17625 _(lisp_gpe_enable_disable, "enable|disable")                            \
17626 _(lisp_enable_disable, "enable|disable")                                \
17627 _(lisp_map_register_enable_disable, "enable|disable")                   \
17628 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
17629 _(lisp_gpe_add_del_iface, "up|down")                                    \
17630 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
17631                                "[seid <seid>] "                         \
17632                                "rloc <locator> p <prio> "               \
17633                                "w <weight> [rloc <loc> ... ] "          \
17634                                "action <action> [del-all]")             \
17635 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
17636                           "<local-eid>")                                \
17637 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
17638 _(lisp_map_request_mode, "src-dst|dst-only")                            \
17639 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
17640 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
17641 _(lisp_locator_set_dump, "[local | remote]")                            \
17642 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
17643 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
17644                        "[local] | [remote]")                            \
17645 _(lisp_eid_table_vni_dump, "")                                          \
17646 _(lisp_eid_table_map_dump, "l2|l3")                                     \
17647 _(lisp_gpe_tunnel_dump, "")                                             \
17648 _(lisp_map_resolver_dump, "")                                           \
17649 _(lisp_map_server_dump, "")                                             \
17650 _(lisp_adjacencies_get, "vni <vni>")                                    \
17651 _(show_lisp_rloc_probe_state, "")                                       \
17652 _(show_lisp_map_register_state, "")                                     \
17653 _(show_lisp_status, "")                                                 \
17654 _(lisp_get_map_request_itr_rlocs, "")                                   \
17655 _(show_lisp_pitr, "")                                                   \
17656 _(show_lisp_map_request_mode, "")                                       \
17657 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
17658 _(af_packet_delete, "name <host interface name>")                       \
17659 _(policer_add_del, "name <policer name> <params> [del]")                \
17660 _(policer_dump, "[name <policer name>]")                                \
17661 _(policer_classify_set_interface,                                       \
17662   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17663   "  [l2-table <nn>] [del]")                                            \
17664 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
17665 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
17666     "[master|slave]")                                                   \
17667 _(netmap_delete, "name <interface name>")                               \
17668 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
17669 _(mpls_fib_dump, "")                                                    \
17670 _(classify_table_ids, "")                                               \
17671 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
17672 _(classify_table_info, "table_id <nn>")                                 \
17673 _(classify_session_dump, "table_id <nn>")                               \
17674 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
17675     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
17676     "[template_interval <nn>] [udp_checksum]")                          \
17677 _(ipfix_exporter_dump, "")                                              \
17678 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17679 _(ipfix_classify_stream_dump, "")                                       \
17680 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
17681 _(ipfix_classify_table_dump, "")                                        \
17682 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
17683 _(sw_interface_span_dump, "")                                           \
17684 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
17685 _(pg_create_interface, "if_id <nn>")                                    \
17686 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
17687 _(pg_enable_disable, "[stream <id>] disable")                           \
17688 _(ip_source_and_port_range_check_add_del,                               \
17689   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
17690 _(ip_source_and_port_range_check_interface_add_del,                     \
17691   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
17692   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
17693 _(ipsec_gre_add_del_tunnel,                                             \
17694   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
17695 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
17696 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
17697 _(l2_interface_pbb_tag_rewrite,                                         \
17698   "<intfc> | sw_if_index <nn> \n"                                       \
17699   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
17700   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
17701 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
17702 _(flow_classify_set_interface,                                          \
17703   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17704 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17705 _(ip_fib_dump, "")                                                      \
17706 _(ip6_fib_dump, "")                                                     \
17707 _(feature_enable_disable, "arc_name <arc_name> "                        \
17708   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
17709 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
17710 "[disable]")                                                            \
17711 _(l2_xconnect_dump, "")                                                 \
17712 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
17713 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
17714 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
17715
17716 /* List of command functions, CLI names map directly to functions */
17717 #define foreach_cli_function                                    \
17718 _(comment, "usage: comment <ignore-rest-of-line>")              \
17719 _(dump_interface_table, "usage: dump_interface_table")          \
17720 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17721 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17722 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17723 _(dump_stats_table, "usage: dump_stats_table")                  \
17724 _(dump_macro_table, "usage: dump_macro_table ")                 \
17725 _(dump_node_table, "usage: dump_node_table")                    \
17726 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17727 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17728 _(echo, "usage: echo <message>")                                \
17729 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17730 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17731 _(help, "usage: help")                                          \
17732 _(q, "usage: quit")                                             \
17733 _(quit, "usage: quit")                                          \
17734 _(search_node_table, "usage: search_node_table <name>...")      \
17735 _(set, "usage: set <variable-name> <value>")                    \
17736 _(script, "usage: script <file-name>")                          \
17737 _(unset, "usage: unset <variable-name>")
17738
17739 #define _(N,n)                                  \
17740     static void vl_api_##n##_t_handler_uni      \
17741     (vl_api_##n##_t * mp)                       \
17742     {                                           \
17743         vat_main_t * vam = &vat_main;           \
17744         if (vam->json_output) {                 \
17745             vl_api_##n##_t_handler_json(mp);    \
17746         } else {                                \
17747             vl_api_##n##_t_handler(mp);         \
17748         }                                       \
17749     }
17750 foreach_vpe_api_reply_msg;
17751 #undef _
17752
17753 void
17754 vat_api_hookup (vat_main_t * vam)
17755 {
17756 #define _(N,n)                                                  \
17757     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17758                            vl_api_##n##_t_handler_uni,          \
17759                            vl_noop_handler,                     \
17760                            vl_api_##n##_t_endian,               \
17761                            vl_api_##n##_t_print,                \
17762                            sizeof(vl_api_##n##_t), 1);
17763   foreach_vpe_api_reply_msg;
17764 #undef _
17765
17766   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17767
17768   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17769
17770   vam->function_by_name = hash_create_string (0, sizeof (uword));
17771
17772   vam->help_by_name = hash_create_string (0, sizeof (uword));
17773
17774   /* API messages we can send */
17775 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17776   foreach_vpe_api_msg;
17777 #undef _
17778
17779   /* Help strings */
17780 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17781   foreach_vpe_api_msg;
17782 #undef _
17783
17784   /* CLI functions */
17785 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17786   foreach_cli_function;
17787 #undef _
17788
17789   /* Help strings */
17790 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17791   foreach_cli_function;
17792 #undef _
17793 }
17794
17795 /*
17796  * fd.io coding-style-patch-verification: ON
17797  *
17798  * Local Variables:
17799  * eval: (c-set-style "gnu")
17800  * End:
17801  */