Move iOAM Trace as a plugin
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014 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/mpls-gre/mpls.h>
39 #if DPDK > 0
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #else
43 #include <inttypes.h>
44 #endif
45 #include <vnet/map/map.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52
53 #include "vat/json_format.h"
54
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 #if DPDK > 0
249   u32 *r = va_arg (*args, u32 *);
250
251   if (0);
252 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
253   foreach_ipsec_policy_action
254 #undef _
255     else
256     return 0;
257   return 1;
258 #else
259   return 0;
260 #endif
261 }
262
263 uword
264 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
265 {
266 #if DPDK > 0
267   u32 *r = va_arg (*args, u32 *);
268
269   if (0);
270 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
271   foreach_ipsec_crypto_alg
272 #undef _
273     else
274     return 0;
275   return 1;
276 #else
277   return 0;
278 #endif
279 }
280
281 u8 *
282 format_ipsec_crypto_alg (u8 * s, va_list * args)
283 {
284 #if DPDK > 0
285   u32 i = va_arg (*args, u32);
286   u8 *t = 0;
287
288   switch (i)
289     {
290 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
291       foreach_ipsec_crypto_alg
292 #undef _
293     default:
294       return format (s, "unknown");
295     }
296   return format (s, "%s", t);
297 #else
298   return format (s, "Unimplemented");
299 #endif
300 }
301
302 uword
303 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
304 {
305 #if DPDK > 0
306   u32 *r = va_arg (*args, u32 *);
307
308   if (0);
309 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
310   foreach_ipsec_integ_alg
311 #undef _
312     else
313     return 0;
314   return 1;
315 #else
316   return 0;
317 #endif
318 }
319
320 u8 *
321 format_ipsec_integ_alg (u8 * s, va_list * args)
322 {
323 #if DPDK > 0
324   u32 i = va_arg (*args, u32);
325   u8 *t = 0;
326
327   switch (i)
328     {
329 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
330       foreach_ipsec_integ_alg
331 #undef _
332     default:
333       return format (s, "unknown");
334     }
335   return format (s, "%s", t);
336 #else
337   return format (s, "Unsupported");
338 #endif
339 }
340
341 uword
342 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
343 {
344 #if DPDK > 0
345   u32 *r = va_arg (*args, u32 *);
346
347   if (0);
348 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
349   foreach_ikev2_auth_method
350 #undef _
351     else
352     return 0;
353   return 1;
354 #else
355   return 0;
356 #endif
357 }
358
359 uword
360 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
361 {
362 #if DPDK > 0
363   u32 *r = va_arg (*args, u32 *);
364
365   if (0);
366 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
367   foreach_ikev2_id_type
368 #undef _
369     else
370     return 0;
371   return 1;
372 #else
373   return 0;
374 #endif
375 }
376
377 uword
378 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
379 {
380   u8 *r = va_arg (*args, u8 *);
381
382   if (unformat (input, "kbps"))
383     *r = SSE2_QOS_RATE_KBPS;
384   else if (unformat (input, "pps"))
385     *r = SSE2_QOS_RATE_PPS;
386   else
387     return 0;
388   return 1;
389 }
390
391 uword
392 unformat_policer_round_type (unformat_input_t * input, va_list * args)
393 {
394   u8 *r = va_arg (*args, u8 *);
395
396   if (unformat (input, "closest"))
397     *r = SSE2_QOS_ROUND_TO_CLOSEST;
398   else if (unformat (input, "up"))
399     *r = SSE2_QOS_ROUND_TO_UP;
400   else if (unformat (input, "down"))
401     *r = SSE2_QOS_ROUND_TO_DOWN;
402   else
403     return 0;
404   return 1;
405 }
406
407 uword
408 unformat_policer_type (unformat_input_t * input, va_list * args)
409 {
410   u8 *r = va_arg (*args, u8 *);
411
412   if (unformat (input, "1r2c"))
413     *r = SSE2_QOS_POLICER_TYPE_1R2C;
414   else if (unformat (input, "1r3c"))
415     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
416   else if (unformat (input, "2r3c-2698"))
417     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
418   else if (unformat (input, "2r3c-4115"))
419     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
420   else if (unformat (input, "2r3c-mef5cf1"))
421     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
422   else
423     return 0;
424   return 1;
425 }
426
427 uword
428 unformat_dscp (unformat_input_t * input, va_list * va)
429 {
430   u8 *r = va_arg (*va, u8 *);
431
432   if (0);
433 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
434   foreach_vnet_dscp
435 #undef _
436     else
437     return 0;
438   return 1;
439 }
440
441 uword
442 unformat_policer_action_type (unformat_input_t * input, va_list * va)
443 {
444   sse2_qos_pol_action_params_st *a
445     = va_arg (*va, sse2_qos_pol_action_params_st *);
446
447   if (unformat (input, "drop"))
448     a->action_type = SSE2_QOS_ACTION_DROP;
449   else if (unformat (input, "transmit"))
450     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
451   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
452     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
453   else
454     return 0;
455   return 1;
456 }
457
458 uword
459 unformat_classify_table_type (unformat_input_t * input, va_list * va)
460 {
461   u32 *r = va_arg (*va, u32 *);
462   u32 tid;
463
464   if (unformat (input, "ip4"))
465     tid = POLICER_CLASSIFY_TABLE_IP4;
466   else if (unformat (input, "ip6"))
467     tid = POLICER_CLASSIFY_TABLE_IP6;
468   else if (unformat (input, "l2"))
469     tid = POLICER_CLASSIFY_TABLE_L2;
470   else
471     return 0;
472
473   *r = tid;
474   return 1;
475 }
476
477 u8 *
478 format_ip4_address (u8 * s, va_list * args)
479 {
480   u8 *a = va_arg (*args, u8 *);
481   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
482 }
483
484 u8 *
485 format_ip6_address (u8 * s, va_list * args)
486 {
487   ip6_address_t *a = va_arg (*args, ip6_address_t *);
488   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
489
490   i_max_n_zero = ARRAY_LEN (a->as_u16);
491   max_n_zeros = 0;
492   i_first_zero = i_max_n_zero;
493   n_zeros = 0;
494   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
495     {
496       u32 is_zero = a->as_u16[i] == 0;
497       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
498         {
499           i_first_zero = i;
500           n_zeros = 0;
501         }
502       n_zeros += is_zero;
503       if ((!is_zero && n_zeros > max_n_zeros)
504           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
505         {
506           i_max_n_zero = i_first_zero;
507           max_n_zeros = n_zeros;
508           i_first_zero = ARRAY_LEN (a->as_u16);
509           n_zeros = 0;
510         }
511     }
512
513   last_double_colon = 0;
514   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
515     {
516       if (i == i_max_n_zero && max_n_zeros > 1)
517         {
518           s = format (s, "::");
519           i += max_n_zeros - 1;
520           last_double_colon = 1;
521         }
522       else
523         {
524           s = format (s, "%s%x",
525                       (last_double_colon || i == 0) ? "" : ":",
526                       clib_net_to_host_u16 (a->as_u16[i]));
527           last_double_colon = 0;
528         }
529     }
530
531   return s;
532 }
533
534 /* Format an IP46 address. */
535 u8 *
536 format_ip46_address (u8 * s, va_list * args)
537 {
538   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
539   ip46_type_t type = va_arg (*args, ip46_type_t);
540   int is_ip4 = 1;
541
542   switch (type)
543     {
544     case IP46_TYPE_ANY:
545       is_ip4 = ip46_address_is_ip4 (ip46);
546       break;
547     case IP46_TYPE_IP4:
548       is_ip4 = 1;
549       break;
550     case IP46_TYPE_IP6:
551       is_ip4 = 0;
552       break;
553     }
554
555   return is_ip4 ?
556     format (s, "%U", format_ip4_address, &ip46->ip4) :
557     format (s, "%U", format_ip6_address, &ip46->ip6);
558 }
559
560 u8 *
561 format_ethernet_address (u8 * s, va_list * args)
562 {
563   u8 *a = va_arg (*args, u8 *);
564
565   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
566                  a[0], a[1], a[2], a[3], a[4], a[5]);
567 }
568
569 void
570 increment_v4_address (ip4_address_t * a)
571 {
572   u32 v;
573
574   v = ntohl (a->as_u32) + 1;
575   a->as_u32 = ntohl (v);
576 }
577
578 void
579 increment_v6_address (ip6_address_t * a)
580 {
581   u64 v0, v1;
582
583   v0 = clib_net_to_host_u64 (a->as_u64[0]);
584   v1 = clib_net_to_host_u64 (a->as_u64[1]);
585
586   v1 += 1;
587   if (v1 == 0)
588     v0 += 1;
589   a->as_u64[0] = clib_net_to_host_u64 (v0);
590   a->as_u64[1] = clib_net_to_host_u64 (v1);
591 }
592
593 void
594 increment_mac_address (u64 * mac)
595 {
596   u64 tmp = *mac;
597
598   tmp = clib_net_to_host_u64 (tmp);
599   tmp += 1 << 16;               /* skip unused (least significant) octets */
600   tmp = clib_host_to_net_u64 (tmp);
601   *mac = tmp;
602 }
603
604 static void vl_api_create_loopback_reply_t_handler
605   (vl_api_create_loopback_reply_t * mp)
606 {
607   vat_main_t *vam = &vat_main;
608   i32 retval = ntohl (mp->retval);
609
610   vam->retval = retval;
611   vam->regenerate_interface_table = 1;
612   vam->sw_if_index = ntohl (mp->sw_if_index);
613   vam->result_ready = 1;
614 }
615
616 static void vl_api_create_loopback_reply_t_handler_json
617   (vl_api_create_loopback_reply_t * mp)
618 {
619   vat_main_t *vam = &vat_main;
620   vat_json_node_t node;
621
622   vat_json_init_object (&node);
623   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
624   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
625
626   vat_json_print (vam->ofp, &node);
627   vat_json_free (&node);
628   vam->retval = ntohl (mp->retval);
629   vam->result_ready = 1;
630 }
631
632 static void vl_api_af_packet_create_reply_t_handler
633   (vl_api_af_packet_create_reply_t * mp)
634 {
635   vat_main_t *vam = &vat_main;
636   i32 retval = ntohl (mp->retval);
637
638   vam->retval = retval;
639   vam->regenerate_interface_table = 1;
640   vam->sw_if_index = ntohl (mp->sw_if_index);
641   vam->result_ready = 1;
642 }
643
644 static void vl_api_af_packet_create_reply_t_handler_json
645   (vl_api_af_packet_create_reply_t * mp)
646 {
647   vat_main_t *vam = &vat_main;
648   vat_json_node_t node;
649
650   vat_json_init_object (&node);
651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
652   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
653
654   vat_json_print (vam->ofp, &node);
655   vat_json_free (&node);
656
657   vam->retval = ntohl (mp->retval);
658   vam->result_ready = 1;
659 }
660
661 static void vl_api_create_vlan_subif_reply_t_handler
662   (vl_api_create_vlan_subif_reply_t * mp)
663 {
664   vat_main_t *vam = &vat_main;
665   i32 retval = ntohl (mp->retval);
666
667   vam->retval = retval;
668   vam->regenerate_interface_table = 1;
669   vam->sw_if_index = ntohl (mp->sw_if_index);
670   vam->result_ready = 1;
671 }
672
673 static void vl_api_create_vlan_subif_reply_t_handler_json
674   (vl_api_create_vlan_subif_reply_t * mp)
675 {
676   vat_main_t *vam = &vat_main;
677   vat_json_node_t node;
678
679   vat_json_init_object (&node);
680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
681   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
682
683   vat_json_print (vam->ofp, &node);
684   vat_json_free (&node);
685
686   vam->retval = ntohl (mp->retval);
687   vam->result_ready = 1;
688 }
689
690 static void vl_api_create_subif_reply_t_handler
691   (vl_api_create_subif_reply_t * mp)
692 {
693   vat_main_t *vam = &vat_main;
694   i32 retval = ntohl (mp->retval);
695
696   vam->retval = retval;
697   vam->regenerate_interface_table = 1;
698   vam->sw_if_index = ntohl (mp->sw_if_index);
699   vam->result_ready = 1;
700 }
701
702 static void vl_api_create_subif_reply_t_handler_json
703   (vl_api_create_subif_reply_t * mp)
704 {
705   vat_main_t *vam = &vat_main;
706   vat_json_node_t node;
707
708   vat_json_init_object (&node);
709   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
710   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
711
712   vat_json_print (vam->ofp, &node);
713   vat_json_free (&node);
714
715   vam->retval = ntohl (mp->retval);
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   i32 retval = ntohl (mp->retval);
724
725   vam->retval = retval;
726   vam->regenerate_interface_table = 1;
727   vam->result_ready = 1;
728 }
729
730 static void vl_api_interface_name_renumber_reply_t_handler_json
731   (vl_api_interface_name_renumber_reply_t * mp)
732 {
733   vat_main_t *vam = &vat_main;
734   vat_json_node_t node;
735
736   vat_json_init_object (&node);
737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
738
739   vat_json_print (vam->ofp, &node);
740   vat_json_free (&node);
741
742   vam->retval = ntohl (mp->retval);
743   vam->result_ready = 1;
744 }
745
746 /*
747  * Special-case: build the interface table, maintain
748  * the next loopback sw_if_index vbl.
749  */
750 static void vl_api_sw_interface_details_t_handler
751   (vl_api_sw_interface_details_t * mp)
752 {
753   vat_main_t *vam = &vat_main;
754   u8 *s = format (0, "%s%c", mp->interface_name, 0);
755
756   hash_set_mem (vam->sw_if_index_by_interface_name, s,
757                 ntohl (mp->sw_if_index));
758
759   /* In sub interface case, fill the sub interface table entry */
760   if (mp->sw_if_index != mp->sup_sw_if_index)
761     {
762       sw_interface_subif_t *sub = NULL;
763
764       vec_add2 (vam->sw_if_subif_table, sub, 1);
765
766       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
767       strncpy ((char *) sub->interface_name, (char *) s,
768                vec_len (sub->interface_name));
769       sub->sw_if_index = ntohl (mp->sw_if_index);
770       sub->sub_id = ntohl (mp->sub_id);
771
772       sub->sub_dot1ad = mp->sub_dot1ad;
773       sub->sub_number_of_tags = mp->sub_number_of_tags;
774       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
775       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
776       sub->sub_exact_match = mp->sub_exact_match;
777       sub->sub_default = mp->sub_default;
778       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
779       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
780
781       /* vlan tag rewrite */
782       sub->vtr_op = ntohl (mp->vtr_op);
783       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
784       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
785       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
786     }
787 }
788
789 static void vl_api_sw_interface_details_t_handler_json
790   (vl_api_sw_interface_details_t * mp)
791 {
792   vat_main_t *vam = &vat_main;
793   vat_json_node_t *node = NULL;
794
795   if (VAT_JSON_ARRAY != vam->json_tree.type)
796     {
797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
798       vat_json_init_array (&vam->json_tree);
799     }
800   node = vat_json_array_add (&vam->json_tree);
801
802   vat_json_init_object (node);
803   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
804   vat_json_object_add_uint (node, "sup_sw_if_index",
805                             ntohl (mp->sup_sw_if_index));
806   vat_json_object_add_uint (node, "l2_address_length",
807                             ntohl (mp->l2_address_length));
808   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
809                              sizeof (mp->l2_address));
810   vat_json_object_add_string_copy (node, "interface_name",
811                                    mp->interface_name);
812   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
813   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
814   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
815   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
816   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
817   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
818   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
819   vat_json_object_add_uint (node, "sub_number_of_tags",
820                             mp->sub_number_of_tags);
821   vat_json_object_add_uint (node, "sub_outer_vlan_id",
822                             ntohs (mp->sub_outer_vlan_id));
823   vat_json_object_add_uint (node, "sub_inner_vlan_id",
824                             ntohs (mp->sub_inner_vlan_id));
825   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
826   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
827   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
828                             mp->sub_outer_vlan_id_any);
829   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
830                             mp->sub_inner_vlan_id_any);
831   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
832   vat_json_object_add_uint (node, "vtr_push_dot1q",
833                             ntohl (mp->vtr_push_dot1q));
834   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
835   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   vat_main_t *vam = &vat_main;
842   if (vam->interface_event_display)
843     errmsg ("interface flags: sw_if_index %d %s %s\n",
844             ntohl (mp->sw_if_index),
845             mp->admin_up_down ? "admin-up" : "admin-down",
846             mp->link_up_down ? "link-up" : "link-down");
847 }
848
849 static void vl_api_sw_interface_set_flags_t_handler_json
850   (vl_api_sw_interface_set_flags_t * mp)
851 {
852   /* JSON output not supported */
853 }
854
855 static void
856 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->shmem_result = (u8 *) mp->reply_in_shmem;
863   vam->result_ready = 1;
864 }
865
866 static void
867 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
868 {
869   vat_main_t *vam = &vat_main;
870   vat_json_node_t node;
871   api_main_t *am = &api_main;
872   void *oldheap;
873   u8 *reply;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "reply_in_shmem",
878                             ntohl (mp->reply_in_shmem));
879   /* Toss the shared-memory original... */
880   pthread_mutex_lock (&am->vlib_rp->mutex);
881   oldheap = svm_push_data_heap (am->vlib_rp);
882
883   reply = (u8 *) (mp->reply_in_shmem);
884   vec_free (reply);
885
886   svm_pop_heap (oldheap);
887   pthread_mutex_unlock (&am->vlib_rp->mutex);
888
889   vat_json_print (vam->ofp, &node);
890   vat_json_free (&node);
891
892   vam->retval = ntohl (mp->retval);
893   vam->result_ready = 1;
894 }
895
896 static void
897 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   i32 retval = ntohl (mp->retval);
901
902   vam->retval = retval;
903   vam->cmd_reply = mp->reply;
904   vam->result_ready = 1;
905 }
906
907 static void
908 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
909 {
910   vat_main_t *vam = &vat_main;
911   vat_json_node_t node;
912
913   vat_json_init_object (&node);
914   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
915   vat_json_object_add_string_copy (&node, "reply", mp->reply);
916
917   vat_json_print (vam->ofp, &node);
918   vat_json_free (&node);
919
920   vam->retval = ntohl (mp->retval);
921   vam->result_ready = 1;
922 }
923
924 static void vl_api_classify_add_del_table_reply_t_handler
925   (vl_api_classify_add_del_table_reply_t * mp)
926 {
927   vat_main_t *vam = &vat_main;
928   i32 retval = ntohl (mp->retval);
929   if (vam->async_mode)
930     {
931       vam->async_errors += (retval < 0);
932     }
933   else
934     {
935       vam->retval = retval;
936       if (retval == 0 &&
937           ((mp->new_table_index != 0xFFFFFFFF) ||
938            (mp->skip_n_vectors != 0xFFFFFFFF) ||
939            (mp->match_n_vectors != 0xFFFFFFFF)))
940         /*
941          * Note: this is just barely thread-safe, depends on
942          * the main thread spinning waiting for an answer...
943          */
944         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
945                 ntohl (mp->new_table_index),
946                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
947       vam->result_ready = 1;
948     }
949 }
950
951 static void vl_api_classify_add_del_table_reply_t_handler_json
952   (vl_api_classify_add_del_table_reply_t * mp)
953 {
954   vat_main_t *vam = &vat_main;
955   vat_json_node_t node;
956
957   vat_json_init_object (&node);
958   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
959   vat_json_object_add_uint (&node, "new_table_index",
960                             ntohl (mp->new_table_index));
961   vat_json_object_add_uint (&node, "skip_n_vectors",
962                             ntohl (mp->skip_n_vectors));
963   vat_json_object_add_uint (&node, "match_n_vectors",
964                             ntohl (mp->match_n_vectors));
965
966   vat_json_print (vam->ofp, &node);
967   vat_json_free (&node);
968
969   vam->retval = ntohl (mp->retval);
970   vam->result_ready = 1;
971 }
972
973 static void vl_api_get_node_index_reply_t_handler
974   (vl_api_get_node_index_reply_t * mp)
975 {
976   vat_main_t *vam = &vat_main;
977   i32 retval = ntohl (mp->retval);
978   if (vam->async_mode)
979     {
980       vam->async_errors += (retval < 0);
981     }
982   else
983     {
984       vam->retval = retval;
985       if (retval == 0)
986         errmsg ("node index %d\n", ntohl (mp->node_index));
987       vam->result_ready = 1;
988     }
989 }
990
991 static void vl_api_get_node_index_reply_t_handler_json
992   (vl_api_get_node_index_reply_t * mp)
993 {
994   vat_main_t *vam = &vat_main;
995   vat_json_node_t node;
996
997   vat_json_init_object (&node);
998   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
999   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1000
1001   vat_json_print (vam->ofp, &node);
1002   vat_json_free (&node);
1003
1004   vam->retval = ntohl (mp->retval);
1005   vam->result_ready = 1;
1006 }
1007
1008 static void vl_api_get_next_index_reply_t_handler
1009   (vl_api_get_next_index_reply_t * mp)
1010 {
1011   vat_main_t *vam = &vat_main;
1012   i32 retval = ntohl (mp->retval);
1013   if (vam->async_mode)
1014     {
1015       vam->async_errors += (retval < 0);
1016     }
1017   else
1018     {
1019       vam->retval = retval;
1020       if (retval == 0)
1021         errmsg ("next node index %d\n", ntohl (mp->next_index));
1022       vam->result_ready = 1;
1023     }
1024 }
1025
1026 static void vl_api_get_next_index_reply_t_handler_json
1027   (vl_api_get_next_index_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   vat_json_node_t node;
1031
1032   vat_json_init_object (&node);
1033   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1034   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1035
1036   vat_json_print (vam->ofp, &node);
1037   vat_json_free (&node);
1038
1039   vam->retval = ntohl (mp->retval);
1040   vam->result_ready = 1;
1041 }
1042
1043 static void vl_api_add_node_next_reply_t_handler
1044   (vl_api_add_node_next_reply_t * mp)
1045 {
1046   vat_main_t *vam = &vat_main;
1047   i32 retval = ntohl (mp->retval);
1048   if (vam->async_mode)
1049     {
1050       vam->async_errors += (retval < 0);
1051     }
1052   else
1053     {
1054       vam->retval = retval;
1055       if (retval == 0)
1056         errmsg ("next index %d\n", ntohl (mp->next_index));
1057       vam->result_ready = 1;
1058     }
1059 }
1060
1061 static void vl_api_add_node_next_reply_t_handler_json
1062   (vl_api_add_node_next_reply_t * mp)
1063 {
1064   vat_main_t *vam = &vat_main;
1065   vat_json_node_t node;
1066
1067   vat_json_init_object (&node);
1068   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1069   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1070
1071   vat_json_print (vam->ofp, &node);
1072   vat_json_free (&node);
1073
1074   vam->retval = ntohl (mp->retval);
1075   vam->result_ready = 1;
1076 }
1077
1078 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
1079   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1080 {
1081   vat_main_t *vam = &vat_main;
1082   i32 retval = ntohl (mp->retval);
1083   u32 sw_if_index = ntohl (mp->tunnel_sw_if_index);
1084
1085   if (retval >= 0 && sw_if_index != (u32) ~ 0)
1086     {
1087       errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1088     }
1089   vam->retval = retval;
1090   vam->result_ready = 1;
1091 }
1092
1093 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1094   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1095 {
1096   vat_main_t *vam = &vat_main;
1097   vat_json_node_t node;
1098
1099   vat_json_init_object (&node);
1100   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1101   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1102                             ntohl (mp->tunnel_sw_if_index));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111
1112 static void vl_api_show_version_reply_t_handler
1113   (vl_api_show_version_reply_t * mp)
1114 {
1115   vat_main_t *vam = &vat_main;
1116   i32 retval = ntohl (mp->retval);
1117
1118   if (retval >= 0)
1119     {
1120       errmsg ("        program: %s\n", mp->program);
1121       errmsg ("        version: %s\n", mp->version);
1122       errmsg ("     build date: %s\n", mp->build_date);
1123       errmsg ("build directory: %s\n", mp->build_directory);
1124     }
1125   vam->retval = retval;
1126   vam->result_ready = 1;
1127 }
1128
1129 static void vl_api_show_version_reply_t_handler_json
1130   (vl_api_show_version_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_string_copy (&node, "program", mp->program);
1138   vat_json_object_add_string_copy (&node, "version", mp->version);
1139   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1140   vat_json_object_add_string_copy (&node, "build_directory",
1141                                    mp->build_directory);
1142
1143   vat_json_print (vam->ofp, &node);
1144   vat_json_free (&node);
1145
1146   vam->retval = ntohl (mp->retval);
1147   vam->result_ready = 1;
1148 }
1149
1150 static void
1151 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1152 {
1153   vat_main_t *vam = &vat_main;
1154   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1155           mp->mac_ip ? "mac/ip binding" : "address resolution",
1156           format_ip4_address, &mp->address,
1157           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1158 }
1159
1160 static void
1161 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1162 {
1163   /* JSON output not supported */
1164 }
1165
1166 static void
1167 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1168 {
1169   vat_main_t *vam = &vat_main;
1170   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1171           mp->mac_ip ? "mac/ip binding" : "address resolution",
1172           format_ip6_address, mp->address,
1173           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1174 }
1175
1176 static void
1177 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1178 {
1179   /* JSON output not supported */
1180 }
1181
1182 /*
1183  * Special-case: build the bridge domain table, maintain
1184  * the next bd id vbl.
1185  */
1186 static void vl_api_bridge_domain_details_t_handler
1187   (vl_api_bridge_domain_details_t * mp)
1188 {
1189   vat_main_t *vam = &vat_main;
1190   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1191
1192   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1193            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1194
1195   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1196            ntohl (mp->bd_id), mp->learn, mp->forward,
1197            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1198
1199   if (n_sw_ifs)
1200     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1201              "Interface Name");
1202 }
1203
1204 static void vl_api_bridge_domain_details_t_handler_json
1205   (vl_api_bridge_domain_details_t * mp)
1206 {
1207   vat_main_t *vam = &vat_main;
1208   vat_json_node_t *node, *array = NULL;
1209
1210   if (VAT_JSON_ARRAY != vam->json_tree.type)
1211     {
1212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1213       vat_json_init_array (&vam->json_tree);
1214     }
1215   node = vat_json_array_add (&vam->json_tree);
1216
1217   vat_json_init_object (node);
1218   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1219   vat_json_object_add_uint (node, "flood", mp->flood);
1220   vat_json_object_add_uint (node, "forward", mp->forward);
1221   vat_json_object_add_uint (node, "learn", mp->learn);
1222   vat_json_object_add_uint (node, "bvi_sw_if_index",
1223                             ntohl (mp->bvi_sw_if_index));
1224   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1225   array = vat_json_object_add (node, "sw_if");
1226   vat_json_init_array (array);
1227 }
1228
1229 /*
1230  * Special-case: build the bridge domain sw if table.
1231  */
1232 static void vl_api_bridge_domain_sw_if_details_t_handler
1233   (vl_api_bridge_domain_sw_if_details_t * mp)
1234 {
1235   vat_main_t *vam = &vat_main;
1236   hash_pair_t *p;
1237   u8 *sw_if_name = 0;
1238   u32 sw_if_index;
1239
1240   sw_if_index = ntohl (mp->sw_if_index);
1241   /* *INDENT-OFF* */
1242   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1243   ({
1244     if ((u32) p->value[0] == sw_if_index)
1245       {
1246         sw_if_name = (u8 *)(p->key);
1247         break;
1248       }
1249   }));
1250   /* *INDENT-ON* */
1251
1252   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1253            mp->shg, sw_if_name ? (char *) sw_if_name :
1254            "sw_if_index not found!");
1255 }
1256
1257 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1258   (vl_api_bridge_domain_sw_if_details_t * mp)
1259 {
1260   vat_main_t *vam = &vat_main;
1261   vat_json_node_t *node = NULL;
1262   uword last_index = 0;
1263
1264   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1265   ASSERT (vec_len (vam->json_tree.array) >= 1);
1266   last_index = vec_len (vam->json_tree.array) - 1;
1267   node = &vam->json_tree.array[last_index];
1268   node = vat_json_object_get_element (node, "sw_if");
1269   ASSERT (NULL != node);
1270   node = vat_json_array_add (node);
1271
1272   vat_json_init_object (node);
1273   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1274   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1275   vat_json_object_add_uint (node, "shg", mp->shg);
1276 }
1277
1278 static void vl_api_control_ping_reply_t_handler
1279   (vl_api_control_ping_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   i32 retval = ntohl (mp->retval);
1283   if (vam->async_mode)
1284     {
1285       vam->async_errors += (retval < 0);
1286     }
1287   else
1288     {
1289       vam->retval = retval;
1290       vam->result_ready = 1;
1291     }
1292 }
1293
1294 static void vl_api_control_ping_reply_t_handler_json
1295   (vl_api_control_ping_reply_t * mp)
1296 {
1297   vat_main_t *vam = &vat_main;
1298   i32 retval = ntohl (mp->retval);
1299
1300   if (VAT_JSON_NONE != vam->json_tree.type)
1301     {
1302       vat_json_print (vam->ofp, &vam->json_tree);
1303       vat_json_free (&vam->json_tree);
1304       vam->json_tree.type = VAT_JSON_NONE;
1305     }
1306   else
1307     {
1308       /* just print [] */
1309       vat_json_init_array (&vam->json_tree);
1310       vat_json_print (vam->ofp, &vam->json_tree);
1311       vam->json_tree.type = VAT_JSON_NONE;
1312     }
1313
1314   vam->retval = retval;
1315   vam->result_ready = 1;
1316 }
1317
1318 static void vl_api_noprint_control_ping_reply_t_handler
1319   (vl_api_noprint_control_ping_reply_t * mp)
1320 {
1321   vat_main_t *vam = &vat_main;
1322   i32 retval = ntohl (mp->retval);
1323   if (vam->async_mode)
1324     {
1325       vam->async_errors += (retval < 0);
1326     }
1327   else
1328     {
1329       vam->retval = retval;
1330       vam->result_ready = 1;
1331     }
1332 }
1333
1334 static void vl_api_noprint_control_ping_reply_t_handler_json
1335   (vl_api_noprint_control_ping_reply_t * mp)
1336 {
1337   vat_main_t *vam = &vat_main;
1338   i32 retval = ntohl (mp->retval);
1339
1340   if (vam->noprint_msg)
1341     {
1342       vam->retval = retval;
1343       vam->result_ready = 1;
1344       return;
1345     }
1346
1347   if (VAT_JSON_NONE != vam->json_tree.type)
1348     {
1349       vat_json_print (vam->ofp, &vam->json_tree);
1350       vat_json_free (&vam->json_tree);
1351       vam->json_tree.type = VAT_JSON_NONE;
1352     }
1353   else
1354     {
1355       /* just print [] */
1356       vat_json_init_array (&vam->json_tree);
1357       vat_json_print (vam->ofp, &vam->json_tree);
1358       vam->json_tree.type = VAT_JSON_NONE;
1359     }
1360
1361   vam->retval = retval;
1362   vam->result_ready = 1;
1363 }
1364
1365 static void
1366 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1367 {
1368   vat_main_t *vam = &vat_main;
1369   i32 retval = ntohl (mp->retval);
1370   if (vam->async_mode)
1371     {
1372       vam->async_errors += (retval < 0);
1373     }
1374   else
1375     {
1376       vam->retval = retval;
1377       vam->result_ready = 1;
1378     }
1379 }
1380
1381 static void vl_api_l2_flags_reply_t_handler_json
1382   (vl_api_l2_flags_reply_t * mp)
1383 {
1384   vat_main_t *vam = &vat_main;
1385   vat_json_node_t node;
1386
1387   vat_json_init_object (&node);
1388   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1389   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1390                             ntohl (mp->resulting_feature_bitmap));
1391
1392   vat_json_print (vam->ofp, &node);
1393   vat_json_free (&node);
1394
1395   vam->retval = ntohl (mp->retval);
1396   vam->result_ready = 1;
1397 }
1398
1399 static void vl_api_bridge_flags_reply_t_handler
1400   (vl_api_bridge_flags_reply_t * mp)
1401 {
1402   vat_main_t *vam = &vat_main;
1403   i32 retval = ntohl (mp->retval);
1404   if (vam->async_mode)
1405     {
1406       vam->async_errors += (retval < 0);
1407     }
1408   else
1409     {
1410       vam->retval = retval;
1411       vam->result_ready = 1;
1412     }
1413 }
1414
1415 static void vl_api_bridge_flags_reply_t_handler_json
1416   (vl_api_bridge_flags_reply_t * mp)
1417 {
1418   vat_main_t *vam = &vat_main;
1419   vat_json_node_t node;
1420
1421   vat_json_init_object (&node);
1422   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1423   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1424                             ntohl (mp->resulting_feature_bitmap));
1425
1426   vat_json_print (vam->ofp, &node);
1427   vat_json_free (&node);
1428
1429   vam->retval = ntohl (mp->retval);
1430   vam->result_ready = 1;
1431 }
1432
1433 static void vl_api_tap_connect_reply_t_handler
1434   (vl_api_tap_connect_reply_t * mp)
1435 {
1436   vat_main_t *vam = &vat_main;
1437   i32 retval = ntohl (mp->retval);
1438   if (vam->async_mode)
1439     {
1440       vam->async_errors += (retval < 0);
1441     }
1442   else
1443     {
1444       vam->retval = retval;
1445       vam->sw_if_index = ntohl (mp->sw_if_index);
1446       vam->result_ready = 1;
1447     }
1448
1449 }
1450
1451 static void vl_api_tap_connect_reply_t_handler_json
1452   (vl_api_tap_connect_reply_t * mp)
1453 {
1454   vat_main_t *vam = &vat_main;
1455   vat_json_node_t node;
1456
1457   vat_json_init_object (&node);
1458   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1459   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1460
1461   vat_json_print (vam->ofp, &node);
1462   vat_json_free (&node);
1463
1464   vam->retval = ntohl (mp->retval);
1465   vam->result_ready = 1;
1466
1467 }
1468
1469 static void
1470 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1471 {
1472   vat_main_t *vam = &vat_main;
1473   i32 retval = ntohl (mp->retval);
1474   if (vam->async_mode)
1475     {
1476       vam->async_errors += (retval < 0);
1477     }
1478   else
1479     {
1480       vam->retval = retval;
1481       vam->sw_if_index = ntohl (mp->sw_if_index);
1482       vam->result_ready = 1;
1483     }
1484 }
1485
1486 static void vl_api_tap_modify_reply_t_handler_json
1487   (vl_api_tap_modify_reply_t * mp)
1488 {
1489   vat_main_t *vam = &vat_main;
1490   vat_json_node_t node;
1491
1492   vat_json_init_object (&node);
1493   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1494   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1495
1496   vat_json_print (vam->ofp, &node);
1497   vat_json_free (&node);
1498
1499   vam->retval = ntohl (mp->retval);
1500   vam->result_ready = 1;
1501 }
1502
1503 static void
1504 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1505 {
1506   vat_main_t *vam = &vat_main;
1507   i32 retval = ntohl (mp->retval);
1508   if (vam->async_mode)
1509     {
1510       vam->async_errors += (retval < 0);
1511     }
1512   else
1513     {
1514       vam->retval = retval;
1515       vam->result_ready = 1;
1516     }
1517 }
1518
1519 static void vl_api_tap_delete_reply_t_handler_json
1520   (vl_api_tap_delete_reply_t * mp)
1521 {
1522   vat_main_t *vam = &vat_main;
1523   vat_json_node_t node;
1524
1525   vat_json_init_object (&node);
1526   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1527
1528   vat_json_print (vam->ofp, &node);
1529   vat_json_free (&node);
1530
1531   vam->retval = ntohl (mp->retval);
1532   vam->result_ready = 1;
1533 }
1534
1535 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1536   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1537 {
1538   vat_main_t *vam = &vat_main;
1539   i32 retval = ntohl (mp->retval);
1540   if (vam->async_mode)
1541     {
1542       vam->async_errors += (retval < 0);
1543     }
1544   else
1545     {
1546       vam->retval = retval;
1547       vam->result_ready = 1;
1548     }
1549 }
1550
1551 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1552   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1553 {
1554   vat_main_t *vam = &vat_main;
1555   vat_json_node_t node;
1556
1557   vat_json_init_object (&node);
1558   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1559   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1560                             ntohl (mp->tunnel_sw_if_index));
1561
1562   vat_json_print (vam->ofp, &node);
1563   vat_json_free (&node);
1564
1565   vam->retval = ntohl (mp->retval);
1566   vam->result_ready = 1;
1567 }
1568
1569 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1570   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1571 {
1572   vat_main_t *vam = &vat_main;
1573   i32 retval = ntohl (mp->retval);
1574   if (vam->async_mode)
1575     {
1576       vam->async_errors += (retval < 0);
1577     }
1578   else
1579     {
1580       vam->retval = retval;
1581       vam->sw_if_index = ntohl (mp->sw_if_index);
1582       vam->result_ready = 1;
1583     }
1584 }
1585
1586 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1587   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1588 {
1589   vat_main_t *vam = &vat_main;
1590   vat_json_node_t node;
1591
1592   vat_json_init_object (&node);
1593   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1594   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1595
1596   vat_json_print (vam->ofp, &node);
1597   vat_json_free (&node);
1598
1599   vam->retval = ntohl (mp->retval);
1600   vam->result_ready = 1;
1601 }
1602
1603
1604 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1605   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1606 {
1607   vat_main_t *vam = &vat_main;
1608   i32 retval = ntohl (mp->retval);
1609   if (vam->async_mode)
1610     {
1611       vam->async_errors += (retval < 0);
1612     }
1613   else
1614     {
1615       vam->retval = retval;
1616       vam->result_ready = 1;
1617     }
1618 }
1619
1620 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1621   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1622 {
1623   vat_main_t *vam = &vat_main;
1624   vat_json_node_t node;
1625
1626   vat_json_init_object (&node);
1627   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1628   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1629
1630   vat_json_print (vam->ofp, &node);
1631   vat_json_free (&node);
1632
1633   vam->retval = ntohl (mp->retval);
1634   vam->result_ready = 1;
1635 }
1636
1637 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1638   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1639 {
1640   vat_main_t *vam = &vat_main;
1641   i32 retval = ntohl (mp->retval);
1642   if (vam->async_mode)
1643     {
1644       vam->async_errors += (retval < 0);
1645     }
1646   else
1647     {
1648       vam->retval = retval;
1649       vam->sw_if_index = ntohl (mp->sw_if_index);
1650       vam->result_ready = 1;
1651     }
1652 }
1653
1654 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1655   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1656 {
1657   vat_main_t *vam = &vat_main;
1658   vat_json_node_t node;
1659
1660   vat_json_init_object (&node);
1661   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1662   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1663
1664   vat_json_print (vam->ofp, &node);
1665   vat_json_free (&node);
1666
1667   vam->retval = ntohl (mp->retval);
1668   vam->result_ready = 1;
1669 }
1670
1671 static void vl_api_gre_add_del_tunnel_reply_t_handler
1672   (vl_api_gre_add_del_tunnel_reply_t * mp)
1673 {
1674   vat_main_t *vam = &vat_main;
1675   i32 retval = ntohl (mp->retval);
1676   if (vam->async_mode)
1677     {
1678       vam->async_errors += (retval < 0);
1679     }
1680   else
1681     {
1682       vam->retval = retval;
1683       vam->sw_if_index = ntohl (mp->sw_if_index);
1684       vam->result_ready = 1;
1685     }
1686 }
1687
1688 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1689   (vl_api_gre_add_del_tunnel_reply_t * mp)
1690 {
1691   vat_main_t *vam = &vat_main;
1692   vat_json_node_t node;
1693
1694   vat_json_init_object (&node);
1695   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1696   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1697
1698   vat_json_print (vam->ofp, &node);
1699   vat_json_free (&node);
1700
1701   vam->retval = ntohl (mp->retval);
1702   vam->result_ready = 1;
1703 }
1704
1705 static void vl_api_create_vhost_user_if_reply_t_handler
1706   (vl_api_create_vhost_user_if_reply_t * mp)
1707 {
1708   vat_main_t *vam = &vat_main;
1709   i32 retval = ntohl (mp->retval);
1710   if (vam->async_mode)
1711     {
1712       vam->async_errors += (retval < 0);
1713     }
1714   else
1715     {
1716       vam->retval = retval;
1717       vam->sw_if_index = ntohl (mp->sw_if_index);
1718       vam->result_ready = 1;
1719     }
1720 }
1721
1722 static void vl_api_create_vhost_user_if_reply_t_handler_json
1723   (vl_api_create_vhost_user_if_reply_t * mp)
1724 {
1725   vat_main_t *vam = &vat_main;
1726   vat_json_node_t node;
1727
1728   vat_json_init_object (&node);
1729   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1730   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1731
1732   vat_json_print (vam->ofp, &node);
1733   vat_json_free (&node);
1734
1735   vam->retval = ntohl (mp->retval);
1736   vam->result_ready = 1;
1737 }
1738
1739 static void vl_api_ip_address_details_t_handler
1740   (vl_api_ip_address_details_t * mp)
1741 {
1742   vat_main_t *vam = &vat_main;
1743   static ip_address_details_t empty_ip_address_details = { {0} };
1744   ip_address_details_t *address = NULL;
1745   ip_details_t *current_ip_details = NULL;
1746   ip_details_t *details = NULL;
1747
1748   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1749
1750   if (!details || vam->current_sw_if_index >= vec_len (details)
1751       || !details[vam->current_sw_if_index].present)
1752     {
1753       errmsg ("ip address details arrived but not stored\n");
1754       errmsg ("ip_dump should be called first\n");
1755       return;
1756     }
1757
1758   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1759
1760 #define addresses (current_ip_details->addr)
1761
1762   vec_validate_init_empty (addresses, vec_len (addresses),
1763                            empty_ip_address_details);
1764
1765   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1766
1767   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1768   address->prefix_length = mp->prefix_length;
1769 #undef addresses
1770 }
1771
1772 static void vl_api_ip_address_details_t_handler_json
1773   (vl_api_ip_address_details_t * mp)
1774 {
1775   vat_main_t *vam = &vat_main;
1776   vat_json_node_t *node = NULL;
1777   struct in6_addr ip6;
1778   struct in_addr ip4;
1779
1780   if (VAT_JSON_ARRAY != vam->json_tree.type)
1781     {
1782       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1783       vat_json_init_array (&vam->json_tree);
1784     }
1785   node = vat_json_array_add (&vam->json_tree);
1786
1787   vat_json_init_object (node);
1788   if (vam->is_ipv6)
1789     {
1790       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1791       vat_json_object_add_ip6 (node, "ip", ip6);
1792     }
1793   else
1794     {
1795       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1796       vat_json_object_add_ip4 (node, "ip", ip4);
1797     }
1798   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1799 }
1800
1801 static void
1802 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1803 {
1804   vat_main_t *vam = &vat_main;
1805   static ip_details_t empty_ip_details = { 0 };
1806   ip_details_t *ip = NULL;
1807   u32 sw_if_index = ~0;
1808
1809   sw_if_index = ntohl (mp->sw_if_index);
1810
1811   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1812                            sw_if_index, empty_ip_details);
1813
1814   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1815                          sw_if_index);
1816
1817   ip->present = 1;
1818 }
1819
1820 static void
1821 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1822 {
1823   vat_main_t *vam = &vat_main;
1824
1825   if (VAT_JSON_ARRAY != vam->json_tree.type)
1826     {
1827       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1828       vat_json_init_array (&vam->json_tree);
1829     }
1830   vat_json_array_add_uint (&vam->json_tree,
1831                            clib_net_to_host_u32 (mp->sw_if_index));
1832 }
1833
1834 static void vl_api_map_domain_details_t_handler_json
1835   (vl_api_map_domain_details_t * mp)
1836 {
1837   vat_json_node_t *node = NULL;
1838   vat_main_t *vam = &vat_main;
1839   struct in6_addr ip6;
1840   struct in_addr ip4;
1841
1842   if (VAT_JSON_ARRAY != vam->json_tree.type)
1843     {
1844       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1845       vat_json_init_array (&vam->json_tree);
1846     }
1847
1848   node = vat_json_array_add (&vam->json_tree);
1849   vat_json_init_object (node);
1850
1851   vat_json_object_add_uint (node, "domain_index",
1852                             clib_net_to_host_u32 (mp->domain_index));
1853   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1854   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1855   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1856   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1857   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1858   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1859   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1860   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1861   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1862   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1863   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1864   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1865   vat_json_object_add_uint (node, "flags", mp->flags);
1866   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1867   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1868 }
1869
1870 static void vl_api_map_domain_details_t_handler
1871   (vl_api_map_domain_details_t * mp)
1872 {
1873   vat_main_t *vam = &vat_main;
1874
1875   if (mp->is_translation)
1876     {
1877       fformat (vam->ofp,
1878                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1879                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1880                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1881                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1882                clib_net_to_host_u32 (mp->domain_index));
1883     }
1884   else
1885     {
1886       fformat (vam->ofp,
1887                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1888                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1889                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1890                format_ip6_address, mp->ip6_src,
1891                clib_net_to_host_u32 (mp->domain_index));
1892     }
1893   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1894            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1895            mp->is_translation ? "map-t" : "");
1896 }
1897
1898 static void vl_api_map_rule_details_t_handler_json
1899   (vl_api_map_rule_details_t * mp)
1900 {
1901   struct in6_addr ip6;
1902   vat_json_node_t *node = NULL;
1903   vat_main_t *vam = &vat_main;
1904
1905   if (VAT_JSON_ARRAY != vam->json_tree.type)
1906     {
1907       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1908       vat_json_init_array (&vam->json_tree);
1909     }
1910
1911   node = vat_json_array_add (&vam->json_tree);
1912   vat_json_init_object (node);
1913
1914   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1915   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1916   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1917 }
1918
1919 static void
1920 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1921 {
1922   vat_main_t *vam = &vat_main;
1923   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1924            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1925 }
1926
1927 static void
1928 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1929 {
1930   vat_main_t *vam = &vat_main;
1931   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1932           "router_addr %U host_mac %U\n",
1933           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1934           format_ip4_address, &mp->host_address,
1935           format_ip4_address, &mp->router_address,
1936           format_ethernet_address, mp->host_mac);
1937 }
1938
1939 static void vl_api_dhcp_compl_event_t_handler_json
1940   (vl_api_dhcp_compl_event_t * mp)
1941 {
1942   /* JSON output not supported */
1943 }
1944
1945 static void
1946 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1947                               u32 counter)
1948 {
1949   vat_main_t *vam = &vat_main;
1950   static u64 default_counter = 0;
1951
1952   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1953                            NULL);
1954   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1955                            sw_if_index, default_counter);
1956   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1957 }
1958
1959 static void
1960 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1961                                 interface_counter_t counter)
1962 {
1963   vat_main_t *vam = &vat_main;
1964   static interface_counter_t default_counter = { 0, };
1965
1966   vec_validate_init_empty (vam->combined_interface_counters,
1967                            vnet_counter_type, NULL);
1968   vec_validate_init_empty (vam->combined_interface_counters
1969                            [vnet_counter_type], sw_if_index, default_counter);
1970   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1971 }
1972
1973 static void vl_api_vnet_interface_counters_t_handler
1974   (vl_api_vnet_interface_counters_t * mp)
1975 {
1976   /* not supported */
1977 }
1978
1979 static void vl_api_vnet_interface_counters_t_handler_json
1980   (vl_api_vnet_interface_counters_t * mp)
1981 {
1982   interface_counter_t counter;
1983   vlib_counter_t *v;
1984   u64 *v_packets;
1985   u64 packets;
1986   u32 count;
1987   u32 first_sw_if_index;
1988   int i;
1989
1990   count = ntohl (mp->count);
1991   first_sw_if_index = ntohl (mp->first_sw_if_index);
1992
1993   if (!mp->is_combined)
1994     {
1995       v_packets = (u64 *) & mp->data;
1996       for (i = 0; i < count; i++)
1997         {
1998           packets =
1999             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2000           set_simple_interface_counter (mp->vnet_counter_type,
2001                                         first_sw_if_index + i, packets);
2002           v_packets++;
2003         }
2004     }
2005   else
2006     {
2007       v = (vlib_counter_t *) & mp->data;
2008       for (i = 0; i < count; i++)
2009         {
2010           counter.packets =
2011             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2012           counter.bytes =
2013             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2014           set_combined_interface_counter (mp->vnet_counter_type,
2015                                           first_sw_if_index + i, counter);
2016           v++;
2017         }
2018     }
2019 }
2020
2021 static u32
2022 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2023 {
2024   vat_main_t *vam = &vat_main;
2025   u32 i;
2026
2027   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2028     {
2029       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2030         {
2031           return i;
2032         }
2033     }
2034   return ~0;
2035 }
2036
2037 static u32
2038 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2039 {
2040   vat_main_t *vam = &vat_main;
2041   u32 i;
2042
2043   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2044     {
2045       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2046         {
2047           return i;
2048         }
2049     }
2050   return ~0;
2051 }
2052
2053 static void vl_api_vnet_ip4_fib_counters_t_handler
2054   (vl_api_vnet_ip4_fib_counters_t * mp)
2055 {
2056   /* not supported */
2057 }
2058
2059 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2060   (vl_api_vnet_ip4_fib_counters_t * mp)
2061 {
2062   vat_main_t *vam = &vat_main;
2063   vl_api_ip4_fib_counter_t *v;
2064   ip4_fib_counter_t *counter;
2065   struct in_addr ip4;
2066   u32 vrf_id;
2067   u32 vrf_index;
2068   u32 count;
2069   int i;
2070
2071   vrf_id = ntohl (mp->vrf_id);
2072   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2073   if (~0 == vrf_index)
2074     {
2075       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2076       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2077       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2078       vec_validate (vam->ip4_fib_counters, vrf_index);
2079       vam->ip4_fib_counters[vrf_index] = NULL;
2080     }
2081
2082   vec_free (vam->ip4_fib_counters[vrf_index]);
2083   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2084   count = ntohl (mp->count);
2085   for (i = 0; i < count; i++)
2086     {
2087       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2088       counter = &vam->ip4_fib_counters[vrf_index][i];
2089       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2090       counter->address = ip4;
2091       counter->address_length = v->address_length;
2092       counter->packets = clib_net_to_host_u64 (v->packets);
2093       counter->bytes = clib_net_to_host_u64 (v->bytes);
2094       v++;
2095     }
2096 }
2097
2098 static void vl_api_vnet_ip6_fib_counters_t_handler
2099   (vl_api_vnet_ip6_fib_counters_t * mp)
2100 {
2101   /* not supported */
2102 }
2103
2104 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2105   (vl_api_vnet_ip6_fib_counters_t * mp)
2106 {
2107   vat_main_t *vam = &vat_main;
2108   vl_api_ip6_fib_counter_t *v;
2109   ip6_fib_counter_t *counter;
2110   struct in6_addr ip6;
2111   u32 vrf_id;
2112   u32 vrf_index;
2113   u32 count;
2114   int i;
2115
2116   vrf_id = ntohl (mp->vrf_id);
2117   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2118   if (~0 == vrf_index)
2119     {
2120       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2121       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2122       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2123       vec_validate (vam->ip6_fib_counters, vrf_index);
2124       vam->ip6_fib_counters[vrf_index] = NULL;
2125     }
2126
2127   vec_free (vam->ip6_fib_counters[vrf_index]);
2128   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2129   count = ntohl (mp->count);
2130   for (i = 0; i < count; i++)
2131     {
2132       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2133       counter = &vam->ip6_fib_counters[vrf_index][i];
2134       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2135       counter->address = ip6;
2136       counter->address_length = v->address_length;
2137       counter->packets = clib_net_to_host_u64 (v->packets);
2138       counter->bytes = clib_net_to_host_u64 (v->bytes);
2139       v++;
2140     }
2141 }
2142
2143 static void vl_api_get_first_msg_id_reply_t_handler
2144   (vl_api_get_first_msg_id_reply_t * mp)
2145 {
2146   vat_main_t *vam = &vat_main;
2147   i32 retval = ntohl (mp->retval);
2148
2149   if (vam->async_mode)
2150     {
2151       vam->async_errors += (retval < 0);
2152     }
2153   else
2154     {
2155       vam->retval = retval;
2156       vam->result_ready = 1;
2157     }
2158   if (retval >= 0)
2159     {
2160       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2161     }
2162 }
2163
2164 static void vl_api_get_first_msg_id_reply_t_handler_json
2165   (vl_api_get_first_msg_id_reply_t * mp)
2166 {
2167   vat_main_t *vam = &vat_main;
2168   vat_json_node_t node;
2169
2170   vat_json_init_object (&node);
2171   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2172   vat_json_object_add_uint (&node, "first_msg_id",
2173                             (uint) ntohs (mp->first_msg_id));
2174
2175   vat_json_print (vam->ofp, &node);
2176   vat_json_free (&node);
2177
2178   vam->retval = ntohl (mp->retval);
2179   vam->result_ready = 1;
2180 }
2181
2182 static void vl_api_get_node_graph_reply_t_handler
2183   (vl_api_get_node_graph_reply_t * mp)
2184 {
2185   vat_main_t *vam = &vat_main;
2186   api_main_t *am = &api_main;
2187   i32 retval = ntohl (mp->retval);
2188   u8 *pvt_copy, *reply;
2189   void *oldheap;
2190   vlib_node_t *node;
2191   int i;
2192
2193   if (vam->async_mode)
2194     {
2195       vam->async_errors += (retval < 0);
2196     }
2197   else
2198     {
2199       vam->retval = retval;
2200       vam->result_ready = 1;
2201     }
2202
2203   /* "Should never happen..." */
2204   if (retval != 0)
2205     return;
2206
2207   reply = (u8 *) (mp->reply_in_shmem);
2208   pvt_copy = vec_dup (reply);
2209
2210   /* Toss the shared-memory original... */
2211   pthread_mutex_lock (&am->vlib_rp->mutex);
2212   oldheap = svm_push_data_heap (am->vlib_rp);
2213
2214   vec_free (reply);
2215
2216   svm_pop_heap (oldheap);
2217   pthread_mutex_unlock (&am->vlib_rp->mutex);
2218
2219   if (vam->graph_nodes)
2220     {
2221       hash_free (vam->graph_node_index_by_name);
2222
2223       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2224         {
2225           node = vam->graph_nodes[i];
2226           vec_free (node->name);
2227           vec_free (node->next_nodes);
2228           vec_free (node);
2229         }
2230       vec_free (vam->graph_nodes);
2231     }
2232
2233   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2234   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2235   vec_free (pvt_copy);
2236
2237   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2238     {
2239       node = vam->graph_nodes[i];
2240       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2241     }
2242 }
2243
2244 static void vl_api_get_node_graph_reply_t_handler_json
2245   (vl_api_get_node_graph_reply_t * mp)
2246 {
2247   vat_main_t *vam = &vat_main;
2248   api_main_t *am = &api_main;
2249   void *oldheap;
2250   vat_json_node_t node;
2251   u8 *reply;
2252
2253   /* $$$$ make this real? */
2254   vat_json_init_object (&node);
2255   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2256   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2257
2258   reply = (u8 *) (mp->reply_in_shmem);
2259
2260   /* Toss the shared-memory original... */
2261   pthread_mutex_lock (&am->vlib_rp->mutex);
2262   oldheap = svm_push_data_heap (am->vlib_rp);
2263
2264   vec_free (reply);
2265
2266   svm_pop_heap (oldheap);
2267   pthread_mutex_unlock (&am->vlib_rp->mutex);
2268
2269   vat_json_print (vam->ofp, &node);
2270   vat_json_free (&node);
2271
2272   vam->retval = ntohl (mp->retval);
2273   vam->result_ready = 1;
2274 }
2275
2276 static void
2277 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2278 {
2279   vat_main_t *vam = &vat_main;
2280   locator_msg_t loc;
2281   u8 *tmp_str = 0;
2282
2283   memset (&loc, 0, sizeof (loc));
2284   if (vam->noprint_msg)
2285     {
2286       loc.local = mp->local;
2287       loc.priority = mp->priority;
2288       loc.weight = mp->weight;
2289       if (loc.local)
2290         {
2291           loc.sw_if_index = ntohl (mp->sw_if_index);
2292         }
2293       else
2294         {
2295           loc.is_ipv6 = mp->is_ipv6;
2296           clib_memcpy (loc.ip_address, mp->ip_address,
2297                        sizeof (loc.ip_address));
2298         }
2299       vec_add1 (vam->locator_msg, loc);
2300     }
2301   else
2302     {
2303       if (mp->local)
2304         {
2305           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
2306                             ntohl (mp->sw_if_index),
2307                             mp->priority, mp->weight);
2308         }
2309       else
2310         {
2311           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
2312                             mp->is_ipv6 ? format_ip6_address :
2313                             format_ip4_address,
2314                             mp->ip_address, mp->priority, mp->weight);
2315         }
2316
2317       fformat (vam->ofp, "%s", tmp_str);
2318
2319       vec_free (tmp_str);
2320     }
2321 }
2322
2323 static void
2324 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2325                                             mp)
2326 {
2327   vat_main_t *vam = &vat_main;
2328   vat_json_node_t *node = NULL;
2329   locator_msg_t loc;
2330   struct in6_addr ip6;
2331   struct in_addr ip4;
2332
2333   memset (&loc, 0, sizeof (loc));
2334   if (vam->noprint_msg)
2335     {
2336       loc.local = mp->local;
2337       loc.priority = mp->priority;
2338       loc.weight = mp->weight;
2339       if (loc.local)
2340         {
2341           loc.sw_if_index = ntohl (mp->sw_if_index);
2342         }
2343       else
2344         {
2345           loc.is_ipv6 = mp->is_ipv6;
2346           clib_memcpy (loc.ip_address, mp->ip_address,
2347                        sizeof (loc.ip_address));
2348         }
2349       vec_add1 (vam->locator_msg, loc);
2350       return;
2351     }
2352
2353   if (VAT_JSON_ARRAY != vam->json_tree.type)
2354     {
2355       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2356       vat_json_init_array (&vam->json_tree);
2357     }
2358   node = vat_json_array_add (&vam->json_tree);
2359
2360   vat_json_init_object (node);
2361
2362   if (mp->local)
2363     {
2364       vat_json_object_add_uint (node, "locator_index",
2365                                 ntohl (mp->sw_if_index));
2366     }
2367   else
2368     {
2369       if (mp->is_ipv6)
2370         {
2371           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2372           vat_json_object_add_ip6 (node, "locator", ip6);
2373         }
2374       else
2375         {
2376           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2377           vat_json_object_add_ip4 (node, "locator", ip4);
2378         }
2379     }
2380   vat_json_object_add_uint (node, "priority", mp->priority);
2381   vat_json_object_add_uint (node, "weight", mp->weight);
2382 }
2383
2384 static void
2385 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2386                                            mp)
2387 {
2388   vat_main_t *vam = &vat_main;
2389   locator_set_msg_t ls;
2390
2391   ls.locator_set_index = ntohl (mp->locator_set_index);
2392   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2393   vec_add1 (vam->locator_set_msg, ls);
2394 }
2395
2396 static void
2397   vl_api_lisp_locator_set_details_t_handler_json
2398   (vl_api_lisp_locator_set_details_t * mp)
2399 {
2400   vat_main_t *vam = &vat_main;
2401   locator_set_msg_t ls;
2402
2403   ls.locator_set_index = ntohl (mp->locator_set_index);
2404   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2405   vec_add1 (vam->locator_set_msg, ls);
2406 }
2407
2408 static void
2409 add_lisp_eid_table_entry (vat_main_t * vam,
2410                           vl_api_lisp_eid_table_details_t * mp)
2411 {
2412   eid_table_t eid_table;
2413
2414   memset (&eid_table, 0, sizeof (eid_table));
2415   eid_table.is_local = mp->is_local;
2416   eid_table.locator_set_index = clib_net_to_host_u32 (mp->locator_set_index);
2417   eid_table.eid_type = mp->eid_type;
2418   eid_table.vni = clib_net_to_host_u32 (mp->vni);
2419   eid_table.eid_prefix_len = mp->eid_prefix_len;
2420   eid_table.ttl = clib_net_to_host_u32 (mp->ttl);
2421   eid_table.action = mp->action;
2422   eid_table.authoritative = mp->authoritative;
2423   clib_memcpy (eid_table.eid, mp->eid, sizeof (eid_table.eid));
2424   vec_add1 (vam->eid_tables, eid_table);
2425 }
2426
2427 static void
2428 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2429 {
2430   vat_main_t *vam = &vat_main;
2431   add_lisp_eid_table_entry (vam, mp);
2432 }
2433
2434 static void
2435 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2436                                               * mp)
2437 {
2438   vat_main_t *vam = &vat_main;
2439   add_lisp_eid_table_entry (vam, mp);
2440 }
2441
2442 static void
2443   vl_api_lisp_eid_table_map_details_t_handler
2444   (vl_api_lisp_eid_table_map_details_t * mp)
2445 {
2446   vat_main_t *vam = &vat_main;
2447
2448   u8 *line = format (0, "%=10d%=10d",
2449                      clib_net_to_host_u32 (mp->vni),
2450                      clib_net_to_host_u32 (mp->dp_table));
2451   fformat (vam->ofp, "%v\n", line);
2452   vec_free (line);
2453 }
2454
2455 static void
2456   vl_api_lisp_eid_table_map_details_t_handler_json
2457   (vl_api_lisp_eid_table_map_details_t * mp)
2458 {
2459   vat_main_t *vam = &vat_main;
2460   vat_json_node_t *node = NULL;
2461
2462   if (VAT_JSON_ARRAY != vam->json_tree.type)
2463     {
2464       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2465       vat_json_init_array (&vam->json_tree);
2466     }
2467   node = vat_json_array_add (&vam->json_tree);
2468   vat_json_init_object (node);
2469   vat_json_object_add_uint (node, "dp_table",
2470                             clib_net_to_host_u32 (mp->dp_table));
2471   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2472 }
2473
2474 static void
2475   vl_api_lisp_eid_table_vni_details_t_handler
2476   (vl_api_lisp_eid_table_vni_details_t * mp)
2477 {
2478   vat_main_t *vam = &vat_main;
2479
2480   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2481   fformat (vam->ofp, "%v\n", line);
2482   vec_free (line);
2483 }
2484
2485 static void
2486   vl_api_lisp_eid_table_vni_details_t_handler_json
2487   (vl_api_lisp_eid_table_vni_details_t * mp)
2488 {
2489   vat_main_t *vam = &vat_main;
2490   vat_json_node_t *node = NULL;
2491
2492   if (VAT_JSON_ARRAY != vam->json_tree.type)
2493     {
2494       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2495       vat_json_init_array (&vam->json_tree);
2496     }
2497   node = vat_json_array_add (&vam->json_tree);
2498   vat_json_init_object (node);
2499   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2500 }
2501
2502 static u8 *
2503 format_decap_next (u8 * s, va_list * args)
2504 {
2505   u32 next_index = va_arg (*args, u32);
2506
2507   switch (next_index)
2508     {
2509     case LISP_GPE_INPUT_NEXT_DROP:
2510       return format (s, "drop");
2511     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2512       return format (s, "ip4");
2513     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2514       return format (s, "ip6");
2515     default:
2516       return format (s, "unknown %d", next_index);
2517     }
2518   return s;
2519 }
2520
2521 static void
2522 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2523                                           mp)
2524 {
2525   vat_main_t *vam = &vat_main;
2526   u8 *iid_str;
2527   u8 *flag_str = NULL;
2528
2529   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2530
2531 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2532   foreach_lisp_gpe_flag_bit;
2533 #undef _
2534
2535   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2536            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2537            mp->tunnels,
2538            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2539            mp->source_ip,
2540            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2541            mp->destination_ip,
2542            ntohl (mp->encap_fib_id),
2543            ntohl (mp->decap_fib_id),
2544            format_decap_next, ntohl (mp->dcap_next),
2545            mp->ver_res >> 6,
2546            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2547
2548   vec_free (iid_str);
2549 }
2550
2551 static void
2552   vl_api_lisp_gpe_tunnel_details_t_handler_json
2553   (vl_api_lisp_gpe_tunnel_details_t * mp)
2554 {
2555   vat_main_t *vam = &vat_main;
2556   vat_json_node_t *node = NULL;
2557   struct in6_addr ip6;
2558   struct in_addr ip4;
2559   u8 *next_decap_str;
2560
2561   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2562
2563   if (VAT_JSON_ARRAY != vam->json_tree.type)
2564     {
2565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2566       vat_json_init_array (&vam->json_tree);
2567     }
2568   node = vat_json_array_add (&vam->json_tree);
2569
2570   vat_json_init_object (node);
2571   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2572   if (mp->is_ipv6)
2573     {
2574       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2575       vat_json_object_add_ip6 (node, "source address", ip6);
2576       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2577       vat_json_object_add_ip6 (node, "destination address", ip6);
2578     }
2579   else
2580     {
2581       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2582       vat_json_object_add_ip4 (node, "source address", ip4);
2583       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2584       vat_json_object_add_ip4 (node, "destination address", ip4);
2585     }
2586   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2587   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2588   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2589   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2590   vat_json_object_add_uint (node, "flags", mp->flags);
2591   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2592   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2593   vat_json_object_add_uint (node, "res", mp->res);
2594   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2595
2596   vec_free (next_decap_str);
2597 }
2598
2599 static void
2600 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2601                                             * mp)
2602 {
2603   vat_main_t *vam = &vat_main;
2604
2605   fformat (vam->ofp, "%=20U\n",
2606            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2607            mp->ip_address);
2608 }
2609
2610 static void
2611   vl_api_lisp_map_resolver_details_t_handler_json
2612   (vl_api_lisp_map_resolver_details_t * mp)
2613 {
2614   vat_main_t *vam = &vat_main;
2615   vat_json_node_t *node = NULL;
2616   struct in6_addr ip6;
2617   struct in_addr ip4;
2618
2619   if (VAT_JSON_ARRAY != vam->json_tree.type)
2620     {
2621       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2622       vat_json_init_array (&vam->json_tree);
2623     }
2624   node = vat_json_array_add (&vam->json_tree);
2625
2626   vat_json_init_object (node);
2627   if (mp->is_ipv6)
2628     {
2629       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2630       vat_json_object_add_ip6 (node, "map resolver", ip6);
2631     }
2632   else
2633     {
2634       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2635       vat_json_object_add_ip4 (node, "map resolver", ip4);
2636     }
2637 }
2638
2639 static void
2640   vl_api_show_lisp_status_reply_t_handler
2641   (vl_api_show_lisp_status_reply_t * mp)
2642 {
2643   vat_main_t *vam = &vat_main;
2644   i32 retval = ntohl (mp->retval);
2645
2646   if (0 <= retval)
2647     {
2648       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2649                mp->feature_status ? "enabled" : "disabled",
2650                mp->gpe_status ? "enabled" : "disabled");
2651     }
2652
2653   vam->retval = retval;
2654   vam->result_ready = 1;
2655 }
2656
2657 static void
2658   vl_api_show_lisp_status_reply_t_handler_json
2659   (vl_api_show_lisp_status_reply_t * mp)
2660 {
2661   vat_main_t *vam = &vat_main;
2662   vat_json_node_t node;
2663   u8 *gpe_status = NULL;
2664   u8 *feature_status = NULL;
2665
2666   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2667   feature_status = format (0, "%s",
2668                            mp->feature_status ? "enabled" : "disabled");
2669   vec_add1 (gpe_status, 0);
2670   vec_add1 (feature_status, 0);
2671
2672   vat_json_init_object (&node);
2673   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2674   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2675
2676   vec_free (gpe_status);
2677   vec_free (feature_status);
2678
2679   vat_json_print (vam->ofp, &node);
2680   vat_json_free (&node);
2681
2682   vam->retval = ntohl (mp->retval);
2683   vam->result_ready = 1;
2684 }
2685
2686 static void
2687   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2688   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2689 {
2690   vat_main_t *vam = &vat_main;
2691   i32 retval = ntohl (mp->retval);
2692
2693   if (retval >= 0)
2694     {
2695       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2696     }
2697
2698   vam->retval = retval;
2699   vam->result_ready = 1;
2700 }
2701
2702 static void
2703   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2704   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   vat_json_node_t *node = NULL;
2708
2709   if (VAT_JSON_ARRAY != vam->json_tree.type)
2710     {
2711       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2712       vat_json_init_array (&vam->json_tree);
2713     }
2714   node = vat_json_array_add (&vam->json_tree);
2715
2716   vat_json_init_object (node);
2717   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2718
2719   vat_json_print (vam->ofp, node);
2720   vat_json_free (node);
2721
2722   vam->retval = ntohl (mp->retval);
2723   vam->result_ready = 1;
2724 }
2725
2726 static void
2727 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2728 {
2729   vat_main_t *vam = &vat_main;
2730   i32 retval = ntohl (mp->retval);
2731
2732   if (0 <= retval)
2733     {
2734       fformat (vam->ofp, "%-20s%-16s\n",
2735                mp->status ? "enabled" : "disabled",
2736                mp->status ? (char *) mp->locator_set_name : "");
2737     }
2738
2739   vam->retval = retval;
2740   vam->result_ready = 1;
2741 }
2742
2743 static void
2744 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2745                                             mp)
2746 {
2747   vat_main_t *vam = &vat_main;
2748   vat_json_node_t node;
2749   u8 *status = 0;
2750
2751   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2752   vec_add1 (status, 0);
2753
2754   vat_json_init_object (&node);
2755   vat_json_object_add_string_copy (&node, "status", status);
2756   if (mp->status)
2757     {
2758       vat_json_object_add_string_copy (&node, "locator_set",
2759                                        mp->locator_set_name);
2760     }
2761
2762   vec_free (status);
2763
2764   vat_json_print (vam->ofp, &node);
2765   vat_json_free (&node);
2766
2767   vam->retval = ntohl (mp->retval);
2768   vam->result_ready = 1;
2769 }
2770
2771 static u8 *
2772 format_policer_type (u8 * s, va_list * va)
2773 {
2774   u32 i = va_arg (*va, u32);
2775
2776   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2777     s = format (s, "1r2c");
2778   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2779     s = format (s, "1r3c");
2780   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2781     s = format (s, "2r3c-2698");
2782   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2783     s = format (s, "2r3c-4115");
2784   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2785     s = format (s, "2r3c-mef5cf1");
2786   else
2787     s = format (s, "ILLEGAL");
2788   return s;
2789 }
2790
2791 static u8 *
2792 format_policer_rate_type (u8 * s, va_list * va)
2793 {
2794   u32 i = va_arg (*va, u32);
2795
2796   if (i == SSE2_QOS_RATE_KBPS)
2797     s = format (s, "kbps");
2798   else if (i == SSE2_QOS_RATE_PPS)
2799     s = format (s, "pps");
2800   else
2801     s = format (s, "ILLEGAL");
2802   return s;
2803 }
2804
2805 static u8 *
2806 format_policer_round_type (u8 * s, va_list * va)
2807 {
2808   u32 i = va_arg (*va, u32);
2809
2810   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2811     s = format (s, "closest");
2812   else if (i == SSE2_QOS_ROUND_TO_UP)
2813     s = format (s, "up");
2814   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2815     s = format (s, "down");
2816   else
2817     s = format (s, "ILLEGAL");
2818   return s;
2819 }
2820
2821 static u8 *
2822 format_policer_action_type (u8 * s, va_list * va)
2823 {
2824   u32 i = va_arg (*va, u32);
2825
2826   if (i == SSE2_QOS_ACTION_DROP)
2827     s = format (s, "drop");
2828   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2829     s = format (s, "transmit");
2830   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2831     s = format (s, "mark-and-transmit");
2832   else
2833     s = format (s, "ILLEGAL");
2834   return s;
2835 }
2836
2837 static u8 *
2838 format_dscp (u8 * s, va_list * va)
2839 {
2840   u32 i = va_arg (*va, u32);
2841   char *t = 0;
2842
2843   switch (i)
2844     {
2845 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2846       foreach_vnet_dscp
2847 #undef _
2848     default:
2849       return format (s, "ILLEGAL");
2850     }
2851   s = format (s, "%s", t);
2852   return s;
2853 }
2854
2855 static void
2856 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2857 {
2858   vat_main_t *vam = &vat_main;
2859   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2860
2861   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2862     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2863   else
2864     conform_dscp_str = format (0, "");
2865
2866   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2867     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2868   else
2869     exceed_dscp_str = format (0, "");
2870
2871   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2872     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2873   else
2874     violate_dscp_str = format (0, "");
2875
2876   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2877            "rate type %U, round type %U, %s rate, %s color-aware, "
2878            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2879            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2880            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2881            mp->name,
2882            format_policer_type, mp->type,
2883            ntohl (mp->cir),
2884            ntohl (mp->eir),
2885            clib_net_to_host_u64 (mp->cb),
2886            clib_net_to_host_u64 (mp->eb),
2887            format_policer_rate_type, mp->rate_type,
2888            format_policer_round_type, mp->round_type,
2889            mp->single_rate ? "single" : "dual",
2890            mp->color_aware ? "is" : "not",
2891            ntohl (mp->cir_tokens_per_period),
2892            ntohl (mp->pir_tokens_per_period),
2893            ntohl (mp->scale),
2894            ntohl (mp->current_limit),
2895            ntohl (mp->current_bucket),
2896            ntohl (mp->extended_limit),
2897            ntohl (mp->extended_bucket),
2898            clib_net_to_host_u64 (mp->last_update_time),
2899            format_policer_action_type, mp->conform_action_type,
2900            conform_dscp_str,
2901            format_policer_action_type, mp->exceed_action_type,
2902            exceed_dscp_str,
2903            format_policer_action_type, mp->violate_action_type,
2904            violate_dscp_str);
2905
2906   vec_free (conform_dscp_str);
2907   vec_free (exceed_dscp_str);
2908   vec_free (violate_dscp_str);
2909 }
2910
2911 static void vl_api_policer_details_t_handler_json
2912   (vl_api_policer_details_t * mp)
2913 {
2914   vat_main_t *vam = &vat_main;
2915   vat_json_node_t *node;
2916   u8 *rate_type_str, *round_type_str, *type_str;
2917   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2918
2919   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2920   round_type_str =
2921     format (0, "%U", format_policer_round_type, mp->round_type);
2922   type_str = format (0, "%U", format_policer_type, mp->type);
2923   conform_action_str = format (0, "%U", format_policer_action_type,
2924                                mp->conform_action_type);
2925   exceed_action_str = format (0, "%U", format_policer_action_type,
2926                               mp->exceed_action_type);
2927   violate_action_str = format (0, "%U", format_policer_action_type,
2928                                mp->violate_action_type);
2929
2930   if (VAT_JSON_ARRAY != vam->json_tree.type)
2931     {
2932       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2933       vat_json_init_array (&vam->json_tree);
2934     }
2935   node = vat_json_array_add (&vam->json_tree);
2936
2937   vat_json_init_object (node);
2938   vat_json_object_add_string_copy (node, "name", mp->name);
2939   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2940   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2941   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
2942   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
2943   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2944   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2945   vat_json_object_add_string_copy (node, "type", type_str);
2946   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2947   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2948   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2949   vat_json_object_add_uint (node, "cir_tokens_per_period",
2950                             ntohl (mp->cir_tokens_per_period));
2951   vat_json_object_add_uint (node, "eir_tokens_per_period",
2952                             ntohl (mp->pir_tokens_per_period));
2953   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2954   vat_json_object_add_uint (node, "current_bucket",
2955                             ntohl (mp->current_bucket));
2956   vat_json_object_add_uint (node, "extended_limit",
2957                             ntohl (mp->extended_limit));
2958   vat_json_object_add_uint (node, "extended_bucket",
2959                             ntohl (mp->extended_bucket));
2960   vat_json_object_add_uint (node, "last_update_time",
2961                             ntohl (mp->last_update_time));
2962   vat_json_object_add_string_copy (node, "conform_action",
2963                                    conform_action_str);
2964   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2965     {
2966       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2967       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2968       vec_free (dscp_str);
2969     }
2970   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
2971   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2972     {
2973       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2974       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2975       vec_free (dscp_str);
2976     }
2977   vat_json_object_add_string_copy (node, "violate_action",
2978                                    violate_action_str);
2979   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2980     {
2981       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2982       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2983       vec_free (dscp_str);
2984     }
2985
2986   vec_free (rate_type_str);
2987   vec_free (round_type_str);
2988   vec_free (type_str);
2989   vec_free (conform_action_str);
2990   vec_free (exceed_action_str);
2991   vec_free (violate_action_str);
2992 }
2993
2994 static void
2995 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2996                                            mp)
2997 {
2998   vat_main_t *vam = &vat_main;
2999   int i, count = ntohl (mp->count);
3000
3001   if (count > 0)
3002     fformat (vam->ofp, "classify table ids (%d) : ", count);
3003   for (i = 0; i < count; i++)
3004     {
3005       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3006       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3007     }
3008   vam->retval = ntohl (mp->retval);
3009   vam->result_ready = 1;
3010 }
3011
3012 static void
3013   vl_api_classify_table_ids_reply_t_handler_json
3014   (vl_api_classify_table_ids_reply_t * mp)
3015 {
3016   vat_main_t *vam = &vat_main;
3017   int i, count = ntohl (mp->count);
3018
3019   if (count > 0)
3020     {
3021       vat_json_node_t node;
3022
3023       vat_json_init_object (&node);
3024       for (i = 0; i < count; i++)
3025         {
3026           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3027         }
3028       vat_json_print (vam->ofp, &node);
3029       vat_json_free (&node);
3030     }
3031   vam->retval = ntohl (mp->retval);
3032   vam->result_ready = 1;
3033 }
3034
3035 static void
3036   vl_api_classify_table_by_interface_reply_t_handler
3037   (vl_api_classify_table_by_interface_reply_t * mp)
3038 {
3039   vat_main_t *vam = &vat_main;
3040   u32 table_id;
3041
3042   table_id = ntohl (mp->l2_table_id);
3043   if (table_id != ~0)
3044     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3045   else
3046     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3047   table_id = ntohl (mp->ip4_table_id);
3048   if (table_id != ~0)
3049     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3050   else
3051     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3052   table_id = ntohl (mp->ip6_table_id);
3053   if (table_id != ~0)
3054     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3055   else
3056     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3057   vam->retval = ntohl (mp->retval);
3058   vam->result_ready = 1;
3059 }
3060
3061 static void
3062   vl_api_classify_table_by_interface_reply_t_handler_json
3063   (vl_api_classify_table_by_interface_reply_t * mp)
3064 {
3065   vat_main_t *vam = &vat_main;
3066   vat_json_node_t node;
3067
3068   vat_json_init_object (&node);
3069
3070   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3071   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3072   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3073
3074   vat_json_print (vam->ofp, &node);
3075   vat_json_free (&node);
3076
3077   vam->retval = ntohl (mp->retval);
3078   vam->result_ready = 1;
3079 }
3080
3081 static void vl_api_policer_add_del_reply_t_handler
3082   (vl_api_policer_add_del_reply_t * mp)
3083 {
3084   vat_main_t *vam = &vat_main;
3085   i32 retval = ntohl (mp->retval);
3086   if (vam->async_mode)
3087     {
3088       vam->async_errors += (retval < 0);
3089     }
3090   else
3091     {
3092       vam->retval = retval;
3093       vam->result_ready = 1;
3094       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3095         /*
3096          * Note: this is just barely thread-safe, depends on
3097          * the main thread spinning waiting for an answer...
3098          */
3099         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3100     }
3101 }
3102
3103 static void vl_api_policer_add_del_reply_t_handler_json
3104   (vl_api_policer_add_del_reply_t * mp)
3105 {
3106   vat_main_t *vam = &vat_main;
3107   vat_json_node_t node;
3108
3109   vat_json_init_object (&node);
3110   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3111   vat_json_object_add_uint (&node, "policer_index",
3112                             ntohl (mp->policer_index));
3113
3114   vat_json_print (vam->ofp, &node);
3115   vat_json_free (&node);
3116
3117   vam->retval = ntohl (mp->retval);
3118   vam->result_ready = 1;
3119 }
3120
3121 /* Format hex dump. */
3122 u8 *
3123 format_hex_bytes (u8 * s, va_list * va)
3124 {
3125   u8 *bytes = va_arg (*va, u8 *);
3126   int n_bytes = va_arg (*va, int);
3127   uword i;
3128
3129   /* Print short or long form depending on byte count. */
3130   uword short_form = n_bytes <= 32;
3131   uword indent = format_get_indent (s);
3132
3133   if (n_bytes == 0)
3134     return s;
3135
3136   for (i = 0; i < n_bytes; i++)
3137     {
3138       if (!short_form && (i % 32) == 0)
3139         s = format (s, "%08x: ", i);
3140       s = format (s, "%02x", bytes[i]);
3141       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3142         s = format (s, "\n%U", format_white_space, indent);
3143     }
3144
3145   return s;
3146 }
3147
3148 static void
3149 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3150                                             * mp)
3151 {
3152   vat_main_t *vam = &vat_main;
3153   i32 retval = ntohl (mp->retval);
3154   if (retval == 0)
3155     {
3156       fformat (vam->ofp, "classify table info :\n");
3157       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3158                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3159                ntohl (mp->miss_next_index));
3160       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3161                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3162                ntohl (mp->match_n_vectors));
3163       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3164                ntohl (mp->mask_length));
3165     }
3166   vam->retval = retval;
3167   vam->result_ready = 1;
3168 }
3169
3170 static void
3171   vl_api_classify_table_info_reply_t_handler_json
3172   (vl_api_classify_table_info_reply_t * mp)
3173 {
3174   vat_main_t *vam = &vat_main;
3175   vat_json_node_t node;
3176
3177   i32 retval = ntohl (mp->retval);
3178   if (retval == 0)
3179     {
3180       vat_json_init_object (&node);
3181
3182       vat_json_object_add_int (&node, "sessions",
3183                                ntohl (mp->active_sessions));
3184       vat_json_object_add_int (&node, "nexttbl",
3185                                ntohl (mp->next_table_index));
3186       vat_json_object_add_int (&node, "nextnode",
3187                                ntohl (mp->miss_next_index));
3188       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3189       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3190       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3191       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3192                       ntohl (mp->mask_length), 0);
3193       vat_json_object_add_string_copy (&node, "mask", s);
3194
3195       vat_json_print (vam->ofp, &node);
3196       vat_json_free (&node);
3197     }
3198   vam->retval = ntohl (mp->retval);
3199   vam->result_ready = 1;
3200 }
3201
3202 static void
3203 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3204                                            mp)
3205 {
3206   vat_main_t *vam = &vat_main;
3207
3208   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3209            ntohl (mp->hit_next_index), ntohl (mp->advance),
3210            ntohl (mp->opaque_index));
3211   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3212            ntohl (mp->match_length));
3213 }
3214
3215 static void
3216   vl_api_classify_session_details_t_handler_json
3217   (vl_api_classify_session_details_t * mp)
3218 {
3219   vat_main_t *vam = &vat_main;
3220   vat_json_node_t *node = NULL;
3221
3222   if (VAT_JSON_ARRAY != vam->json_tree.type)
3223     {
3224       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3225       vat_json_init_array (&vam->json_tree);
3226     }
3227   node = vat_json_array_add (&vam->json_tree);
3228
3229   vat_json_init_object (node);
3230   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3231   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3232   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3233   u8 *s =
3234     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3235             0);
3236   vat_json_object_add_string_copy (node, "match", s);
3237 }
3238
3239 static void vl_api_pg_create_interface_reply_t_handler
3240   (vl_api_pg_create_interface_reply_t * mp)
3241 {
3242   vat_main_t *vam = &vat_main;
3243
3244   vam->retval = ntohl (mp->retval);
3245   vam->result_ready = 1;
3246 }
3247
3248 static void vl_api_pg_create_interface_reply_t_handler_json
3249   (vl_api_pg_create_interface_reply_t * mp)
3250 {
3251   vat_main_t *vam = &vat_main;
3252   vat_json_node_t node;
3253
3254   i32 retval = ntohl (mp->retval);
3255   if (retval == 0)
3256     {
3257       vat_json_init_object (&node);
3258
3259       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3260
3261       vat_json_print (vam->ofp, &node);
3262       vat_json_free (&node);
3263     }
3264   vam->retval = ntohl (mp->retval);
3265   vam->result_ready = 1;
3266 }
3267
3268 static void vl_api_policer_classify_details_t_handler
3269   (vl_api_policer_classify_details_t * mp)
3270 {
3271   vat_main_t *vam = &vat_main;
3272
3273   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3274            ntohl (mp->table_index));
3275 }
3276
3277 static void vl_api_policer_classify_details_t_handler_json
3278   (vl_api_policer_classify_details_t * mp)
3279 {
3280   vat_main_t *vam = &vat_main;
3281   vat_json_node_t *node;
3282
3283   if (VAT_JSON_ARRAY != vam->json_tree.type)
3284     {
3285       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3286       vat_json_init_array (&vam->json_tree);
3287     }
3288   node = vat_json_array_add (&vam->json_tree);
3289
3290   vat_json_init_object (node);
3291   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3292   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3293 }
3294
3295 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3296   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3297 {
3298   vat_main_t *vam = &vat_main;
3299   i32 retval = ntohl (mp->retval);
3300   if (vam->async_mode)
3301     {
3302       vam->async_errors += (retval < 0);
3303     }
3304   else
3305     {
3306       vam->retval = retval;
3307       vam->sw_if_index = ntohl (mp->sw_if_index);
3308       vam->result_ready = 1;
3309     }
3310 }
3311
3312 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3313   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3314 {
3315   vat_main_t *vam = &vat_main;
3316   vat_json_node_t node;
3317
3318   vat_json_init_object (&node);
3319   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3320   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3321
3322   vat_json_print (vam->ofp, &node);
3323   vat_json_free (&node);
3324
3325   vam->retval = ntohl (mp->retval);
3326   vam->result_ready = 1;
3327 }
3328
3329 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3330 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3331 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3332 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3333
3334 /*
3335  * Generate boilerplate reply handlers, which
3336  * dig the return value out of the xxx_reply_t API message,
3337  * stick it into vam->retval, and set vam->result_ready
3338  *
3339  * Could also do this by pointing N message decode slots at
3340  * a single function, but that could break in subtle ways.
3341  */
3342
3343 #define foreach_standard_reply_retval_handler           \
3344 _(sw_interface_set_flags_reply)                         \
3345 _(sw_interface_add_del_address_reply)                   \
3346 _(sw_interface_set_table_reply)                         \
3347 _(sw_interface_set_vpath_reply)                         \
3348 _(sw_interface_set_l2_bridge_reply)                     \
3349 _(bridge_domain_add_del_reply)                          \
3350 _(sw_interface_set_l2_xconnect_reply)                   \
3351 _(l2fib_add_del_reply)                                  \
3352 _(ip_add_del_route_reply)                               \
3353 _(proxy_arp_add_del_reply)                              \
3354 _(proxy_arp_intfc_enable_disable_reply)                 \
3355 _(mpls_add_del_encap_reply)                             \
3356 _(mpls_add_del_decap_reply)                             \
3357 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3358 _(sw_interface_set_unnumbered_reply)                    \
3359 _(ip_neighbor_add_del_reply)                            \
3360 _(reset_vrf_reply)                                      \
3361 _(oam_add_del_reply)                                    \
3362 _(reset_fib_reply)                                      \
3363 _(dhcp_proxy_config_reply)                              \
3364 _(dhcp_proxy_config_2_reply)                            \
3365 _(dhcp_proxy_set_vss_reply)                             \
3366 _(dhcp_client_config_reply)                             \
3367 _(set_ip_flow_hash_reply)                               \
3368 _(sw_interface_ip6_enable_disable_reply)                \
3369 _(sw_interface_ip6_set_link_local_address_reply)        \
3370 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3371 _(sw_interface_ip6nd_ra_config_reply)                   \
3372 _(set_arp_neighbor_limit_reply)                         \
3373 _(l2_patch_add_del_reply)                               \
3374 _(sr_tunnel_add_del_reply)                              \
3375 _(sr_policy_add_del_reply)                              \
3376 _(sr_multicast_map_add_del_reply)                       \
3377 _(classify_add_del_session_reply)                       \
3378 _(classify_set_interface_ip_table_reply)                \
3379 _(classify_set_interface_l2_tables_reply)               \
3380 _(l2tpv3_set_tunnel_cookies_reply)                      \
3381 _(l2tpv3_interface_enable_disable_reply)                \
3382 _(l2tpv3_set_lookup_key_reply)                          \
3383 _(l2_fib_clear_table_reply)                             \
3384 _(l2_interface_efp_filter_reply)                        \
3385 _(l2_interface_vlan_tag_rewrite_reply)                  \
3386 _(modify_vhost_user_if_reply)                           \
3387 _(delete_vhost_user_if_reply)                           \
3388 _(want_ip4_arp_events_reply)                            \
3389 _(want_ip6_nd_events_reply)                             \
3390 _(input_acl_set_interface_reply)                        \
3391 _(ipsec_spd_add_del_reply)                              \
3392 _(ipsec_interface_add_del_spd_reply)                    \
3393 _(ipsec_spd_add_del_entry_reply)                        \
3394 _(ipsec_sad_add_del_entry_reply)                        \
3395 _(ipsec_sa_set_key_reply)                               \
3396 _(ikev2_profile_add_del_reply)                          \
3397 _(ikev2_profile_set_auth_reply)                         \
3398 _(ikev2_profile_set_id_reply)                           \
3399 _(ikev2_profile_set_ts_reply)                           \
3400 _(ikev2_set_local_key_reply)                            \
3401 _(delete_loopback_reply)                                \
3402 _(bd_ip_mac_add_del_reply)                              \
3403 _(map_del_domain_reply)                                 \
3404 _(map_add_del_rule_reply)                               \
3405 _(want_interface_events_reply)                          \
3406 _(want_stats_reply)                                     \
3407 _(cop_interface_enable_disable_reply)                   \
3408 _(cop_whitelist_enable_disable_reply)                   \
3409 _(sw_interface_clear_stats_reply)                       \
3410 _(ioam_enable_reply)                              \
3411 _(ioam_disable_reply)                              \
3412 _(lisp_add_del_locator_reply)                           \
3413 _(lisp_add_del_local_eid_reply)                         \
3414 _(lisp_add_del_remote_mapping_reply)                    \
3415 _(lisp_add_del_adjacency_reply)                         \
3416 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3417 _(lisp_add_del_map_resolver_reply)                      \
3418 _(lisp_gpe_enable_disable_reply)                        \
3419 _(lisp_gpe_add_del_iface_reply)                         \
3420 _(lisp_enable_disable_reply)                            \
3421 _(lisp_pitr_set_locator_set_reply)                      \
3422 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3423 _(lisp_eid_table_add_del_map_reply)                     \
3424 _(vxlan_gpe_add_del_tunnel_reply)                       \
3425 _(af_packet_delete_reply)                               \
3426 _(policer_classify_set_interface_reply)                 \
3427 _(netmap_create_reply)                                  \
3428 _(netmap_delete_reply)                                  \
3429 _(ipfix_enable_reply)                                   \
3430 _(pg_capture_reply)                                     \
3431 _(pg_enable_disable_reply)                              \
3432 _(ip_source_and_port_range_check_add_del_reply)         \
3433 _(ip_source_and_port_range_check_interface_add_del_reply)\
3434 _(delete_subif_reply)
3435
3436 #define _(n)                                    \
3437     static void vl_api_##n##_t_handler          \
3438     (vl_api_##n##_t * mp)                       \
3439     {                                           \
3440         vat_main_t * vam = &vat_main;           \
3441         i32 retval = ntohl(mp->retval);         \
3442         if (vam->async_mode) {                  \
3443             vam->async_errors += (retval < 0);  \
3444         } else {                                \
3445             vam->retval = retval;               \
3446             vam->result_ready = 1;              \
3447         }                                       \
3448     }
3449 foreach_standard_reply_retval_handler;
3450 #undef _
3451
3452 #define _(n)                                    \
3453     static void vl_api_##n##_t_handler_json     \
3454     (vl_api_##n##_t * mp)                       \
3455     {                                           \
3456         vat_main_t * vam = &vat_main;           \
3457         vat_json_node_t node;                   \
3458         vat_json_init_object(&node);            \
3459         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3460         vat_json_print(vam->ofp, &node);        \
3461         vam->retval = ntohl(mp->retval);        \
3462         vam->result_ready = 1;                  \
3463     }
3464 foreach_standard_reply_retval_handler;
3465 #undef _
3466
3467 /*
3468  * Table of message reply handlers, must include boilerplate handlers
3469  * we just generated
3470  */
3471
3472 #define foreach_vpe_api_reply_msg                                       \
3473 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3474 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3475 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3476 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3477 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3478 _(NOPRINT_CONTROL_PING_REPLY, noprint_control_ping_reply)               \
3479 _(CLI_REPLY, cli_reply)                                                 \
3480 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3481 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3482   sw_interface_add_del_address_reply)                                   \
3483 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3484 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3485 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3486   sw_interface_set_l2_xconnect_reply)                                   \
3487 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3488   sw_interface_set_l2_bridge_reply)                                     \
3489 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3490 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3491 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3492 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3493 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3494 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3495 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3496 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3497 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3498 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3499 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3500 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3501 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3502   proxy_arp_intfc_enable_disable_reply)                                 \
3503 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3504 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3505 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3506 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3507   mpls_ethernet_add_del_tunnel_reply)                                   \
3508 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3509   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3510 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3511   sw_interface_set_unnumbered_reply)                                    \
3512 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3513 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3514 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3515 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3516 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3517 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3518 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3519 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3520 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3521 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3522 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3523 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3524   sw_interface_ip6_enable_disable_reply)                                \
3525 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3526   sw_interface_ip6_set_link_local_address_reply)                        \
3527 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3528   sw_interface_ip6nd_ra_prefix_reply)                                   \
3529 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3530   sw_interface_ip6nd_ra_config_reply)                                   \
3531 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3532 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3533 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3534 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3535 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3536 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3537 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3538 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3539 classify_set_interface_ip_table_reply)                                  \
3540 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3541   classify_set_interface_l2_tables_reply)                               \
3542 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3543 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3544 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3545 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3546 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3547   l2tpv3_interface_enable_disable_reply)                                \
3548 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3549 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3550 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3551 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3552 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3553 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3554 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3555 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3556 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3557 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3558 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3559 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3560 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3561 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3562 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3563 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3564 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3565 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3566 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3567 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3568 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3569 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3570 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3571 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3572 _(IP_DETAILS, ip_details)                                               \
3573 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3574 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3575 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3576 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3577 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3578 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3579 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3580 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3581 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3582 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3583 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3584 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3585 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3586 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3587 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3588 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3589 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3590 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3591 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3592 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3593 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3594 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3595 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3596 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3597 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3598 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3599 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3600 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3601 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3602 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3603 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3604 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3605 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3606 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3607 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3608 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3609 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3610 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3611 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3612 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3613 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3614 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3615 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3616 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3617 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3618 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3619 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3620 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3621 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3622 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3623 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3624   lisp_add_del_map_request_itr_rlocs_reply)                             \
3625 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3626   lisp_get_map_request_itr_rlocs_reply)                                 \
3627 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3628 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3629 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3630 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3631 _(POLICER_DETAILS, policer_details)                                     \
3632 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3633 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3634 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3635 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3636 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3637 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3638 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3639 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3640 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3641 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3642 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3643 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3644 _(IPFIX_ENABLE_REPLY, ipfix_enable_reply)                               \
3645 _(IPFIX_DETAILS, ipfix_details)                                         \
3646 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3647 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3648 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3649 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3650 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3651  ip_source_and_port_range_check_add_del_reply)                          \
3652 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3653  ip_source_and_port_range_check_interface_add_del_reply)                \
3654 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3655 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3656 _(DELETE_SUBIF_REPLY, delete_subif_reply)
3657
3658 /* M: construct, but don't yet send a message */
3659
3660 #define M(T,t)                                  \
3661 do {                                            \
3662     vam->result_ready = 0;                      \
3663     mp = vl_msg_api_alloc(sizeof(*mp));         \
3664     memset (mp, 0, sizeof (*mp));               \
3665     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3666     mp->client_index = vam->my_client_index;    \
3667 } while(0);
3668
3669 #define M2(T,t,n)                               \
3670 do {                                            \
3671     vam->result_ready = 0;                      \
3672     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3673     memset (mp, 0, sizeof (*mp));               \
3674     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3675     mp->client_index = vam->my_client_index;    \
3676 } while(0);
3677
3678
3679 /* S: send a message */
3680 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3681
3682 /* W: wait for results, with timeout */
3683 #define W                                       \
3684 do {                                            \
3685     timeout = vat_time_now (vam) + 1.0;         \
3686                                                 \
3687     while (vat_time_now (vam) < timeout) {      \
3688         if (vam->result_ready == 1) {           \
3689             return (vam->retval);               \
3690         }                                       \
3691     }                                           \
3692     return -99;                                 \
3693 } while(0);
3694
3695 /* W2: wait for results, with timeout */
3696 #define W2(body)                                \
3697 do {                                            \
3698     timeout = vat_time_now (vam) + 1.0;         \
3699                                                 \
3700     while (vat_time_now (vam) < timeout) {      \
3701         if (vam->result_ready == 1) {           \
3702           (body);                               \
3703           return (vam->retval);                 \
3704         }                                       \
3705     }                                           \
3706     return -99;                                 \
3707 } while(0);
3708
3709 /* W_L: wait for results, with timeout */
3710 #define W_L(body)                               \
3711 do {                                            \
3712     timeout = vat_time_now (vam) + 1.0;         \
3713                                                 \
3714     while (vat_time_now (vam) < timeout) {      \
3715         if (vam->result_ready == 1) {           \
3716           (body);                               \
3717           return (vam->retval);                 \
3718         }                                       \
3719     }                                           \
3720     vam->noprint_msg = 0;     \
3721     return -99;                                 \
3722 } while(0);
3723
3724 typedef struct
3725 {
3726   u8 *name;
3727   u32 value;
3728 } name_sort_t;
3729
3730
3731 #define STR_VTR_OP_CASE(op)     \
3732     case L2_VTR_ ## op:         \
3733         return "" # op;
3734
3735 static const char *
3736 str_vtr_op (u32 vtr_op)
3737 {
3738   switch (vtr_op)
3739     {
3740       STR_VTR_OP_CASE (DISABLED);
3741       STR_VTR_OP_CASE (PUSH_1);
3742       STR_VTR_OP_CASE (PUSH_2);
3743       STR_VTR_OP_CASE (POP_1);
3744       STR_VTR_OP_CASE (POP_2);
3745       STR_VTR_OP_CASE (TRANSLATE_1_1);
3746       STR_VTR_OP_CASE (TRANSLATE_1_2);
3747       STR_VTR_OP_CASE (TRANSLATE_2_1);
3748       STR_VTR_OP_CASE (TRANSLATE_2_2);
3749     }
3750
3751   return "UNKNOWN";
3752 }
3753
3754 static int
3755 dump_sub_interface_table (vat_main_t * vam)
3756 {
3757   const sw_interface_subif_t *sub = NULL;
3758
3759   if (vam->json_output)
3760     {
3761       clib_warning
3762         ("JSON output supported only for VPE API calls and dump_stats_table");
3763       return -99;
3764     }
3765
3766   fformat (vam->ofp,
3767            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3768            "Interface", "sw_if_index",
3769            "sub id", "dot1ad", "tags", "outer id",
3770            "inner id", "exact", "default", "outer any", "inner any");
3771
3772   vec_foreach (sub, vam->sw_if_subif_table)
3773   {
3774     fformat (vam->ofp,
3775              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3776              sub->interface_name,
3777              sub->sw_if_index,
3778              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3779              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3780              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3781              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3782     if (sub->vtr_op != L2_VTR_DISABLED)
3783       {
3784         fformat (vam->ofp,
3785                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3786                  "tag1: %d tag2: %d ]\n",
3787                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3788                  sub->vtr_tag1, sub->vtr_tag2);
3789       }
3790   }
3791
3792   return 0;
3793 }
3794
3795 static int
3796 name_sort_cmp (void *a1, void *a2)
3797 {
3798   name_sort_t *n1 = a1;
3799   name_sort_t *n2 = a2;
3800
3801   return strcmp ((char *) n1->name, (char *) n2->name);
3802 }
3803
3804 static int
3805 dump_interface_table (vat_main_t * vam)
3806 {
3807   hash_pair_t *p;
3808   name_sort_t *nses = 0, *ns;
3809
3810   if (vam->json_output)
3811     {
3812       clib_warning
3813         ("JSON output supported only for VPE API calls and dump_stats_table");
3814       return -99;
3815     }
3816
3817   /* *INDENT-OFF* */
3818   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3819   ({
3820     vec_add2 (nses, ns, 1);
3821     ns->name = (u8 *)(p->key);
3822     ns->value = (u32) p->value[0];
3823   }));
3824   /* *INDENT-ON* */
3825
3826   vec_sort_with_function (nses, name_sort_cmp);
3827
3828   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3829   vec_foreach (ns, nses)
3830   {
3831     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3832   }
3833   vec_free (nses);
3834   return 0;
3835 }
3836
3837 static int
3838 dump_ip_table (vat_main_t * vam, int is_ipv6)
3839 {
3840   const ip_details_t *det = NULL;
3841   const ip_address_details_t *address = NULL;
3842   u32 i = ~0;
3843
3844   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3845
3846   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3847   {
3848     i++;
3849     if (!det->present)
3850       {
3851         continue;
3852       }
3853     fformat (vam->ofp, "%-12d\n", i);
3854     fformat (vam->ofp,
3855              "            %-30s%-13s\n", "Address", "Prefix length");
3856     if (!det->addr)
3857       {
3858         continue;
3859       }
3860     vec_foreach (address, det->addr)
3861     {
3862       fformat (vam->ofp,
3863                "            %-30U%-13d\n",
3864                is_ipv6 ? format_ip6_address : format_ip4_address,
3865                address->ip, address->prefix_length);
3866     }
3867   }
3868
3869   return 0;
3870 }
3871
3872 static int
3873 dump_ipv4_table (vat_main_t * vam)
3874 {
3875   if (vam->json_output)
3876     {
3877       clib_warning
3878         ("JSON output supported only for VPE API calls and dump_stats_table");
3879       return -99;
3880     }
3881
3882   return dump_ip_table (vam, 0);
3883 }
3884
3885 static int
3886 dump_ipv6_table (vat_main_t * vam)
3887 {
3888   if (vam->json_output)
3889     {
3890       clib_warning
3891         ("JSON output supported only for VPE API calls and dump_stats_table");
3892       return -99;
3893     }
3894
3895   return dump_ip_table (vam, 1);
3896 }
3897
3898 static char *
3899 counter_type_to_str (u8 counter_type, u8 is_combined)
3900 {
3901   if (!is_combined)
3902     {
3903       switch (counter_type)
3904         {
3905         case VNET_INTERFACE_COUNTER_DROP:
3906           return "drop";
3907         case VNET_INTERFACE_COUNTER_PUNT:
3908           return "punt";
3909         case VNET_INTERFACE_COUNTER_IP4:
3910           return "ip4";
3911         case VNET_INTERFACE_COUNTER_IP6:
3912           return "ip6";
3913         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3914           return "rx-no-buf";
3915         case VNET_INTERFACE_COUNTER_RX_MISS:
3916           return "rx-miss";
3917         case VNET_INTERFACE_COUNTER_RX_ERROR:
3918           return "rx-error";
3919         case VNET_INTERFACE_COUNTER_TX_ERROR:
3920           return "tx-error";
3921         default:
3922           return "INVALID-COUNTER-TYPE";
3923         }
3924     }
3925   else
3926     {
3927       switch (counter_type)
3928         {
3929         case VNET_INTERFACE_COUNTER_RX:
3930           return "rx";
3931         case VNET_INTERFACE_COUNTER_TX:
3932           return "tx";
3933         default:
3934           return "INVALID-COUNTER-TYPE";
3935         }
3936     }
3937 }
3938
3939 static int
3940 dump_stats_table (vat_main_t * vam)
3941 {
3942   vat_json_node_t node;
3943   vat_json_node_t *msg_array;
3944   vat_json_node_t *msg;
3945   vat_json_node_t *counter_array;
3946   vat_json_node_t *counter;
3947   interface_counter_t c;
3948   u64 packets;
3949   ip4_fib_counter_t *c4;
3950   ip6_fib_counter_t *c6;
3951   int i, j;
3952
3953   if (!vam->json_output)
3954     {
3955       clib_warning ("dump_stats_table supported only in JSON format");
3956       return -99;
3957     }
3958
3959   vat_json_init_object (&node);
3960
3961   /* interface counters */
3962   msg_array = vat_json_object_add (&node, "interface_counters");
3963   vat_json_init_array (msg_array);
3964   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
3965     {
3966       msg = vat_json_array_add (msg_array);
3967       vat_json_init_object (msg);
3968       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3969                                        (u8 *) counter_type_to_str (i, 0));
3970       vat_json_object_add_int (msg, "is_combined", 0);
3971       counter_array = vat_json_object_add (msg, "data");
3972       vat_json_init_array (counter_array);
3973       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
3974         {
3975           packets = vam->simple_interface_counters[i][j];
3976           vat_json_array_add_uint (counter_array, packets);
3977         }
3978     }
3979   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
3980     {
3981       msg = vat_json_array_add (msg_array);
3982       vat_json_init_object (msg);
3983       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3984                                        (u8 *) counter_type_to_str (i, 1));
3985       vat_json_object_add_int (msg, "is_combined", 1);
3986       counter_array = vat_json_object_add (msg, "data");
3987       vat_json_init_array (counter_array);
3988       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
3989         {
3990           c = vam->combined_interface_counters[i][j];
3991           counter = vat_json_array_add (counter_array);
3992           vat_json_init_object (counter);
3993           vat_json_object_add_uint (counter, "packets", c.packets);
3994           vat_json_object_add_uint (counter, "bytes", c.bytes);
3995         }
3996     }
3997
3998   /* ip4 fib counters */
3999   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4000   vat_json_init_array (msg_array);
4001   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4002     {
4003       msg = vat_json_array_add (msg_array);
4004       vat_json_init_object (msg);
4005       vat_json_object_add_uint (msg, "vrf_id",
4006                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4007       counter_array = vat_json_object_add (msg, "c");
4008       vat_json_init_array (counter_array);
4009       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4010         {
4011           counter = vat_json_array_add (counter_array);
4012           vat_json_init_object (counter);
4013           c4 = &vam->ip4_fib_counters[i][j];
4014           vat_json_object_add_ip4 (counter, "address", c4->address);
4015           vat_json_object_add_uint (counter, "address_length",
4016                                     c4->address_length);
4017           vat_json_object_add_uint (counter, "packets", c4->packets);
4018           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4019         }
4020     }
4021
4022   /* ip6 fib counters */
4023   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4024   vat_json_init_array (msg_array);
4025   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4026     {
4027       msg = vat_json_array_add (msg_array);
4028       vat_json_init_object (msg);
4029       vat_json_object_add_uint (msg, "vrf_id",
4030                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4031       counter_array = vat_json_object_add (msg, "c");
4032       vat_json_init_array (counter_array);
4033       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4034         {
4035           counter = vat_json_array_add (counter_array);
4036           vat_json_init_object (counter);
4037           c6 = &vam->ip6_fib_counters[i][j];
4038           vat_json_object_add_ip6 (counter, "address", c6->address);
4039           vat_json_object_add_uint (counter, "address_length",
4040                                     c6->address_length);
4041           vat_json_object_add_uint (counter, "packets", c6->packets);
4042           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4043         }
4044     }
4045
4046   vat_json_print (vam->ofp, &node);
4047   vat_json_free (&node);
4048
4049   return 0;
4050 }
4051
4052 int
4053 exec (vat_main_t * vam)
4054 {
4055   api_main_t *am = &api_main;
4056   vl_api_cli_request_t *mp;
4057   f64 timeout;
4058   void *oldheap;
4059   u8 *cmd = 0;
4060   unformat_input_t *i = vam->input;
4061
4062   if (vec_len (i->buffer) == 0)
4063     return -1;
4064
4065   if (vam->exec_mode == 0 && unformat (i, "mode"))
4066     {
4067       vam->exec_mode = 1;
4068       return 0;
4069     }
4070   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4071     {
4072       vam->exec_mode = 0;
4073       return 0;
4074     }
4075
4076
4077   M (CLI_REQUEST, cli_request);
4078
4079   /*
4080    * Copy cmd into shared memory.
4081    * In order for the CLI command to work, it
4082    * must be a vector ending in \n, not a C-string ending
4083    * in \n\0.
4084    */
4085   pthread_mutex_lock (&am->vlib_rp->mutex);
4086   oldheap = svm_push_data_heap (am->vlib_rp);
4087
4088   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4089   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4090
4091   svm_pop_heap (oldheap);
4092   pthread_mutex_unlock (&am->vlib_rp->mutex);
4093
4094   mp->cmd_in_shmem = (u64) cmd;
4095   S;
4096   timeout = vat_time_now (vam) + 10.0;
4097
4098   while (vat_time_now (vam) < timeout)
4099     {
4100       if (vam->result_ready == 1)
4101         {
4102           u8 *free_me;
4103           if (vam->shmem_result != NULL)
4104             fformat (vam->ofp, "%s", vam->shmem_result);
4105           pthread_mutex_lock (&am->vlib_rp->mutex);
4106           oldheap = svm_push_data_heap (am->vlib_rp);
4107
4108           free_me = (u8 *) vam->shmem_result;
4109           vec_free (free_me);
4110
4111           svm_pop_heap (oldheap);
4112           pthread_mutex_unlock (&am->vlib_rp->mutex);
4113           return 0;
4114         }
4115     }
4116   return -99;
4117 }
4118
4119 /*
4120  * Future replacement of exec() that passes CLI buffers directly in
4121  * the API messages instead of an additional shared memory area.
4122  */
4123 static int
4124 exec_inband (vat_main_t * vam)
4125 {
4126   vl_api_cli_inband_t *mp;
4127   f64 timeout;
4128   unformat_input_t *i = vam->input;
4129
4130   if (vec_len (i->buffer) == 0)
4131     return -1;
4132
4133   if (vam->exec_mode == 0 && unformat (i, "mode"))
4134     {
4135       vam->exec_mode = 1;
4136       return 0;
4137     }
4138   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4139     {
4140       vam->exec_mode = 0;
4141       return 0;
4142     }
4143
4144   /*
4145    * In order for the CLI command to work, it
4146    * must be a vector ending in \n, not a C-string ending
4147    * in \n\0.
4148    */
4149   u32 len = vec_len (vam->input->buffer);
4150   M2 (CLI_INBAND, cli_inband, len);
4151   clib_memcpy (mp->cmd, vam->input->buffer, len);
4152   mp->length = htonl (len);
4153
4154   S;
4155   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4156 }
4157
4158 static int
4159 api_create_loopback (vat_main_t * vam)
4160 {
4161   unformat_input_t *i = vam->input;
4162   vl_api_create_loopback_t *mp;
4163   f64 timeout;
4164   u8 mac_address[6];
4165   u8 mac_set = 0;
4166
4167   memset (mac_address, 0, sizeof (mac_address));
4168
4169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4170     {
4171       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4172         mac_set = 1;
4173       else
4174         break;
4175     }
4176
4177   /* Construct the API message */
4178   M (CREATE_LOOPBACK, create_loopback);
4179   if (mac_set)
4180     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4181
4182   S;
4183   W;
4184 }
4185
4186 static int
4187 api_delete_loopback (vat_main_t * vam)
4188 {
4189   unformat_input_t *i = vam->input;
4190   vl_api_delete_loopback_t *mp;
4191   f64 timeout;
4192   u32 sw_if_index = ~0;
4193
4194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4195     {
4196       if (unformat (i, "sw_if_index %d", &sw_if_index))
4197         ;
4198       else
4199         break;
4200     }
4201
4202   if (sw_if_index == ~0)
4203     {
4204       errmsg ("missing sw_if_index\n");
4205       return -99;
4206     }
4207
4208   /* Construct the API message */
4209   M (DELETE_LOOPBACK, delete_loopback);
4210   mp->sw_if_index = ntohl (sw_if_index);
4211
4212   S;
4213   W;
4214 }
4215
4216 static int
4217 api_want_stats (vat_main_t * vam)
4218 {
4219   unformat_input_t *i = vam->input;
4220   vl_api_want_stats_t *mp;
4221   f64 timeout;
4222   int enable = -1;
4223
4224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4225     {
4226       if (unformat (i, "enable"))
4227         enable = 1;
4228       else if (unformat (i, "disable"))
4229         enable = 0;
4230       else
4231         break;
4232     }
4233
4234   if (enable == -1)
4235     {
4236       errmsg ("missing enable|disable\n");
4237       return -99;
4238     }
4239
4240   M (WANT_STATS, want_stats);
4241   mp->enable_disable = enable;
4242
4243   S;
4244   W;
4245 }
4246
4247 static int
4248 api_want_interface_events (vat_main_t * vam)
4249 {
4250   unformat_input_t *i = vam->input;
4251   vl_api_want_interface_events_t *mp;
4252   f64 timeout;
4253   int enable = -1;
4254
4255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4256     {
4257       if (unformat (i, "enable"))
4258         enable = 1;
4259       else if (unformat (i, "disable"))
4260         enable = 0;
4261       else
4262         break;
4263     }
4264
4265   if (enable == -1)
4266     {
4267       errmsg ("missing enable|disable\n");
4268       return -99;
4269     }
4270
4271   M (WANT_INTERFACE_EVENTS, want_interface_events);
4272   mp->enable_disable = enable;
4273
4274   vam->interface_event_display = enable;
4275
4276   S;
4277   W;
4278 }
4279
4280
4281 /* Note: non-static, called once to set up the initial intfc table */
4282 int
4283 api_sw_interface_dump (vat_main_t * vam)
4284 {
4285   vl_api_sw_interface_dump_t *mp;
4286   f64 timeout;
4287   hash_pair_t *p;
4288   name_sort_t *nses = 0, *ns;
4289   sw_interface_subif_t *sub = NULL;
4290
4291   /* Toss the old name table */
4292   /* *INDENT-OFF* */
4293   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4294   ({
4295     vec_add2 (nses, ns, 1);
4296     ns->name = (u8 *)(p->key);
4297     ns->value = (u32) p->value[0];
4298   }));
4299   /* *INDENT-ON* */
4300
4301   hash_free (vam->sw_if_index_by_interface_name);
4302
4303   vec_foreach (ns, nses) vec_free (ns->name);
4304
4305   vec_free (nses);
4306
4307   vec_foreach (sub, vam->sw_if_subif_table)
4308   {
4309     vec_free (sub->interface_name);
4310   }
4311   vec_free (vam->sw_if_subif_table);
4312
4313   /* recreate the interface name hash table */
4314   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4315
4316   /* Get list of ethernets */
4317   M (SW_INTERFACE_DUMP, sw_interface_dump);
4318   mp->name_filter_valid = 1;
4319   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4320   S;
4321
4322   /* and local / loopback interfaces */
4323   M (SW_INTERFACE_DUMP, sw_interface_dump);
4324   mp->name_filter_valid = 1;
4325   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4326   S;
4327
4328
4329   /* and vxlan-gpe tunnel interfaces */
4330   M (SW_INTERFACE_DUMP, sw_interface_dump);
4331   mp->name_filter_valid = 1;
4332   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4333            sizeof (mp->name_filter) - 1);
4334   S;
4335
4336   /* and vxlan tunnel interfaces */
4337   M (SW_INTERFACE_DUMP, sw_interface_dump);
4338   mp->name_filter_valid = 1;
4339   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4340   S;
4341
4342   /* and host (af_packet) interfaces */
4343   M (SW_INTERFACE_DUMP, sw_interface_dump);
4344   mp->name_filter_valid = 1;
4345   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4346   S;
4347
4348   /* and l2tpv3 tunnel interfaces */
4349   M (SW_INTERFACE_DUMP, sw_interface_dump);
4350   mp->name_filter_valid = 1;
4351   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4352            sizeof (mp->name_filter) - 1);
4353   S;
4354
4355   /* and GRE tunnel interfaces */
4356   M (SW_INTERFACE_DUMP, sw_interface_dump);
4357   mp->name_filter_valid = 1;
4358   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4359   S;
4360
4361   /* and LISP-GPE interfaces */
4362   M (SW_INTERFACE_DUMP, sw_interface_dump);
4363   mp->name_filter_valid = 1;
4364   strncpy ((char *) mp->name_filter, "lisp_gpe",
4365            sizeof (mp->name_filter) - 1);
4366   S;
4367
4368   /* Use a control ping for synchronization */
4369   {
4370     vl_api_control_ping_t *mp;
4371     M (CONTROL_PING, control_ping);
4372     S;
4373   }
4374   W;
4375 }
4376
4377 static int
4378 api_sw_interface_set_flags (vat_main_t * vam)
4379 {
4380   unformat_input_t *i = vam->input;
4381   vl_api_sw_interface_set_flags_t *mp;
4382   f64 timeout;
4383   u32 sw_if_index;
4384   u8 sw_if_index_set = 0;
4385   u8 admin_up = 0, link_up = 0;
4386
4387   /* Parse args required to build the message */
4388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4389     {
4390       if (unformat (i, "admin-up"))
4391         admin_up = 1;
4392       else if (unformat (i, "admin-down"))
4393         admin_up = 0;
4394       else if (unformat (i, "link-up"))
4395         link_up = 1;
4396       else if (unformat (i, "link-down"))
4397         link_up = 0;
4398       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4399         sw_if_index_set = 1;
4400       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4401         sw_if_index_set = 1;
4402       else
4403         break;
4404     }
4405
4406   if (sw_if_index_set == 0)
4407     {
4408       errmsg ("missing interface name or sw_if_index\n");
4409       return -99;
4410     }
4411
4412   /* Construct the API message */
4413   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4414   mp->sw_if_index = ntohl (sw_if_index);
4415   mp->admin_up_down = admin_up;
4416   mp->link_up_down = link_up;
4417
4418   /* send it... */
4419   S;
4420
4421   /* Wait for a reply, return the good/bad news... */
4422   W;
4423 }
4424
4425 static int
4426 api_sw_interface_clear_stats (vat_main_t * vam)
4427 {
4428   unformat_input_t *i = vam->input;
4429   vl_api_sw_interface_clear_stats_t *mp;
4430   f64 timeout;
4431   u32 sw_if_index;
4432   u8 sw_if_index_set = 0;
4433
4434   /* Parse args required to build the message */
4435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4436     {
4437       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4438         sw_if_index_set = 1;
4439       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4440         sw_if_index_set = 1;
4441       else
4442         break;
4443     }
4444
4445   /* Construct the API message */
4446   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4447
4448   if (sw_if_index_set == 1)
4449     mp->sw_if_index = ntohl (sw_if_index);
4450   else
4451     mp->sw_if_index = ~0;
4452
4453   /* send it... */
4454   S;
4455
4456   /* Wait for a reply, return the good/bad news... */
4457   W;
4458 }
4459
4460 static int
4461 api_sw_interface_add_del_address (vat_main_t * vam)
4462 {
4463   unformat_input_t *i = vam->input;
4464   vl_api_sw_interface_add_del_address_t *mp;
4465   f64 timeout;
4466   u32 sw_if_index;
4467   u8 sw_if_index_set = 0;
4468   u8 is_add = 1, del_all = 0;
4469   u32 address_length = 0;
4470   u8 v4_address_set = 0;
4471   u8 v6_address_set = 0;
4472   ip4_address_t v4address;
4473   ip6_address_t v6address;
4474
4475   /* Parse args required to build the message */
4476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4477     {
4478       if (unformat (i, "del-all"))
4479         del_all = 1;
4480       else if (unformat (i, "del"))
4481         is_add = 0;
4482       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4483         sw_if_index_set = 1;
4484       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4485         sw_if_index_set = 1;
4486       else if (unformat (i, "%U/%d",
4487                          unformat_ip4_address, &v4address, &address_length))
4488         v4_address_set = 1;
4489       else if (unformat (i, "%U/%d",
4490                          unformat_ip6_address, &v6address, &address_length))
4491         v6_address_set = 1;
4492       else
4493         break;
4494     }
4495
4496   if (sw_if_index_set == 0)
4497     {
4498       errmsg ("missing interface name or sw_if_index\n");
4499       return -99;
4500     }
4501   if (v4_address_set && v6_address_set)
4502     {
4503       errmsg ("both v4 and v6 addresses set\n");
4504       return -99;
4505     }
4506   if (!v4_address_set && !v6_address_set && !del_all)
4507     {
4508       errmsg ("no addresses set\n");
4509       return -99;
4510     }
4511
4512   /* Construct the API message */
4513   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4514
4515   mp->sw_if_index = ntohl (sw_if_index);
4516   mp->is_add = is_add;
4517   mp->del_all = del_all;
4518   if (v6_address_set)
4519     {
4520       mp->is_ipv6 = 1;
4521       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4522     }
4523   else
4524     {
4525       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4526     }
4527   mp->address_length = address_length;
4528
4529   /* send it... */
4530   S;
4531
4532   /* Wait for a reply, return good/bad news  */
4533   W;
4534 }
4535
4536 static int
4537 api_sw_interface_set_table (vat_main_t * vam)
4538 {
4539   unformat_input_t *i = vam->input;
4540   vl_api_sw_interface_set_table_t *mp;
4541   f64 timeout;
4542   u32 sw_if_index, vrf_id = 0;
4543   u8 sw_if_index_set = 0;
4544   u8 is_ipv6 = 0;
4545
4546   /* Parse args required to build the message */
4547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4548     {
4549       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4550         sw_if_index_set = 1;
4551       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4552         sw_if_index_set = 1;
4553       else if (unformat (i, "vrf %d", &vrf_id))
4554         ;
4555       else if (unformat (i, "ipv6"))
4556         is_ipv6 = 1;
4557       else
4558         break;
4559     }
4560
4561   if (sw_if_index_set == 0)
4562     {
4563       errmsg ("missing interface name or sw_if_index\n");
4564       return -99;
4565     }
4566
4567   /* Construct the API message */
4568   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4569
4570   mp->sw_if_index = ntohl (sw_if_index);
4571   mp->is_ipv6 = is_ipv6;
4572   mp->vrf_id = ntohl (vrf_id);
4573
4574   /* send it... */
4575   S;
4576
4577   /* Wait for a reply... */
4578   W;
4579 }
4580
4581 static int
4582 api_sw_interface_set_vpath (vat_main_t * vam)
4583 {
4584   unformat_input_t *i = vam->input;
4585   vl_api_sw_interface_set_vpath_t *mp;
4586   f64 timeout;
4587   u32 sw_if_index = 0;
4588   u8 sw_if_index_set = 0;
4589   u8 is_enable = 0;
4590
4591   /* Parse args required to build the message */
4592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4593     {
4594       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4595         sw_if_index_set = 1;
4596       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4597         sw_if_index_set = 1;
4598       else if (unformat (i, "enable"))
4599         is_enable = 1;
4600       else if (unformat (i, "disable"))
4601         is_enable = 0;
4602       else
4603         break;
4604     }
4605
4606   if (sw_if_index_set == 0)
4607     {
4608       errmsg ("missing interface name or sw_if_index\n");
4609       return -99;
4610     }
4611
4612   /* Construct the API message */
4613   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4614
4615   mp->sw_if_index = ntohl (sw_if_index);
4616   mp->enable = is_enable;
4617
4618   /* send it... */
4619   S;
4620
4621   /* Wait for a reply... */
4622   W;
4623 }
4624
4625 static int
4626 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4627 {
4628   unformat_input_t *i = vam->input;
4629   vl_api_sw_interface_set_l2_xconnect_t *mp;
4630   f64 timeout;
4631   u32 rx_sw_if_index;
4632   u8 rx_sw_if_index_set = 0;
4633   u32 tx_sw_if_index;
4634   u8 tx_sw_if_index_set = 0;
4635   u8 enable = 1;
4636
4637   /* Parse args required to build the message */
4638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4639     {
4640       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4641         rx_sw_if_index_set = 1;
4642       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4643         tx_sw_if_index_set = 1;
4644       else if (unformat (i, "rx"))
4645         {
4646           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4647             {
4648               if (unformat (i, "%U", unformat_sw_if_index, vam,
4649                             &rx_sw_if_index))
4650                 rx_sw_if_index_set = 1;
4651             }
4652           else
4653             break;
4654         }
4655       else if (unformat (i, "tx"))
4656         {
4657           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4658             {
4659               if (unformat (i, "%U", unformat_sw_if_index, vam,
4660                             &tx_sw_if_index))
4661                 tx_sw_if_index_set = 1;
4662             }
4663           else
4664             break;
4665         }
4666       else if (unformat (i, "enable"))
4667         enable = 1;
4668       else if (unformat (i, "disable"))
4669         enable = 0;
4670       else
4671         break;
4672     }
4673
4674   if (rx_sw_if_index_set == 0)
4675     {
4676       errmsg ("missing rx interface name or rx_sw_if_index\n");
4677       return -99;
4678     }
4679
4680   if (enable && (tx_sw_if_index_set == 0))
4681     {
4682       errmsg ("missing tx interface name or tx_sw_if_index\n");
4683       return -99;
4684     }
4685
4686   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4687
4688   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4689   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4690   mp->enable = enable;
4691
4692   S;
4693   W;
4694   /* NOTREACHED */
4695   return 0;
4696 }
4697
4698 static int
4699 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4700 {
4701   unformat_input_t *i = vam->input;
4702   vl_api_sw_interface_set_l2_bridge_t *mp;
4703   f64 timeout;
4704   u32 rx_sw_if_index;
4705   u8 rx_sw_if_index_set = 0;
4706   u32 bd_id;
4707   u8 bd_id_set = 0;
4708   u8 bvi = 0;
4709   u32 shg = 0;
4710   u8 enable = 1;
4711
4712   /* Parse args required to build the message */
4713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4714     {
4715       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4716         rx_sw_if_index_set = 1;
4717       else if (unformat (i, "bd_id %d", &bd_id))
4718         bd_id_set = 1;
4719       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
4720         rx_sw_if_index_set = 1;
4721       else if (unformat (i, "shg %d", &shg))
4722         ;
4723       else if (unformat (i, "bvi"))
4724         bvi = 1;
4725       else if (unformat (i, "enable"))
4726         enable = 1;
4727       else if (unformat (i, "disable"))
4728         enable = 0;
4729       else
4730         break;
4731     }
4732
4733   if (rx_sw_if_index_set == 0)
4734     {
4735       errmsg ("missing rx interface name or sw_if_index\n");
4736       return -99;
4737     }
4738
4739   if (enable && (bd_id_set == 0))
4740     {
4741       errmsg ("missing bridge domain\n");
4742       return -99;
4743     }
4744
4745   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
4746
4747   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4748   mp->bd_id = ntohl (bd_id);
4749   mp->shg = (u8) shg;
4750   mp->bvi = bvi;
4751   mp->enable = enable;
4752
4753   S;
4754   W;
4755   /* NOTREACHED */
4756   return 0;
4757 }
4758
4759 static int
4760 api_bridge_domain_dump (vat_main_t * vam)
4761 {
4762   unformat_input_t *i = vam->input;
4763   vl_api_bridge_domain_dump_t *mp;
4764   f64 timeout;
4765   u32 bd_id = ~0;
4766
4767   /* Parse args required to build the message */
4768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4769     {
4770       if (unformat (i, "bd_id %d", &bd_id))
4771         ;
4772       else
4773         break;
4774     }
4775
4776   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
4777   mp->bd_id = ntohl (bd_id);
4778   S;
4779
4780   /* Use a control ping for synchronization */
4781   {
4782     vl_api_control_ping_t *mp;
4783     M (CONTROL_PING, control_ping);
4784     S;
4785   }
4786
4787   W;
4788   /* NOTREACHED */
4789   return 0;
4790 }
4791
4792 static int
4793 api_bridge_domain_add_del (vat_main_t * vam)
4794 {
4795   unformat_input_t *i = vam->input;
4796   vl_api_bridge_domain_add_del_t *mp;
4797   f64 timeout;
4798   u32 bd_id = ~0;
4799   u8 is_add = 1;
4800   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4801
4802   /* Parse args required to build the message */
4803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4804     {
4805       if (unformat (i, "bd_id %d", &bd_id))
4806         ;
4807       else if (unformat (i, "flood %d", &flood))
4808         ;
4809       else if (unformat (i, "uu-flood %d", &uu_flood))
4810         ;
4811       else if (unformat (i, "forward %d", &forward))
4812         ;
4813       else if (unformat (i, "learn %d", &learn))
4814         ;
4815       else if (unformat (i, "arp-term %d", &arp_term))
4816         ;
4817       else if (unformat (i, "del"))
4818         {
4819           is_add = 0;
4820           flood = uu_flood = forward = learn = 0;
4821         }
4822       else
4823         break;
4824     }
4825
4826   if (bd_id == ~0)
4827     {
4828       errmsg ("missing bridge domain\n");
4829       return -99;
4830     }
4831
4832   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
4833
4834   mp->bd_id = ntohl (bd_id);
4835   mp->flood = flood;
4836   mp->uu_flood = uu_flood;
4837   mp->forward = forward;
4838   mp->learn = learn;
4839   mp->arp_term = arp_term;
4840   mp->is_add = is_add;
4841
4842   S;
4843   W;
4844   /* NOTREACHED */
4845   return 0;
4846 }
4847
4848 static int
4849 api_l2fib_add_del (vat_main_t * vam)
4850 {
4851   unformat_input_t *i = vam->input;
4852   vl_api_l2fib_add_del_t *mp;
4853   f64 timeout;
4854   u64 mac = 0;
4855   u8 mac_set = 0;
4856   u32 bd_id;
4857   u8 bd_id_set = 0;
4858   u32 sw_if_index;
4859   u8 sw_if_index_set = 0;
4860   u8 is_add = 1;
4861   u8 static_mac = 0;
4862   u8 filter_mac = 0;
4863   u8 bvi_mac = 0;
4864   int count = 1;
4865   f64 before = 0;
4866   int j;
4867
4868   /* Parse args required to build the message */
4869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4870     {
4871       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
4872         mac_set = 1;
4873       else if (unformat (i, "bd_id %d", &bd_id))
4874         bd_id_set = 1;
4875       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4876         sw_if_index_set = 1;
4877       else if (unformat (i, "sw_if"))
4878         {
4879           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4880             {
4881               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4882                 sw_if_index_set = 1;
4883             }
4884           else
4885             break;
4886         }
4887       else if (unformat (i, "static"))
4888         static_mac = 1;
4889       else if (unformat (i, "filter"))
4890         {
4891           filter_mac = 1;
4892           static_mac = 1;
4893         }
4894       else if (unformat (i, "bvi"))
4895         {
4896           bvi_mac = 1;
4897           static_mac = 1;
4898         }
4899       else if (unformat (i, "del"))
4900         is_add = 0;
4901       else if (unformat (i, "count %d", &count))
4902         ;
4903       else
4904         break;
4905     }
4906
4907   if (mac_set == 0)
4908     {
4909       errmsg ("missing mac address\n");
4910       return -99;
4911     }
4912
4913   if (bd_id_set == 0)
4914     {
4915       errmsg ("missing bridge domain\n");
4916       return -99;
4917     }
4918
4919   if (is_add && (sw_if_index_set == 0))
4920     {
4921       errmsg ("missing interface name or sw_if_index\n");
4922       return -99;
4923     }
4924
4925   if (count > 1)
4926     {
4927       /* Turn on async mode */
4928       vam->async_mode = 1;
4929       vam->async_errors = 0;
4930       before = vat_time_now (vam);
4931     }
4932
4933   for (j = 0; j < count; j++)
4934     {
4935       M (L2FIB_ADD_DEL, l2fib_add_del);
4936
4937       mp->mac = mac;
4938       mp->bd_id = ntohl (bd_id);
4939       mp->is_add = is_add;
4940
4941       if (is_add)
4942         {
4943           mp->sw_if_index = ntohl (sw_if_index);
4944           mp->static_mac = static_mac;
4945           mp->filter_mac = filter_mac;
4946           mp->bvi_mac = bvi_mac;
4947         }
4948       increment_mac_address (&mac);
4949       /* send it... */
4950       S;
4951     }
4952
4953   if (count > 1)
4954     {
4955       vl_api_control_ping_t *mp;
4956       f64 after;
4957
4958       /* Shut off async mode */
4959       vam->async_mode = 0;
4960
4961       M (CONTROL_PING, control_ping);
4962       S;
4963
4964       timeout = vat_time_now (vam) + 1.0;
4965       while (vat_time_now (vam) < timeout)
4966         if (vam->result_ready == 1)
4967           goto out;
4968       vam->retval = -99;
4969
4970     out:
4971       if (vam->retval == -99)
4972         errmsg ("timeout\n");
4973
4974       if (vam->async_errors > 0)
4975         {
4976           errmsg ("%d asynchronous errors\n", vam->async_errors);
4977           vam->retval = -98;
4978         }
4979       vam->async_errors = 0;
4980       after = vat_time_now (vam);
4981
4982       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4983                count, after - before, count / (after - before));
4984     }
4985   else
4986     {
4987       /* Wait for a reply... */
4988       W;
4989     }
4990   /* Return the good/bad news */
4991   return (vam->retval);
4992 }
4993
4994 static int
4995 api_l2_flags (vat_main_t * vam)
4996 {
4997   unformat_input_t *i = vam->input;
4998   vl_api_l2_flags_t *mp;
4999   f64 timeout;
5000   u32 sw_if_index;
5001   u32 feature_bitmap = 0;
5002   u8 sw_if_index_set = 0;
5003
5004   /* Parse args required to build the message */
5005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5006     {
5007       if (unformat (i, "sw_if_index %d", &sw_if_index))
5008         sw_if_index_set = 1;
5009       else if (unformat (i, "sw_if"))
5010         {
5011           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5012             {
5013               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5014                 sw_if_index_set = 1;
5015             }
5016           else
5017             break;
5018         }
5019       else if (unformat (i, "learn"))
5020         feature_bitmap |= L2INPUT_FEAT_LEARN;
5021       else if (unformat (i, "forward"))
5022         feature_bitmap |= L2INPUT_FEAT_FWD;
5023       else if (unformat (i, "flood"))
5024         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5025       else if (unformat (i, "uu-flood"))
5026         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5027       else
5028         break;
5029     }
5030
5031   if (sw_if_index_set == 0)
5032     {
5033       errmsg ("missing interface name or sw_if_index\n");
5034       return -99;
5035     }
5036
5037   M (L2_FLAGS, l2_flags);
5038
5039   mp->sw_if_index = ntohl (sw_if_index);
5040   mp->feature_bitmap = ntohl (feature_bitmap);
5041
5042   S;
5043   W;
5044   /* NOTREACHED */
5045   return 0;
5046 }
5047
5048 static int
5049 api_bridge_flags (vat_main_t * vam)
5050 {
5051   unformat_input_t *i = vam->input;
5052   vl_api_bridge_flags_t *mp;
5053   f64 timeout;
5054   u32 bd_id;
5055   u8 bd_id_set = 0;
5056   u8 is_set = 1;
5057   u32 flags = 0;
5058
5059   /* Parse args required to build the message */
5060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5061     {
5062       if (unformat (i, "bd_id %d", &bd_id))
5063         bd_id_set = 1;
5064       else if (unformat (i, "learn"))
5065         flags |= L2_LEARN;
5066       else if (unformat (i, "forward"))
5067         flags |= L2_FWD;
5068       else if (unformat (i, "flood"))
5069         flags |= L2_FLOOD;
5070       else if (unformat (i, "uu-flood"))
5071         flags |= L2_UU_FLOOD;
5072       else if (unformat (i, "arp-term"))
5073         flags |= L2_ARP_TERM;
5074       else if (unformat (i, "off"))
5075         is_set = 0;
5076       else if (unformat (i, "disable"))
5077         is_set = 0;
5078       else
5079         break;
5080     }
5081
5082   if (bd_id_set == 0)
5083     {
5084       errmsg ("missing bridge domain\n");
5085       return -99;
5086     }
5087
5088   M (BRIDGE_FLAGS, bridge_flags);
5089
5090   mp->bd_id = ntohl (bd_id);
5091   mp->feature_bitmap = ntohl (flags);
5092   mp->is_set = is_set;
5093
5094   S;
5095   W;
5096   /* NOTREACHED */
5097   return 0;
5098 }
5099
5100 static int
5101 api_bd_ip_mac_add_del (vat_main_t * vam)
5102 {
5103   unformat_input_t *i = vam->input;
5104   vl_api_bd_ip_mac_add_del_t *mp;
5105   f64 timeout;
5106   u32 bd_id;
5107   u8 is_ipv6 = 0;
5108   u8 is_add = 1;
5109   u8 bd_id_set = 0;
5110   u8 ip_set = 0;
5111   u8 mac_set = 0;
5112   ip4_address_t v4addr;
5113   ip6_address_t v6addr;
5114   u8 macaddr[6];
5115
5116
5117   /* Parse args required to build the message */
5118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5119     {
5120       if (unformat (i, "bd_id %d", &bd_id))
5121         {
5122           bd_id_set++;
5123         }
5124       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5125         {
5126           ip_set++;
5127         }
5128       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5129         {
5130           ip_set++;
5131           is_ipv6++;
5132         }
5133       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5134         {
5135           mac_set++;
5136         }
5137       else if (unformat (i, "del"))
5138         is_add = 0;
5139       else
5140         break;
5141     }
5142
5143   if (bd_id_set == 0)
5144     {
5145       errmsg ("missing bridge domain\n");
5146       return -99;
5147     }
5148   else if (ip_set == 0)
5149     {
5150       errmsg ("missing IP address\n");
5151       return -99;
5152     }
5153   else if (mac_set == 0)
5154     {
5155       errmsg ("missing MAC address\n");
5156       return -99;
5157     }
5158
5159   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5160
5161   mp->bd_id = ntohl (bd_id);
5162   mp->is_ipv6 = is_ipv6;
5163   mp->is_add = is_add;
5164   if (is_ipv6)
5165     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5166   else
5167     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5168   clib_memcpy (mp->mac_address, macaddr, 6);
5169   S;
5170   W;
5171   /* NOTREACHED */
5172   return 0;
5173 }
5174
5175 static int
5176 api_tap_connect (vat_main_t * vam)
5177 {
5178   unformat_input_t *i = vam->input;
5179   vl_api_tap_connect_t *mp;
5180   f64 timeout;
5181   u8 mac_address[6];
5182   u8 random_mac = 1;
5183   u8 name_set = 0;
5184   u8 *tap_name;
5185
5186   memset (mac_address, 0, sizeof (mac_address));
5187
5188   /* Parse args required to build the message */
5189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5190     {
5191       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5192         {
5193           random_mac = 0;
5194         }
5195       else if (unformat (i, "random-mac"))
5196         random_mac = 1;
5197       else if (unformat (i, "tapname %s", &tap_name))
5198         name_set = 1;
5199       else
5200         break;
5201     }
5202
5203   if (name_set == 0)
5204     {
5205       errmsg ("missing tap name\n");
5206       return -99;
5207     }
5208   if (vec_len (tap_name) > 63)
5209     {
5210       errmsg ("tap name too long\n");
5211     }
5212   vec_add1 (tap_name, 0);
5213
5214   /* Construct the API message */
5215   M (TAP_CONNECT, tap_connect);
5216
5217   mp->use_random_mac = random_mac;
5218   clib_memcpy (mp->mac_address, mac_address, 6);
5219   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5220   vec_free (tap_name);
5221
5222   /* send it... */
5223   S;
5224
5225   /* Wait for a reply... */
5226   W;
5227 }
5228
5229 static int
5230 api_tap_modify (vat_main_t * vam)
5231 {
5232   unformat_input_t *i = vam->input;
5233   vl_api_tap_modify_t *mp;
5234   f64 timeout;
5235   u8 mac_address[6];
5236   u8 random_mac = 1;
5237   u8 name_set = 0;
5238   u8 *tap_name;
5239   u32 sw_if_index = ~0;
5240   u8 sw_if_index_set = 0;
5241
5242   memset (mac_address, 0, sizeof (mac_address));
5243
5244   /* Parse args required to build the message */
5245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5246     {
5247       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5248         sw_if_index_set = 1;
5249       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5250         sw_if_index_set = 1;
5251       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5252         {
5253           random_mac = 0;
5254         }
5255       else if (unformat (i, "random-mac"))
5256         random_mac = 1;
5257       else if (unformat (i, "tapname %s", &tap_name))
5258         name_set = 1;
5259       else
5260         break;
5261     }
5262
5263   if (sw_if_index_set == 0)
5264     {
5265       errmsg ("missing vpp interface name");
5266       return -99;
5267     }
5268   if (name_set == 0)
5269     {
5270       errmsg ("missing tap name\n");
5271       return -99;
5272     }
5273   if (vec_len (tap_name) > 63)
5274     {
5275       errmsg ("tap name too long\n");
5276     }
5277   vec_add1 (tap_name, 0);
5278
5279   /* Construct the API message */
5280   M (TAP_MODIFY, tap_modify);
5281
5282   mp->use_random_mac = random_mac;
5283   mp->sw_if_index = ntohl (sw_if_index);
5284   clib_memcpy (mp->mac_address, mac_address, 6);
5285   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5286   vec_free (tap_name);
5287
5288   /* send it... */
5289   S;
5290
5291   /* Wait for a reply... */
5292   W;
5293 }
5294
5295 static int
5296 api_tap_delete (vat_main_t * vam)
5297 {
5298   unformat_input_t *i = vam->input;
5299   vl_api_tap_delete_t *mp;
5300   f64 timeout;
5301   u32 sw_if_index = ~0;
5302   u8 sw_if_index_set = 0;
5303
5304   /* Parse args required to build the message */
5305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5306     {
5307       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5308         sw_if_index_set = 1;
5309       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5310         sw_if_index_set = 1;
5311       else
5312         break;
5313     }
5314
5315   if (sw_if_index_set == 0)
5316     {
5317       errmsg ("missing vpp interface name");
5318       return -99;
5319     }
5320
5321   /* Construct the API message */
5322   M (TAP_DELETE, tap_delete);
5323
5324   mp->sw_if_index = ntohl (sw_if_index);
5325
5326   /* send it... */
5327   S;
5328
5329   /* Wait for a reply... */
5330   W;
5331 }
5332
5333 static int
5334 api_ip_add_del_route (vat_main_t * vam)
5335 {
5336   unformat_input_t *i = vam->input;
5337   vl_api_ip_add_del_route_t *mp;
5338   f64 timeout;
5339   u32 sw_if_index = ~0, vrf_id = 0;
5340   u8 sw_if_index_set = 0;
5341   u8 is_ipv6 = 0;
5342   u8 is_local = 0, is_drop = 0;
5343   u8 create_vrf_if_needed = 0;
5344   u8 is_add = 1;
5345   u8 next_hop_weight = 1;
5346   u8 not_last = 0;
5347   u8 is_multipath = 0;
5348   u8 address_set = 0;
5349   u8 address_length_set = 0;
5350   u32 lookup_in_vrf = 0;
5351   u32 resolve_attempts = 0;
5352   u32 dst_address_length = 0;
5353   u8 next_hop_set = 0;
5354   ip4_address_t v4_dst_address, v4_next_hop_address;
5355   ip6_address_t v6_dst_address, v6_next_hop_address;
5356   int count = 1;
5357   int j;
5358   f64 before = 0;
5359   u32 random_add_del = 0;
5360   u32 *random_vector = 0;
5361   uword *random_hash;
5362   u32 random_seed = 0xdeaddabe;
5363   u32 classify_table_index = ~0;
5364   u8 is_classify = 0;
5365
5366   /* Parse args required to build the message */
5367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5368     {
5369       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5370         sw_if_index_set = 1;
5371       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5372         sw_if_index_set = 1;
5373       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5374         {
5375           address_set = 1;
5376           is_ipv6 = 0;
5377         }
5378       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5379         {
5380           address_set = 1;
5381           is_ipv6 = 1;
5382         }
5383       else if (unformat (i, "/%d", &dst_address_length))
5384         {
5385           address_length_set = 1;
5386         }
5387
5388       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5389                                          &v4_next_hop_address))
5390         {
5391           next_hop_set = 1;
5392         }
5393       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5394                                          &v6_next_hop_address))
5395         {
5396           next_hop_set = 1;
5397         }
5398       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5399         ;
5400       else if (unformat (i, "weight %d", &next_hop_weight))
5401         ;
5402       else if (unformat (i, "drop"))
5403         {
5404           is_drop = 1;
5405         }
5406       else if (unformat (i, "local"))
5407         {
5408           is_local = 1;
5409         }
5410       else if (unformat (i, "classify %d", &classify_table_index))
5411         {
5412           is_classify = 1;
5413         }
5414       else if (unformat (i, "del"))
5415         is_add = 0;
5416       else if (unformat (i, "add"))
5417         is_add = 1;
5418       else if (unformat (i, "not-last"))
5419         not_last = 1;
5420       else if (unformat (i, "multipath"))
5421         is_multipath = 1;
5422       else if (unformat (i, "vrf %d", &vrf_id))
5423         ;
5424       else if (unformat (i, "create-vrf"))
5425         create_vrf_if_needed = 1;
5426       else if (unformat (i, "count %d", &count))
5427         ;
5428       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5429         ;
5430       else if (unformat (i, "random"))
5431         random_add_del = 1;
5432       else if (unformat (i, "seed %d", &random_seed))
5433         ;
5434       else
5435         {
5436           clib_warning ("parse error '%U'", format_unformat_error, i);
5437           return -99;
5438         }
5439     }
5440
5441   if (resolve_attempts > 0 && sw_if_index_set == 0)
5442     {
5443       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5444       return -99;
5445     }
5446
5447   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5448     {
5449       errmsg ("next hop / local / drop / classify not set\n");
5450       return -99;
5451     }
5452
5453   if (address_set == 0)
5454     {
5455       errmsg ("missing addresses\n");
5456       return -99;
5457     }
5458
5459   if (address_length_set == 0)
5460     {
5461       errmsg ("missing address length\n");
5462       return -99;
5463     }
5464
5465   /* Generate a pile of unique, random routes */
5466   if (random_add_del)
5467     {
5468       u32 this_random_address;
5469       random_hash = hash_create (count, sizeof (uword));
5470
5471       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5472       for (j = 0; j <= count; j++)
5473         {
5474           do
5475             {
5476               this_random_address = random_u32 (&random_seed);
5477               this_random_address =
5478                 clib_host_to_net_u32 (this_random_address);
5479             }
5480           while (hash_get (random_hash, this_random_address));
5481           vec_add1 (random_vector, this_random_address);
5482           hash_set (random_hash, this_random_address, 1);
5483         }
5484       hash_free (random_hash);
5485       v4_dst_address.as_u32 = random_vector[0];
5486     }
5487
5488   if (count > 1)
5489     {
5490       /* Turn on async mode */
5491       vam->async_mode = 1;
5492       vam->async_errors = 0;
5493       before = vat_time_now (vam);
5494     }
5495
5496   for (j = 0; j < count; j++)
5497     {
5498       /* Construct the API message */
5499       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5500
5501       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5502       mp->vrf_id = ntohl (vrf_id);
5503       if (resolve_attempts > 0)
5504         {
5505           mp->resolve_attempts = ntohl (resolve_attempts);
5506           mp->resolve_if_needed = 1;
5507         }
5508       mp->create_vrf_if_needed = create_vrf_if_needed;
5509
5510       mp->is_add = is_add;
5511       mp->is_drop = is_drop;
5512       mp->is_ipv6 = is_ipv6;
5513       mp->is_local = is_local;
5514       mp->is_classify = is_classify;
5515       mp->is_multipath = is_multipath;
5516       mp->not_last = not_last;
5517       mp->next_hop_weight = next_hop_weight;
5518       mp->dst_address_length = dst_address_length;
5519       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5520       mp->classify_table_index = ntohl (classify_table_index);
5521
5522       if (is_ipv6)
5523         {
5524           clib_memcpy (mp->dst_address, &v6_dst_address,
5525                        sizeof (v6_dst_address));
5526           if (next_hop_set)
5527             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5528                          sizeof (v6_next_hop_address));
5529           increment_v6_address (&v6_dst_address);
5530         }
5531       else
5532         {
5533           clib_memcpy (mp->dst_address, &v4_dst_address,
5534                        sizeof (v4_dst_address));
5535           if (next_hop_set)
5536             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5537                          sizeof (v4_next_hop_address));
5538           if (random_add_del)
5539             v4_dst_address.as_u32 = random_vector[j + 1];
5540           else
5541             increment_v4_address (&v4_dst_address);
5542         }
5543       /* send it... */
5544       S;
5545     }
5546
5547   /* When testing multiple add/del ops, use a control-ping to sync */
5548   if (count > 1)
5549     {
5550       vl_api_control_ping_t *mp;
5551       f64 after;
5552
5553       /* Shut off async mode */
5554       vam->async_mode = 0;
5555
5556       M (CONTROL_PING, control_ping);
5557       S;
5558
5559       timeout = vat_time_now (vam) + 1.0;
5560       while (vat_time_now (vam) < timeout)
5561         if (vam->result_ready == 1)
5562           goto out;
5563       vam->retval = -99;
5564
5565     out:
5566       if (vam->retval == -99)
5567         errmsg ("timeout\n");
5568
5569       if (vam->async_errors > 0)
5570         {
5571           errmsg ("%d asynchronous errors\n", vam->async_errors);
5572           vam->retval = -98;
5573         }
5574       vam->async_errors = 0;
5575       after = vat_time_now (vam);
5576
5577       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5578                count, after - before, count / (after - before));
5579     }
5580   else
5581     {
5582       /* Wait for a reply... */
5583       W;
5584     }
5585
5586   /* Return the good/bad news */
5587   return (vam->retval);
5588 }
5589
5590 static int
5591 api_proxy_arp_add_del (vat_main_t * vam)
5592 {
5593   unformat_input_t *i = vam->input;
5594   vl_api_proxy_arp_add_del_t *mp;
5595   f64 timeout;
5596   u32 vrf_id = 0;
5597   u8 is_add = 1;
5598   ip4_address_t lo, hi;
5599   u8 range_set = 0;
5600
5601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5602     {
5603       if (unformat (i, "vrf %d", &vrf_id))
5604         ;
5605       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5606                          unformat_ip4_address, &hi))
5607         range_set = 1;
5608       else if (unformat (i, "del"))
5609         is_add = 0;
5610       else
5611         {
5612           clib_warning ("parse error '%U'", format_unformat_error, i);
5613           return -99;
5614         }
5615     }
5616
5617   if (range_set == 0)
5618     {
5619       errmsg ("address range not set\n");
5620       return -99;
5621     }
5622
5623   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5624
5625   mp->vrf_id = ntohl (vrf_id);
5626   mp->is_add = is_add;
5627   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5628   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5629
5630   S;
5631   W;
5632   /* NOTREACHED */
5633   return 0;
5634 }
5635
5636 static int
5637 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5638 {
5639   unformat_input_t *i = vam->input;
5640   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5641   f64 timeout;
5642   u32 sw_if_index;
5643   u8 enable = 1;
5644   u8 sw_if_index_set = 0;
5645
5646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5647     {
5648       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5649         sw_if_index_set = 1;
5650       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5651         sw_if_index_set = 1;
5652       else if (unformat (i, "enable"))
5653         enable = 1;
5654       else if (unformat (i, "disable"))
5655         enable = 0;
5656       else
5657         {
5658           clib_warning ("parse error '%U'", format_unformat_error, i);
5659           return -99;
5660         }
5661     }
5662
5663   if (sw_if_index_set == 0)
5664     {
5665       errmsg ("missing interface name or sw_if_index\n");
5666       return -99;
5667     }
5668
5669   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5670
5671   mp->sw_if_index = ntohl (sw_if_index);
5672   mp->enable_disable = enable;
5673
5674   S;
5675   W;
5676   /* NOTREACHED */
5677   return 0;
5678 }
5679
5680 static int
5681 api_mpls_add_del_decap (vat_main_t * vam)
5682 {
5683   unformat_input_t *i = vam->input;
5684   vl_api_mpls_add_del_decap_t *mp;
5685   f64 timeout;
5686   u32 rx_vrf_id = 0;
5687   u32 tx_vrf_id = 0;
5688   u32 label = 0;
5689   u8 is_add = 1;
5690   u8 s_bit = 1;
5691   u32 next_index = 1;
5692
5693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5694     {
5695       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5696         ;
5697       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5698         ;
5699       else if (unformat (i, "label %d", &label))
5700         ;
5701       else if (unformat (i, "next-index %d", &next_index))
5702         ;
5703       else if (unformat (i, "del"))
5704         is_add = 0;
5705       else if (unformat (i, "s-bit-clear"))
5706         s_bit = 0;
5707       else
5708         {
5709           clib_warning ("parse error '%U'", format_unformat_error, i);
5710           return -99;
5711         }
5712     }
5713
5714   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5715
5716   mp->rx_vrf_id = ntohl (rx_vrf_id);
5717   mp->tx_vrf_id = ntohl (tx_vrf_id);
5718   mp->label = ntohl (label);
5719   mp->next_index = ntohl (next_index);
5720   mp->s_bit = s_bit;
5721   mp->is_add = is_add;
5722
5723   S;
5724   W;
5725   /* NOTREACHED */
5726   return 0;
5727 }
5728
5729 static int
5730 api_mpls_add_del_encap (vat_main_t * vam)
5731 {
5732   unformat_input_t *i = vam->input;
5733   vl_api_mpls_add_del_encap_t *mp;
5734   f64 timeout;
5735   u32 vrf_id = 0;
5736   u32 *labels = 0;
5737   u32 label;
5738   ip4_address_t dst_address;
5739   u8 is_add = 1;
5740
5741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5742     {
5743       if (unformat (i, "vrf %d", &vrf_id))
5744         ;
5745       else if (unformat (i, "label %d", &label))
5746         vec_add1 (labels, ntohl (label));
5747       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5748         ;
5749       else if (unformat (i, "del"))
5750         is_add = 0;
5751       else
5752         {
5753           clib_warning ("parse error '%U'", format_unformat_error, i);
5754           return -99;
5755         }
5756     }
5757
5758   if (vec_len (labels) == 0)
5759     {
5760       errmsg ("missing encap label stack\n");
5761       return -99;
5762     }
5763
5764   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
5765       sizeof (u32) * vec_len (labels));
5766
5767   mp->vrf_id = ntohl (vrf_id);
5768   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5769   mp->is_add = is_add;
5770   mp->nlabels = vec_len (labels);
5771   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
5772
5773   vec_free (labels);
5774
5775   S;
5776   W;
5777   /* NOTREACHED */
5778   return 0;
5779 }
5780
5781 static int
5782 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
5783 {
5784   unformat_input_t *i = vam->input;
5785   vl_api_mpls_gre_add_del_tunnel_t *mp;
5786   f64 timeout;
5787   u32 inner_vrf_id = 0;
5788   u32 outer_vrf_id = 0;
5789   ip4_address_t src_address;
5790   ip4_address_t dst_address;
5791   ip4_address_t intfc_address;
5792   u32 tmp;
5793   u8 intfc_address_length = 0;
5794   u8 is_add = 1;
5795   u8 l2_only = 0;
5796
5797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5798     {
5799       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5800         ;
5801       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5802         ;
5803       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
5804         ;
5805       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5806         ;
5807       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5808                          &intfc_address, &tmp))
5809         intfc_address_length = tmp;
5810       else if (unformat (i, "l2-only"))
5811         l2_only = 1;
5812       else if (unformat (i, "del"))
5813         is_add = 0;
5814       else
5815         {
5816           clib_warning ("parse error '%U'", format_unformat_error, i);
5817           return -99;
5818         }
5819     }
5820
5821   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
5822
5823   mp->inner_vrf_id = ntohl (inner_vrf_id);
5824   mp->outer_vrf_id = ntohl (outer_vrf_id);
5825   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
5826   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5827   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
5828   mp->intfc_address_length = intfc_address_length;
5829   mp->l2_only = l2_only;
5830   mp->is_add = is_add;
5831
5832   S;
5833   W;
5834   /* NOTREACHED */
5835   return 0;
5836 }
5837
5838 static int
5839 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
5840 {
5841   unformat_input_t *i = vam->input;
5842   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
5843   f64 timeout;
5844   u32 inner_vrf_id = 0;
5845   ip4_address_t intfc_address;
5846   u8 dst_mac_address[6];
5847   int dst_set = 1;
5848   u32 tmp;
5849   u8 intfc_address_length = 0;
5850   u8 is_add = 1;
5851   u8 l2_only = 0;
5852   u32 tx_sw_if_index;
5853   int tx_sw_if_index_set = 0;
5854
5855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5856     {
5857       if (unformat (i, "vrf %d", &inner_vrf_id))
5858         ;
5859       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5860                          &intfc_address, &tmp))
5861         intfc_address_length = tmp;
5862       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
5863         tx_sw_if_index_set = 1;
5864       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5865         tx_sw_if_index_set = 1;
5866       else if (unformat (i, "dst %U", unformat_ethernet_address,
5867                          dst_mac_address))
5868         dst_set = 1;
5869       else if (unformat (i, "l2-only"))
5870         l2_only = 1;
5871       else if (unformat (i, "del"))
5872         is_add = 0;
5873       else
5874         {
5875           clib_warning ("parse error '%U'", format_unformat_error, i);
5876           return -99;
5877         }
5878     }
5879
5880   if (!dst_set)
5881     {
5882       errmsg ("dst (mac address) not set\n");
5883       return -99;
5884     }
5885   if (!tx_sw_if_index_set)
5886     {
5887       errmsg ("tx-intfc not set\n");
5888       return -99;
5889     }
5890
5891   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
5892
5893   mp->vrf_id = ntohl (inner_vrf_id);
5894   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
5895   mp->adj_address_length = intfc_address_length;
5896   clib_memcpy (mp->dst_mac_address, dst_mac_address,
5897                sizeof (dst_mac_address));
5898   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5899   mp->l2_only = l2_only;
5900   mp->is_add = is_add;
5901
5902   S;
5903   W;
5904   /* NOTREACHED */
5905   return 0;
5906 }
5907
5908 static int
5909 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
5910 {
5911   unformat_input_t *i = vam->input;
5912   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
5913   f64 timeout;
5914   u32 inner_vrf_id = 0;
5915   u32 outer_vrf_id = 0;
5916   ip4_address_t adj_address;
5917   int adj_address_set = 0;
5918   ip4_address_t next_hop_address;
5919   int next_hop_address_set = 0;
5920   u32 tmp;
5921   u8 adj_address_length = 0;
5922   u8 l2_only = 0;
5923   u8 is_add = 1;
5924   u32 resolve_attempts = 5;
5925   u8 resolve_if_needed = 1;
5926
5927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5928     {
5929       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5930         ;
5931       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5932         ;
5933       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5934                          &adj_address, &tmp))
5935         {
5936           adj_address_length = tmp;
5937           adj_address_set = 1;
5938         }
5939       else if (unformat (i, "next-hop %U", unformat_ip4_address,
5940                          &next_hop_address))
5941         next_hop_address_set = 1;
5942       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5943         ;
5944       else if (unformat (i, "resolve-if-needed %d", &tmp))
5945         resolve_if_needed = tmp;
5946       else if (unformat (i, "l2-only"))
5947         l2_only = 1;
5948       else if (unformat (i, "del"))
5949         is_add = 0;
5950       else
5951         {
5952           clib_warning ("parse error '%U'", format_unformat_error, i);
5953           return -99;
5954         }
5955     }
5956
5957   if (!adj_address_set)
5958     {
5959       errmsg ("adjacency address/mask not set\n");
5960       return -99;
5961     }
5962   if (!next_hop_address_set)
5963     {
5964       errmsg ("ip4 next hop address (in outer fib) not set\n");
5965       return -99;
5966     }
5967
5968   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
5969
5970   mp->inner_vrf_id = ntohl (inner_vrf_id);
5971   mp->outer_vrf_id = ntohl (outer_vrf_id);
5972   mp->resolve_attempts = ntohl (resolve_attempts);
5973   mp->resolve_if_needed = resolve_if_needed;
5974   mp->is_add = is_add;
5975   mp->l2_only = l2_only;
5976   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
5977   mp->adj_address_length = adj_address_length;
5978   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
5979                sizeof (next_hop_address));
5980
5981   S;
5982   W;
5983   /* NOTREACHED */
5984   return 0;
5985 }
5986
5987 static int
5988 api_sw_interface_set_unnumbered (vat_main_t * vam)
5989 {
5990   unformat_input_t *i = vam->input;
5991   vl_api_sw_interface_set_unnumbered_t *mp;
5992   f64 timeout;
5993   u32 sw_if_index;
5994   u32 unnum_sw_index = ~0;
5995   u8 is_add = 1;
5996   u8 sw_if_index_set = 0;
5997
5998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5999     {
6000       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6001         sw_if_index_set = 1;
6002       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6003         sw_if_index_set = 1;
6004       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6005         ;
6006       else if (unformat (i, "del"))
6007         is_add = 0;
6008       else
6009         {
6010           clib_warning ("parse error '%U'", format_unformat_error, i);
6011           return -99;
6012         }
6013     }
6014
6015   if (sw_if_index_set == 0)
6016     {
6017       errmsg ("missing interface name or sw_if_index\n");
6018       return -99;
6019     }
6020
6021   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6022
6023   mp->sw_if_index = ntohl (sw_if_index);
6024   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6025   mp->is_add = is_add;
6026
6027   S;
6028   W;
6029   /* NOTREACHED */
6030   return 0;
6031 }
6032
6033 static int
6034 api_ip_neighbor_add_del (vat_main_t * vam)
6035 {
6036   unformat_input_t *i = vam->input;
6037   vl_api_ip_neighbor_add_del_t *mp;
6038   f64 timeout;
6039   u32 sw_if_index;
6040   u8 sw_if_index_set = 0;
6041   u32 vrf_id = 0;
6042   u8 is_add = 1;
6043   u8 is_static = 0;
6044   u8 mac_address[6];
6045   u8 mac_set = 0;
6046   u8 v4_address_set = 0;
6047   u8 v6_address_set = 0;
6048   ip4_address_t v4address;
6049   ip6_address_t v6address;
6050
6051   memset (mac_address, 0, sizeof (mac_address));
6052
6053   /* Parse args required to build the message */
6054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6055     {
6056       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6057         {
6058           mac_set = 1;
6059         }
6060       else if (unformat (i, "del"))
6061         is_add = 0;
6062       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6063         sw_if_index_set = 1;
6064       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6065         sw_if_index_set = 1;
6066       else if (unformat (i, "is_static"))
6067         is_static = 1;
6068       else if (unformat (i, "vrf %d", &vrf_id))
6069         ;
6070       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6071         v4_address_set = 1;
6072       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6073         v6_address_set = 1;
6074       else
6075         {
6076           clib_warning ("parse error '%U'", format_unformat_error, i);
6077           return -99;
6078         }
6079     }
6080
6081   if (sw_if_index_set == 0)
6082     {
6083       errmsg ("missing interface name or sw_if_index\n");
6084       return -99;
6085     }
6086   if (v4_address_set && v6_address_set)
6087     {
6088       errmsg ("both v4 and v6 addresses set\n");
6089       return -99;
6090     }
6091   if (!v4_address_set && !v6_address_set)
6092     {
6093       errmsg ("no address set\n");
6094       return -99;
6095     }
6096
6097   /* Construct the API message */
6098   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6099
6100   mp->sw_if_index = ntohl (sw_if_index);
6101   mp->is_add = is_add;
6102   mp->vrf_id = ntohl (vrf_id);
6103   mp->is_static = is_static;
6104   if (mac_set)
6105     clib_memcpy (mp->mac_address, mac_address, 6);
6106   if (v6_address_set)
6107     {
6108       mp->is_ipv6 = 1;
6109       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6110     }
6111   else
6112     {
6113       /* mp->is_ipv6 = 0; via memset in M macro above */
6114       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6115     }
6116
6117   /* send it... */
6118   S;
6119
6120   /* Wait for a reply, return good/bad news  */
6121   W;
6122
6123   /* NOTREACHED */
6124   return 0;
6125 }
6126
6127 static int
6128 api_reset_vrf (vat_main_t * vam)
6129 {
6130   unformat_input_t *i = vam->input;
6131   vl_api_reset_vrf_t *mp;
6132   f64 timeout;
6133   u32 vrf_id = 0;
6134   u8 is_ipv6 = 0;
6135   u8 vrf_id_set = 0;
6136
6137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6138     {
6139       if (unformat (i, "vrf %d", &vrf_id))
6140         vrf_id_set = 1;
6141       else if (unformat (i, "ipv6"))
6142         is_ipv6 = 1;
6143       else
6144         {
6145           clib_warning ("parse error '%U'", format_unformat_error, i);
6146           return -99;
6147         }
6148     }
6149
6150   if (vrf_id_set == 0)
6151     {
6152       errmsg ("missing vrf id\n");
6153       return -99;
6154     }
6155
6156   M (RESET_VRF, reset_vrf);
6157
6158   mp->vrf_id = ntohl (vrf_id);
6159   mp->is_ipv6 = is_ipv6;
6160
6161   S;
6162   W;
6163   /* NOTREACHED */
6164   return 0;
6165 }
6166
6167 static int
6168 api_create_vlan_subif (vat_main_t * vam)
6169 {
6170   unformat_input_t *i = vam->input;
6171   vl_api_create_vlan_subif_t *mp;
6172   f64 timeout;
6173   u32 sw_if_index;
6174   u8 sw_if_index_set = 0;
6175   u32 vlan_id;
6176   u8 vlan_id_set = 0;
6177
6178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6179     {
6180       if (unformat (i, "sw_if_index %d", &sw_if_index))
6181         sw_if_index_set = 1;
6182       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6183         sw_if_index_set = 1;
6184       else if (unformat (i, "vlan %d", &vlan_id))
6185         vlan_id_set = 1;
6186       else
6187         {
6188           clib_warning ("parse error '%U'", format_unformat_error, i);
6189           return -99;
6190         }
6191     }
6192
6193   if (sw_if_index_set == 0)
6194     {
6195       errmsg ("missing interface name or sw_if_index\n");
6196       return -99;
6197     }
6198
6199   if (vlan_id_set == 0)
6200     {
6201       errmsg ("missing vlan_id\n");
6202       return -99;
6203     }
6204   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6205
6206   mp->sw_if_index = ntohl (sw_if_index);
6207   mp->vlan_id = ntohl (vlan_id);
6208
6209   S;
6210   W;
6211   /* NOTREACHED */
6212   return 0;
6213 }
6214
6215 #define foreach_create_subif_bit                \
6216 _(no_tags)                                      \
6217 _(one_tag)                                      \
6218 _(two_tags)                                     \
6219 _(dot1ad)                                       \
6220 _(exact_match)                                  \
6221 _(default_sub)                                  \
6222 _(outer_vlan_id_any)                            \
6223 _(inner_vlan_id_any)
6224
6225 static int
6226 api_create_subif (vat_main_t * vam)
6227 {
6228   unformat_input_t *i = vam->input;
6229   vl_api_create_subif_t *mp;
6230   f64 timeout;
6231   u32 sw_if_index;
6232   u8 sw_if_index_set = 0;
6233   u32 sub_id;
6234   u8 sub_id_set = 0;
6235   u32 no_tags = 0;
6236   u32 one_tag = 0;
6237   u32 two_tags = 0;
6238   u32 dot1ad = 0;
6239   u32 exact_match = 0;
6240   u32 default_sub = 0;
6241   u32 outer_vlan_id_any = 0;
6242   u32 inner_vlan_id_any = 0;
6243   u32 tmp;
6244   u16 outer_vlan_id = 0;
6245   u16 inner_vlan_id = 0;
6246
6247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6248     {
6249       if (unformat (i, "sw_if_index %d", &sw_if_index))
6250         sw_if_index_set = 1;
6251       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6252         sw_if_index_set = 1;
6253       else if (unformat (i, "sub_id %d", &sub_id))
6254         sub_id_set = 1;
6255       else if (unformat (i, "outer_vlan_id %d", &tmp))
6256         outer_vlan_id = tmp;
6257       else if (unformat (i, "inner_vlan_id %d", &tmp))
6258         inner_vlan_id = tmp;
6259
6260 #define _(a) else if (unformat (i, #a)) a = 1 ;
6261       foreach_create_subif_bit
6262 #undef _
6263         else
6264         {
6265           clib_warning ("parse error '%U'", format_unformat_error, i);
6266           return -99;
6267         }
6268     }
6269
6270   if (sw_if_index_set == 0)
6271     {
6272       errmsg ("missing interface name or sw_if_index\n");
6273       return -99;
6274     }
6275
6276   if (sub_id_set == 0)
6277     {
6278       errmsg ("missing sub_id\n");
6279       return -99;
6280     }
6281   M (CREATE_SUBIF, create_subif);
6282
6283   mp->sw_if_index = ntohl (sw_if_index);
6284   mp->sub_id = ntohl (sub_id);
6285
6286 #define _(a) mp->a = a;
6287   foreach_create_subif_bit;
6288 #undef _
6289
6290   mp->outer_vlan_id = ntohs (outer_vlan_id);
6291   mp->inner_vlan_id = ntohs (inner_vlan_id);
6292
6293   S;
6294   W;
6295   /* NOTREACHED */
6296   return 0;
6297 }
6298
6299 static int
6300 api_oam_add_del (vat_main_t * vam)
6301 {
6302   unformat_input_t *i = vam->input;
6303   vl_api_oam_add_del_t *mp;
6304   f64 timeout;
6305   u32 vrf_id = 0;
6306   u8 is_add = 1;
6307   ip4_address_t src, dst;
6308   u8 src_set = 0;
6309   u8 dst_set = 0;
6310
6311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6312     {
6313       if (unformat (i, "vrf %d", &vrf_id))
6314         ;
6315       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6316         src_set = 1;
6317       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6318         dst_set = 1;
6319       else if (unformat (i, "del"))
6320         is_add = 0;
6321       else
6322         {
6323           clib_warning ("parse error '%U'", format_unformat_error, i);
6324           return -99;
6325         }
6326     }
6327
6328   if (src_set == 0)
6329     {
6330       errmsg ("missing src addr\n");
6331       return -99;
6332     }
6333
6334   if (dst_set == 0)
6335     {
6336       errmsg ("missing dst addr\n");
6337       return -99;
6338     }
6339
6340   M (OAM_ADD_DEL, oam_add_del);
6341
6342   mp->vrf_id = ntohl (vrf_id);
6343   mp->is_add = is_add;
6344   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6345   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6346
6347   S;
6348   W;
6349   /* NOTREACHED */
6350   return 0;
6351 }
6352
6353 static int
6354 api_reset_fib (vat_main_t * vam)
6355 {
6356   unformat_input_t *i = vam->input;
6357   vl_api_reset_fib_t *mp;
6358   f64 timeout;
6359   u32 vrf_id = 0;
6360   u8 is_ipv6 = 0;
6361   u8 vrf_id_set = 0;
6362
6363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6364     {
6365       if (unformat (i, "vrf %d", &vrf_id))
6366         vrf_id_set = 1;
6367       else if (unformat (i, "ipv6"))
6368         is_ipv6 = 1;
6369       else
6370         {
6371           clib_warning ("parse error '%U'", format_unformat_error, i);
6372           return -99;
6373         }
6374     }
6375
6376   if (vrf_id_set == 0)
6377     {
6378       errmsg ("missing vrf id\n");
6379       return -99;
6380     }
6381
6382   M (RESET_FIB, reset_fib);
6383
6384   mp->vrf_id = ntohl (vrf_id);
6385   mp->is_ipv6 = is_ipv6;
6386
6387   S;
6388   W;
6389   /* NOTREACHED */
6390   return 0;
6391 }
6392
6393 static int
6394 api_dhcp_proxy_config (vat_main_t * vam)
6395 {
6396   unformat_input_t *i = vam->input;
6397   vl_api_dhcp_proxy_config_t *mp;
6398   f64 timeout;
6399   u32 vrf_id = 0;
6400   u8 is_add = 1;
6401   u8 insert_cid = 1;
6402   u8 v4_address_set = 0;
6403   u8 v6_address_set = 0;
6404   ip4_address_t v4address;
6405   ip6_address_t v6address;
6406   u8 v4_src_address_set = 0;
6407   u8 v6_src_address_set = 0;
6408   ip4_address_t v4srcaddress;
6409   ip6_address_t v6srcaddress;
6410
6411   /* Parse args required to build the message */
6412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6413     {
6414       if (unformat (i, "del"))
6415         is_add = 0;
6416       else if (unformat (i, "vrf %d", &vrf_id))
6417         ;
6418       else if (unformat (i, "insert-cid %d", &insert_cid))
6419         ;
6420       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6421         v4_address_set = 1;
6422       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6423         v6_address_set = 1;
6424       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6425         v4_src_address_set = 1;
6426       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6427         v6_src_address_set = 1;
6428       else
6429         break;
6430     }
6431
6432   if (v4_address_set && v6_address_set)
6433     {
6434       errmsg ("both v4 and v6 server addresses set\n");
6435       return -99;
6436     }
6437   if (!v4_address_set && !v6_address_set)
6438     {
6439       errmsg ("no server addresses set\n");
6440       return -99;
6441     }
6442
6443   if (v4_src_address_set && v6_src_address_set)
6444     {
6445       errmsg ("both v4 and v6  src addresses set\n");
6446       return -99;
6447     }
6448   if (!v4_src_address_set && !v6_src_address_set)
6449     {
6450       errmsg ("no src addresses set\n");
6451       return -99;
6452     }
6453
6454   if (!(v4_src_address_set && v4_address_set) &&
6455       !(v6_src_address_set && v6_address_set))
6456     {
6457       errmsg ("no matching server and src addresses set\n");
6458       return -99;
6459     }
6460
6461   /* Construct the API message */
6462   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6463
6464   mp->insert_circuit_id = insert_cid;
6465   mp->is_add = is_add;
6466   mp->vrf_id = ntohl (vrf_id);
6467   if (v6_address_set)
6468     {
6469       mp->is_ipv6 = 1;
6470       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6471       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6472     }
6473   else
6474     {
6475       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6476       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6477     }
6478
6479   /* send it... */
6480   S;
6481
6482   /* Wait for a reply, return good/bad news  */
6483   W;
6484   /* NOTREACHED */
6485   return 0;
6486 }
6487
6488 static int
6489 api_dhcp_proxy_config_2 (vat_main_t * vam)
6490 {
6491   unformat_input_t *i = vam->input;
6492   vl_api_dhcp_proxy_config_2_t *mp;
6493   f64 timeout;
6494   u32 rx_vrf_id = 0;
6495   u32 server_vrf_id = 0;
6496   u8 is_add = 1;
6497   u8 insert_cid = 1;
6498   u8 v4_address_set = 0;
6499   u8 v6_address_set = 0;
6500   ip4_address_t v4address;
6501   ip6_address_t v6address;
6502   u8 v4_src_address_set = 0;
6503   u8 v6_src_address_set = 0;
6504   ip4_address_t v4srcaddress;
6505   ip6_address_t v6srcaddress;
6506
6507   /* Parse args required to build the message */
6508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6509     {
6510       if (unformat (i, "del"))
6511         is_add = 0;
6512       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6513         ;
6514       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6515         ;
6516       else if (unformat (i, "insert-cid %d", &insert_cid))
6517         ;
6518       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6519         v4_address_set = 1;
6520       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6521         v6_address_set = 1;
6522       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6523         v4_src_address_set = 1;
6524       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6525         v6_src_address_set = 1;
6526       else
6527         break;
6528     }
6529
6530   if (v4_address_set && v6_address_set)
6531     {
6532       errmsg ("both v4 and v6 server addresses set\n");
6533       return -99;
6534     }
6535   if (!v4_address_set && !v6_address_set)
6536     {
6537       errmsg ("no server addresses set\n");
6538       return -99;
6539     }
6540
6541   if (v4_src_address_set && v6_src_address_set)
6542     {
6543       errmsg ("both v4 and v6  src addresses set\n");
6544       return -99;
6545     }
6546   if (!v4_src_address_set && !v6_src_address_set)
6547     {
6548       errmsg ("no src addresses set\n");
6549       return -99;
6550     }
6551
6552   if (!(v4_src_address_set && v4_address_set) &&
6553       !(v6_src_address_set && v6_address_set))
6554     {
6555       errmsg ("no matching server and src addresses set\n");
6556       return -99;
6557     }
6558
6559   /* Construct the API message */
6560   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6561
6562   mp->insert_circuit_id = insert_cid;
6563   mp->is_add = is_add;
6564   mp->rx_vrf_id = ntohl (rx_vrf_id);
6565   mp->server_vrf_id = ntohl (server_vrf_id);
6566   if (v6_address_set)
6567     {
6568       mp->is_ipv6 = 1;
6569       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6570       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6571     }
6572   else
6573     {
6574       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6575       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6576     }
6577
6578   /* send it... */
6579   S;
6580
6581   /* Wait for a reply, return good/bad news  */
6582   W;
6583   /* NOTREACHED */
6584   return 0;
6585 }
6586
6587 static int
6588 api_dhcp_proxy_set_vss (vat_main_t * vam)
6589 {
6590   unformat_input_t *i = vam->input;
6591   vl_api_dhcp_proxy_set_vss_t *mp;
6592   f64 timeout;
6593   u8 is_ipv6 = 0;
6594   u8 is_add = 1;
6595   u32 tbl_id;
6596   u8 tbl_id_set = 0;
6597   u32 oui;
6598   u8 oui_set = 0;
6599   u32 fib_id;
6600   u8 fib_id_set = 0;
6601
6602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6603     {
6604       if (unformat (i, "tbl_id %d", &tbl_id))
6605         tbl_id_set = 1;
6606       if (unformat (i, "fib_id %d", &fib_id))
6607         fib_id_set = 1;
6608       if (unformat (i, "oui %d", &oui))
6609         oui_set = 1;
6610       else if (unformat (i, "ipv6"))
6611         is_ipv6 = 1;
6612       else if (unformat (i, "del"))
6613         is_add = 0;
6614       else
6615         {
6616           clib_warning ("parse error '%U'", format_unformat_error, i);
6617           return -99;
6618         }
6619     }
6620
6621   if (tbl_id_set == 0)
6622     {
6623       errmsg ("missing tbl id\n");
6624       return -99;
6625     }
6626
6627   if (fib_id_set == 0)
6628     {
6629       errmsg ("missing fib id\n");
6630       return -99;
6631     }
6632   if (oui_set == 0)
6633     {
6634       errmsg ("missing oui\n");
6635       return -99;
6636     }
6637
6638   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6639   mp->tbl_id = ntohl (tbl_id);
6640   mp->fib_id = ntohl (fib_id);
6641   mp->oui = ntohl (oui);
6642   mp->is_ipv6 = is_ipv6;
6643   mp->is_add = is_add;
6644
6645   S;
6646   W;
6647   /* NOTREACHED */
6648   return 0;
6649 }
6650
6651 static int
6652 api_dhcp_client_config (vat_main_t * vam)
6653 {
6654   unformat_input_t *i = vam->input;
6655   vl_api_dhcp_client_config_t *mp;
6656   f64 timeout;
6657   u32 sw_if_index;
6658   u8 sw_if_index_set = 0;
6659   u8 is_add = 1;
6660   u8 *hostname = 0;
6661   u8 disable_event = 0;
6662
6663   /* Parse args required to build the message */
6664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6665     {
6666       if (unformat (i, "del"))
6667         is_add = 0;
6668       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6669         sw_if_index_set = 1;
6670       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6671         sw_if_index_set = 1;
6672       else if (unformat (i, "hostname %s", &hostname))
6673         ;
6674       else if (unformat (i, "disable_event"))
6675         disable_event = 1;
6676       else
6677         break;
6678     }
6679
6680   if (sw_if_index_set == 0)
6681     {
6682       errmsg ("missing interface name or sw_if_index\n");
6683       return -99;
6684     }
6685
6686   if (vec_len (hostname) > 63)
6687     {
6688       errmsg ("hostname too long\n");
6689     }
6690   vec_add1 (hostname, 0);
6691
6692   /* Construct the API message */
6693   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6694
6695   mp->sw_if_index = ntohl (sw_if_index);
6696   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6697   vec_free (hostname);
6698   mp->is_add = is_add;
6699   mp->want_dhcp_event = disable_event ? 0 : 1;
6700   mp->pid = getpid ();
6701
6702   /* send it... */
6703   S;
6704
6705   /* Wait for a reply, return good/bad news  */
6706   W;
6707   /* NOTREACHED */
6708   return 0;
6709 }
6710
6711 static int
6712 api_set_ip_flow_hash (vat_main_t * vam)
6713 {
6714   unformat_input_t *i = vam->input;
6715   vl_api_set_ip_flow_hash_t *mp;
6716   f64 timeout;
6717   u32 vrf_id = 0;
6718   u8 is_ipv6 = 0;
6719   u8 vrf_id_set = 0;
6720   u8 src = 0;
6721   u8 dst = 0;
6722   u8 sport = 0;
6723   u8 dport = 0;
6724   u8 proto = 0;
6725   u8 reverse = 0;
6726
6727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6728     {
6729       if (unformat (i, "vrf %d", &vrf_id))
6730         vrf_id_set = 1;
6731       else if (unformat (i, "ipv6"))
6732         is_ipv6 = 1;
6733       else if (unformat (i, "src"))
6734         src = 1;
6735       else if (unformat (i, "dst"))
6736         dst = 1;
6737       else if (unformat (i, "sport"))
6738         sport = 1;
6739       else if (unformat (i, "dport"))
6740         dport = 1;
6741       else if (unformat (i, "proto"))
6742         proto = 1;
6743       else if (unformat (i, "reverse"))
6744         reverse = 1;
6745
6746       else
6747         {
6748           clib_warning ("parse error '%U'", format_unformat_error, i);
6749           return -99;
6750         }
6751     }
6752
6753   if (vrf_id_set == 0)
6754     {
6755       errmsg ("missing vrf id\n");
6756       return -99;
6757     }
6758
6759   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
6760   mp->src = src;
6761   mp->dst = dst;
6762   mp->sport = sport;
6763   mp->dport = dport;
6764   mp->proto = proto;
6765   mp->reverse = reverse;
6766   mp->vrf_id = ntohl (vrf_id);
6767   mp->is_ipv6 = is_ipv6;
6768
6769   S;
6770   W;
6771   /* NOTREACHED */
6772   return 0;
6773 }
6774
6775 static int
6776 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
6777 {
6778   unformat_input_t *i = vam->input;
6779   vl_api_sw_interface_ip6_enable_disable_t *mp;
6780   f64 timeout;
6781   u32 sw_if_index;
6782   u8 sw_if_index_set = 0;
6783   u8 enable = 0;
6784
6785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6786     {
6787       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6788         sw_if_index_set = 1;
6789       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6790         sw_if_index_set = 1;
6791       else if (unformat (i, "enable"))
6792         enable = 1;
6793       else if (unformat (i, "disable"))
6794         enable = 0;
6795       else
6796         {
6797           clib_warning ("parse error '%U'", format_unformat_error, i);
6798           return -99;
6799         }
6800     }
6801
6802   if (sw_if_index_set == 0)
6803     {
6804       errmsg ("missing interface name or sw_if_index\n");
6805       return -99;
6806     }
6807
6808   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
6809
6810   mp->sw_if_index = ntohl (sw_if_index);
6811   mp->enable = enable;
6812
6813   S;
6814   W;
6815   /* NOTREACHED */
6816   return 0;
6817 }
6818
6819 static int
6820 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
6821 {
6822   unformat_input_t *i = vam->input;
6823   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
6824   f64 timeout;
6825   u32 sw_if_index;
6826   u8 sw_if_index_set = 0;
6827   u32 address_length = 0;
6828   u8 v6_address_set = 0;
6829   ip6_address_t v6address;
6830
6831   /* Parse args required to build the message */
6832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6833     {
6834       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6835         sw_if_index_set = 1;
6836       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6837         sw_if_index_set = 1;
6838       else if (unformat (i, "%U/%d",
6839                          unformat_ip6_address, &v6address, &address_length))
6840         v6_address_set = 1;
6841       else
6842         break;
6843     }
6844
6845   if (sw_if_index_set == 0)
6846     {
6847       errmsg ("missing interface name or sw_if_index\n");
6848       return -99;
6849     }
6850   if (!v6_address_set)
6851     {
6852       errmsg ("no address set\n");
6853       return -99;
6854     }
6855
6856   /* Construct the API message */
6857   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
6858      sw_interface_ip6_set_link_local_address);
6859
6860   mp->sw_if_index = ntohl (sw_if_index);
6861   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6862   mp->address_length = address_length;
6863
6864   /* send it... */
6865   S;
6866
6867   /* Wait for a reply, return good/bad news  */
6868   W;
6869
6870   /* NOTREACHED */
6871   return 0;
6872 }
6873
6874
6875 static int
6876 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
6877 {
6878   unformat_input_t *i = vam->input;
6879   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
6880   f64 timeout;
6881   u32 sw_if_index;
6882   u8 sw_if_index_set = 0;
6883   u32 address_length = 0;
6884   u8 v6_address_set = 0;
6885   ip6_address_t v6address;
6886   u8 use_default = 0;
6887   u8 no_advertise = 0;
6888   u8 off_link = 0;
6889   u8 no_autoconfig = 0;
6890   u8 no_onlink = 0;
6891   u8 is_no = 0;
6892   u32 val_lifetime = 0;
6893   u32 pref_lifetime = 0;
6894
6895   /* Parse args required to build the message */
6896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6897     {
6898       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6899         sw_if_index_set = 1;
6900       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6901         sw_if_index_set = 1;
6902       else if (unformat (i, "%U/%d",
6903                          unformat_ip6_address, &v6address, &address_length))
6904         v6_address_set = 1;
6905       else if (unformat (i, "val_life %d", &val_lifetime))
6906         ;
6907       else if (unformat (i, "pref_life %d", &pref_lifetime))
6908         ;
6909       else if (unformat (i, "def"))
6910         use_default = 1;
6911       else if (unformat (i, "noadv"))
6912         no_advertise = 1;
6913       else if (unformat (i, "offl"))
6914         off_link = 1;
6915       else if (unformat (i, "noauto"))
6916         no_autoconfig = 1;
6917       else if (unformat (i, "nolink"))
6918         no_onlink = 1;
6919       else if (unformat (i, "isno"))
6920         is_no = 1;
6921       else
6922         {
6923           clib_warning ("parse error '%U'", format_unformat_error, i);
6924           return -99;
6925         }
6926     }
6927
6928   if (sw_if_index_set == 0)
6929     {
6930       errmsg ("missing interface name or sw_if_index\n");
6931       return -99;
6932     }
6933   if (!v6_address_set)
6934     {
6935       errmsg ("no address set\n");
6936       return -99;
6937     }
6938
6939   /* Construct the API message */
6940   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
6941
6942   mp->sw_if_index = ntohl (sw_if_index);
6943   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6944   mp->address_length = address_length;
6945   mp->use_default = use_default;
6946   mp->no_advertise = no_advertise;
6947   mp->off_link = off_link;
6948   mp->no_autoconfig = no_autoconfig;
6949   mp->no_onlink = no_onlink;
6950   mp->is_no = is_no;
6951   mp->val_lifetime = ntohl (val_lifetime);
6952   mp->pref_lifetime = ntohl (pref_lifetime);
6953
6954   /* send it... */
6955   S;
6956
6957   /* Wait for a reply, return good/bad news  */
6958   W;
6959
6960   /* NOTREACHED */
6961   return 0;
6962 }
6963
6964 static int
6965 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
6966 {
6967   unformat_input_t *i = vam->input;
6968   vl_api_sw_interface_ip6nd_ra_config_t *mp;
6969   f64 timeout;
6970   u32 sw_if_index;
6971   u8 sw_if_index_set = 0;
6972   u8 suppress = 0;
6973   u8 managed = 0;
6974   u8 other = 0;
6975   u8 ll_option = 0;
6976   u8 send_unicast = 0;
6977   u8 cease = 0;
6978   u8 is_no = 0;
6979   u8 default_router = 0;
6980   u32 max_interval = 0;
6981   u32 min_interval = 0;
6982   u32 lifetime = 0;
6983   u32 initial_count = 0;
6984   u32 initial_interval = 0;
6985
6986
6987   /* Parse args required to build the message */
6988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6989     {
6990       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6991         sw_if_index_set = 1;
6992       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6993         sw_if_index_set = 1;
6994       else if (unformat (i, "maxint %d", &max_interval))
6995         ;
6996       else if (unformat (i, "minint %d", &min_interval))
6997         ;
6998       else if (unformat (i, "life %d", &lifetime))
6999         ;
7000       else if (unformat (i, "count %d", &initial_count))
7001         ;
7002       else if (unformat (i, "interval %d", &initial_interval))
7003         ;
7004       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7005         suppress = 1;
7006       else if (unformat (i, "managed"))
7007         managed = 1;
7008       else if (unformat (i, "other"))
7009         other = 1;
7010       else if (unformat (i, "ll"))
7011         ll_option = 1;
7012       else if (unformat (i, "send"))
7013         send_unicast = 1;
7014       else if (unformat (i, "cease"))
7015         cease = 1;
7016       else if (unformat (i, "isno"))
7017         is_no = 1;
7018       else if (unformat (i, "def"))
7019         default_router = 1;
7020       else
7021         {
7022           clib_warning ("parse error '%U'", format_unformat_error, i);
7023           return -99;
7024         }
7025     }
7026
7027   if (sw_if_index_set == 0)
7028     {
7029       errmsg ("missing interface name or sw_if_index\n");
7030       return -99;
7031     }
7032
7033   /* Construct the API message */
7034   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7035
7036   mp->sw_if_index = ntohl (sw_if_index);
7037   mp->max_interval = ntohl (max_interval);
7038   mp->min_interval = ntohl (min_interval);
7039   mp->lifetime = ntohl (lifetime);
7040   mp->initial_count = ntohl (initial_count);
7041   mp->initial_interval = ntohl (initial_interval);
7042   mp->suppress = suppress;
7043   mp->managed = managed;
7044   mp->other = other;
7045   mp->ll_option = ll_option;
7046   mp->send_unicast = send_unicast;
7047   mp->cease = cease;
7048   mp->is_no = is_no;
7049   mp->default_router = default_router;
7050
7051   /* send it... */
7052   S;
7053
7054   /* Wait for a reply, return good/bad news  */
7055   W;
7056
7057   /* NOTREACHED */
7058   return 0;
7059 }
7060
7061 static int
7062 api_set_arp_neighbor_limit (vat_main_t * vam)
7063 {
7064   unformat_input_t *i = vam->input;
7065   vl_api_set_arp_neighbor_limit_t *mp;
7066   f64 timeout;
7067   u32 arp_nbr_limit;
7068   u8 limit_set = 0;
7069   u8 is_ipv6 = 0;
7070
7071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7072     {
7073       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7074         limit_set = 1;
7075       else if (unformat (i, "ipv6"))
7076         is_ipv6 = 1;
7077       else
7078         {
7079           clib_warning ("parse error '%U'", format_unformat_error, i);
7080           return -99;
7081         }
7082     }
7083
7084   if (limit_set == 0)
7085     {
7086       errmsg ("missing limit value\n");
7087       return -99;
7088     }
7089
7090   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7091
7092   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7093   mp->is_ipv6 = is_ipv6;
7094
7095   S;
7096   W;
7097   /* NOTREACHED */
7098   return 0;
7099 }
7100
7101 static int
7102 api_l2_patch_add_del (vat_main_t * vam)
7103 {
7104   unformat_input_t *i = vam->input;
7105   vl_api_l2_patch_add_del_t *mp;
7106   f64 timeout;
7107   u32 rx_sw_if_index;
7108   u8 rx_sw_if_index_set = 0;
7109   u32 tx_sw_if_index;
7110   u8 tx_sw_if_index_set = 0;
7111   u8 is_add = 1;
7112
7113   /* Parse args required to build the message */
7114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7115     {
7116       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7117         rx_sw_if_index_set = 1;
7118       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7119         tx_sw_if_index_set = 1;
7120       else if (unformat (i, "rx"))
7121         {
7122           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7123             {
7124               if (unformat (i, "%U", unformat_sw_if_index, vam,
7125                             &rx_sw_if_index))
7126                 rx_sw_if_index_set = 1;
7127             }
7128           else
7129             break;
7130         }
7131       else if (unformat (i, "tx"))
7132         {
7133           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7134             {
7135               if (unformat (i, "%U", unformat_sw_if_index, vam,
7136                             &tx_sw_if_index))
7137                 tx_sw_if_index_set = 1;
7138             }
7139           else
7140             break;
7141         }
7142       else if (unformat (i, "del"))
7143         is_add = 0;
7144       else
7145         break;
7146     }
7147
7148   if (rx_sw_if_index_set == 0)
7149     {
7150       errmsg ("missing rx interface name or rx_sw_if_index\n");
7151       return -99;
7152     }
7153
7154   if (tx_sw_if_index_set == 0)
7155     {
7156       errmsg ("missing tx interface name or tx_sw_if_index\n");
7157       return -99;
7158     }
7159
7160   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7161
7162   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7163   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7164   mp->is_add = is_add;
7165
7166   S;
7167   W;
7168   /* NOTREACHED */
7169   return 0;
7170 }
7171
7172 static int
7173 api_ioam_enable (vat_main_t * vam)
7174 {
7175   unformat_input_t *input = vam->input;
7176   vl_api_ioam_enable_t *mp;
7177   f64 timeout;
7178   u32 id = 0;
7179   int has_trace_option = 0;
7180   int has_pow_option = 0;
7181   int has_ppc_option = 0;
7182
7183   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7184     {
7185       if (unformat (input, "trace"))
7186         has_trace_option = 1;
7187       else if (unformat (input, "pow"))
7188         has_pow_option = 1;
7189       else if (unformat (input, "ppc encap"))
7190         has_ppc_option = PPC_ENCAP;
7191       else if (unformat (input, "ppc decap"))
7192         has_ppc_option = PPC_DECAP;
7193       else if (unformat (input, "ppc none"))
7194         has_ppc_option = PPC_NONE;
7195       else
7196         break;
7197     }
7198   M (IOAM_ENABLE, ioam_enable);
7199   mp->id = htons (id);
7200   mp->trace_ppc = has_ppc_option;
7201   mp->pow_enable = has_pow_option;
7202   mp->trace_enable = has_trace_option;
7203
7204   S;
7205   W;
7206
7207   return (0);
7208
7209 }
7210
7211
7212 static int
7213 api_ioam_disable (vat_main_t * vam)
7214 {
7215   vl_api_ioam_disable_t *mp;
7216   f64 timeout;
7217
7218   M (IOAM_DISABLE, ioam_disable);
7219   S;
7220   W;
7221   return 0;
7222 }
7223
7224 static int
7225 api_sr_tunnel_add_del (vat_main_t * vam)
7226 {
7227   unformat_input_t *i = vam->input;
7228   vl_api_sr_tunnel_add_del_t *mp;
7229   f64 timeout;
7230   int is_del = 0;
7231   int pl_index;
7232   ip6_address_t src_address;
7233   int src_address_set = 0;
7234   ip6_address_t dst_address;
7235   u32 dst_mask_width;
7236   int dst_address_set = 0;
7237   u16 flags = 0;
7238   u32 rx_table_id = 0;
7239   u32 tx_table_id = 0;
7240   ip6_address_t *segments = 0;
7241   ip6_address_t *this_seg;
7242   ip6_address_t *tags = 0;
7243   ip6_address_t *this_tag;
7244   ip6_address_t next_address, tag;
7245   u8 *name = 0;
7246   u8 *policy_name = 0;
7247
7248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7249     {
7250       if (unformat (i, "del"))
7251         is_del = 1;
7252       else if (unformat (i, "name %s", &name))
7253         ;
7254       else if (unformat (i, "policy %s", &policy_name))
7255         ;
7256       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7257         ;
7258       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7259         ;
7260       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7261         src_address_set = 1;
7262       else if (unformat (i, "dst %U/%d",
7263                          unformat_ip6_address, &dst_address, &dst_mask_width))
7264         dst_address_set = 1;
7265       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7266         {
7267           vec_add2 (segments, this_seg, 1);
7268           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7269                        sizeof (*this_seg));
7270         }
7271       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7272         {
7273           vec_add2 (tags, this_tag, 1);
7274           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7275         }
7276       else if (unformat (i, "clean"))
7277         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7278       else if (unformat (i, "protected"))
7279         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7280       else if (unformat (i, "InPE %d", &pl_index))
7281         {
7282           if (pl_index <= 0 || pl_index > 4)
7283             {
7284             pl_index_range_error:
7285               errmsg ("pl index %d out of range\n", pl_index);
7286               return -99;
7287             }
7288           flags |=
7289             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7290         }
7291       else if (unformat (i, "EgPE %d", &pl_index))
7292         {
7293           if (pl_index <= 0 || pl_index > 4)
7294             goto pl_index_range_error;
7295           flags |=
7296             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7297         }
7298       else if (unformat (i, "OrgSrc %d", &pl_index))
7299         {
7300           if (pl_index <= 0 || pl_index > 4)
7301             goto pl_index_range_error;
7302           flags |=
7303             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7304         }
7305       else
7306         break;
7307     }
7308
7309   if (!src_address_set)
7310     {
7311       errmsg ("src address required\n");
7312       return -99;
7313     }
7314
7315   if (!dst_address_set)
7316     {
7317       errmsg ("dst address required\n");
7318       return -99;
7319     }
7320
7321   if (!segments)
7322     {
7323       errmsg ("at least one sr segment required\n");
7324       return -99;
7325     }
7326
7327   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7328       vec_len (segments) * sizeof (ip6_address_t)
7329       + vec_len (tags) * sizeof (ip6_address_t));
7330
7331   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7332   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7333   mp->dst_mask_width = dst_mask_width;
7334   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7335   mp->n_segments = vec_len (segments);
7336   mp->n_tags = vec_len (tags);
7337   mp->is_add = is_del == 0;
7338   clib_memcpy (mp->segs_and_tags, segments,
7339                vec_len (segments) * sizeof (ip6_address_t));
7340   clib_memcpy (mp->segs_and_tags +
7341                vec_len (segments) * sizeof (ip6_address_t), tags,
7342                vec_len (tags) * sizeof (ip6_address_t));
7343
7344   mp->outer_vrf_id = ntohl (rx_table_id);
7345   mp->inner_vrf_id = ntohl (tx_table_id);
7346   memcpy (mp->name, name, vec_len (name));
7347   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7348
7349   vec_free (segments);
7350   vec_free (tags);
7351
7352   S;
7353   W;
7354   /* NOTREACHED */
7355 }
7356
7357 static int
7358 api_sr_policy_add_del (vat_main_t * vam)
7359 {
7360   unformat_input_t *input = vam->input;
7361   vl_api_sr_policy_add_del_t *mp;
7362   f64 timeout;
7363   int is_del = 0;
7364   u8 *name = 0;
7365   u8 *tunnel_name = 0;
7366   u8 **tunnel_names = 0;
7367
7368   int name_set = 0;
7369   int tunnel_set = 0;
7370   int j = 0;
7371   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7372   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7373
7374   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7375     {
7376       if (unformat (input, "del"))
7377         is_del = 1;
7378       else if (unformat (input, "name %s", &name))
7379         name_set = 1;
7380       else if (unformat (input, "tunnel %s", &tunnel_name))
7381         {
7382           if (tunnel_name)
7383             {
7384               vec_add1 (tunnel_names, tunnel_name);
7385               /* For serializer:
7386                  - length = #bytes to store in serial vector
7387                  - +1 = byte to store that length
7388                */
7389               tunnel_names_length += (vec_len (tunnel_name) + 1);
7390               tunnel_set = 1;
7391               tunnel_name = 0;
7392             }
7393         }
7394       else
7395         break;
7396     }
7397
7398   if (!name_set)
7399     {
7400       errmsg ("policy name required\n");
7401       return -99;
7402     }
7403
7404   if ((!tunnel_set) && (!is_del))
7405     {
7406       errmsg ("tunnel name required\n");
7407       return -99;
7408     }
7409
7410   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7411
7412
7413
7414   mp->is_add = !is_del;
7415
7416   memcpy (mp->name, name, vec_len (name));
7417   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7418   u8 *serial_orig = 0;
7419   vec_validate (serial_orig, tunnel_names_length);
7420   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7421   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7422
7423   for (j = 0; j < vec_len (tunnel_names); j++)
7424     {
7425       tun_name_len = vec_len (tunnel_names[j]);
7426       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7427       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7428       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7429       serial_orig += tun_name_len;      // Advance past the copy
7430     }
7431   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7432
7433   vec_free (tunnel_names);
7434   vec_free (tunnel_name);
7435
7436   S;
7437   W;
7438   /* NOTREACHED */
7439 }
7440
7441 static int
7442 api_sr_multicast_map_add_del (vat_main_t * vam)
7443 {
7444   unformat_input_t *input = vam->input;
7445   vl_api_sr_multicast_map_add_del_t *mp;
7446   f64 timeout;
7447   int is_del = 0;
7448   ip6_address_t multicast_address;
7449   u8 *policy_name = 0;
7450   int multicast_address_set = 0;
7451
7452   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7453     {
7454       if (unformat (input, "del"))
7455         is_del = 1;
7456       else
7457         if (unformat
7458             (input, "address %U", unformat_ip6_address, &multicast_address))
7459         multicast_address_set = 1;
7460       else if (unformat (input, "sr-policy %s", &policy_name))
7461         ;
7462       else
7463         break;
7464     }
7465
7466   if (!is_del && !policy_name)
7467     {
7468       errmsg ("sr-policy name required\n");
7469       return -99;
7470     }
7471
7472
7473   if (!multicast_address_set)
7474     {
7475       errmsg ("address required\n");
7476       return -99;
7477     }
7478
7479   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7480
7481   mp->is_add = !is_del;
7482   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7483   clib_memcpy (mp->multicast_address, &multicast_address,
7484                sizeof (mp->multicast_address));
7485
7486
7487   vec_free (policy_name);
7488
7489   S;
7490   W;
7491   /* NOTREACHED */
7492 }
7493
7494
7495 #define foreach_ip4_proto_field                 \
7496 _(src_address)                                  \
7497 _(dst_address)                                  \
7498 _(tos)                                          \
7499 _(length)                                       \
7500 _(fragment_id)                                  \
7501 _(ttl)                                          \
7502 _(protocol)                                     \
7503 _(checksum)
7504
7505 uword
7506 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7507 {
7508   u8 **maskp = va_arg (*args, u8 **);
7509   u8 *mask = 0;
7510   u8 found_something = 0;
7511   ip4_header_t *ip;
7512
7513 #define _(a) u8 a=0;
7514   foreach_ip4_proto_field;
7515 #undef _
7516   u8 version = 0;
7517   u8 hdr_length = 0;
7518
7519
7520   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7521     {
7522       if (unformat (input, "version"))
7523         version = 1;
7524       else if (unformat (input, "hdr_length"))
7525         hdr_length = 1;
7526       else if (unformat (input, "src"))
7527         src_address = 1;
7528       else if (unformat (input, "dst"))
7529         dst_address = 1;
7530       else if (unformat (input, "proto"))
7531         protocol = 1;
7532
7533 #define _(a) else if (unformat (input, #a)) a=1;
7534       foreach_ip4_proto_field
7535 #undef _
7536         else
7537         break;
7538     }
7539
7540 #define _(a) found_something += a;
7541   foreach_ip4_proto_field;
7542 #undef _
7543
7544   if (found_something == 0)
7545     return 0;
7546
7547   vec_validate (mask, sizeof (*ip) - 1);
7548
7549   ip = (ip4_header_t *) mask;
7550
7551 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7552   foreach_ip4_proto_field;
7553 #undef _
7554
7555   ip->ip_version_and_header_length = 0;
7556
7557   if (version)
7558     ip->ip_version_and_header_length |= 0xF0;
7559
7560   if (hdr_length)
7561     ip->ip_version_and_header_length |= 0x0F;
7562
7563   *maskp = mask;
7564   return 1;
7565 }
7566
7567 #define foreach_ip6_proto_field                 \
7568 _(src_address)                                  \
7569 _(dst_address)                                  \
7570 _(payload_length)                               \
7571 _(hop_limit)                                    \
7572 _(protocol)
7573
7574 uword
7575 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7576 {
7577   u8 **maskp = va_arg (*args, u8 **);
7578   u8 *mask = 0;
7579   u8 found_something = 0;
7580   ip6_header_t *ip;
7581   u32 ip_version_traffic_class_and_flow_label;
7582
7583 #define _(a) u8 a=0;
7584   foreach_ip6_proto_field;
7585 #undef _
7586   u8 version = 0;
7587   u8 traffic_class = 0;
7588   u8 flow_label = 0;
7589
7590   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7591     {
7592       if (unformat (input, "version"))
7593         version = 1;
7594       else if (unformat (input, "traffic-class"))
7595         traffic_class = 1;
7596       else if (unformat (input, "flow-label"))
7597         flow_label = 1;
7598       else if (unformat (input, "src"))
7599         src_address = 1;
7600       else if (unformat (input, "dst"))
7601         dst_address = 1;
7602       else if (unformat (input, "proto"))
7603         protocol = 1;
7604
7605 #define _(a) else if (unformat (input, #a)) a=1;
7606       foreach_ip6_proto_field
7607 #undef _
7608         else
7609         break;
7610     }
7611
7612 #define _(a) found_something += a;
7613   foreach_ip6_proto_field;
7614 #undef _
7615
7616   if (found_something == 0)
7617     return 0;
7618
7619   vec_validate (mask, sizeof (*ip) - 1);
7620
7621   ip = (ip6_header_t *) mask;
7622
7623 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7624   foreach_ip6_proto_field;
7625 #undef _
7626
7627   ip_version_traffic_class_and_flow_label = 0;
7628
7629   if (version)
7630     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7631
7632   if (traffic_class)
7633     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7634
7635   if (flow_label)
7636     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7637
7638   ip->ip_version_traffic_class_and_flow_label =
7639     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7640
7641   *maskp = mask;
7642   return 1;
7643 }
7644
7645 uword
7646 unformat_l3_mask (unformat_input_t * input, va_list * args)
7647 {
7648   u8 **maskp = va_arg (*args, u8 **);
7649
7650   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7651     {
7652       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7653         return 1;
7654       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7655         return 1;
7656       else
7657         break;
7658     }
7659   return 0;
7660 }
7661
7662 uword
7663 unformat_l2_mask (unformat_input_t * input, va_list * args)
7664 {
7665   u8 **maskp = va_arg (*args, u8 **);
7666   u8 *mask = 0;
7667   u8 src = 0;
7668   u8 dst = 0;
7669   u8 proto = 0;
7670   u8 tag1 = 0;
7671   u8 tag2 = 0;
7672   u8 ignore_tag1 = 0;
7673   u8 ignore_tag2 = 0;
7674   u8 cos1 = 0;
7675   u8 cos2 = 0;
7676   u8 dot1q = 0;
7677   u8 dot1ad = 0;
7678   int len = 14;
7679
7680   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7681     {
7682       if (unformat (input, "src"))
7683         src = 1;
7684       else if (unformat (input, "dst"))
7685         dst = 1;
7686       else if (unformat (input, "proto"))
7687         proto = 1;
7688       else if (unformat (input, "tag1"))
7689         tag1 = 1;
7690       else if (unformat (input, "tag2"))
7691         tag2 = 1;
7692       else if (unformat (input, "ignore-tag1"))
7693         ignore_tag1 = 1;
7694       else if (unformat (input, "ignore-tag2"))
7695         ignore_tag2 = 1;
7696       else if (unformat (input, "cos1"))
7697         cos1 = 1;
7698       else if (unformat (input, "cos2"))
7699         cos2 = 1;
7700       else if (unformat (input, "dot1q"))
7701         dot1q = 1;
7702       else if (unformat (input, "dot1ad"))
7703         dot1ad = 1;
7704       else
7705         break;
7706     }
7707   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7708        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7709     return 0;
7710
7711   if (tag1 || ignore_tag1 || cos1 || dot1q)
7712     len = 18;
7713   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7714     len = 22;
7715
7716   vec_validate (mask, len - 1);
7717
7718   if (dst)
7719     memset (mask, 0xff, 6);
7720
7721   if (src)
7722     memset (mask + 6, 0xff, 6);
7723
7724   if (tag2 || dot1ad)
7725     {
7726       /* inner vlan tag */
7727       if (tag2)
7728         {
7729           mask[19] = 0xff;
7730           mask[18] = 0x0f;
7731         }
7732       if (cos2)
7733         mask[18] |= 0xe0;
7734       if (proto)
7735         mask[21] = mask[20] = 0xff;
7736       if (tag1)
7737         {
7738           mask[15] = 0xff;
7739           mask[14] = 0x0f;
7740         }
7741       if (cos1)
7742         mask[14] |= 0xe0;
7743       *maskp = mask;
7744       return 1;
7745     }
7746   if (tag1 | dot1q)
7747     {
7748       if (tag1)
7749         {
7750           mask[15] = 0xff;
7751           mask[14] = 0x0f;
7752         }
7753       if (cos1)
7754         mask[14] |= 0xe0;
7755       if (proto)
7756         mask[16] = mask[17] = 0xff;
7757
7758       *maskp = mask;
7759       return 1;
7760     }
7761   if (cos2)
7762     mask[18] |= 0xe0;
7763   if (cos1)
7764     mask[14] |= 0xe0;
7765   if (proto)
7766     mask[12] = mask[13] = 0xff;
7767
7768   *maskp = mask;
7769   return 1;
7770 }
7771
7772 uword
7773 unformat_classify_mask (unformat_input_t * input, va_list * args)
7774 {
7775   u8 **maskp = va_arg (*args, u8 **);
7776   u32 *skipp = va_arg (*args, u32 *);
7777   u32 *matchp = va_arg (*args, u32 *);
7778   u32 match;
7779   u8 *mask = 0;
7780   u8 *l2 = 0;
7781   u8 *l3 = 0;
7782   int i;
7783
7784   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7785     {
7786       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7787         ;
7788       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7789         ;
7790       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7791         ;
7792       else
7793         break;
7794     }
7795
7796   if (mask || l2 || l3)
7797     {
7798       if (l2 || l3)
7799         {
7800           /* "With a free Ethernet header in every package" */
7801           if (l2 == 0)
7802             vec_validate (l2, 13);
7803           mask = l2;
7804           if (vec_len (l3))
7805             {
7806               vec_append (mask, l3);
7807               vec_free (l3);
7808             }
7809         }
7810
7811       /* Scan forward looking for the first significant mask octet */
7812       for (i = 0; i < vec_len (mask); i++)
7813         if (mask[i])
7814           break;
7815
7816       /* compute (skip, match) params */
7817       *skipp = i / sizeof (u32x4);
7818       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7819
7820       /* Pad mask to an even multiple of the vector size */
7821       while (vec_len (mask) % sizeof (u32x4))
7822         vec_add1 (mask, 0);
7823
7824       match = vec_len (mask) / sizeof (u32x4);
7825
7826       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7827         {
7828           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7829           if (*tmp || *(tmp + 1))
7830             break;
7831           match--;
7832         }
7833       if (match == 0)
7834         clib_warning ("BUG: match 0");
7835
7836       _vec_len (mask) = match * sizeof (u32x4);
7837
7838       *matchp = match;
7839       *maskp = mask;
7840
7841       return 1;
7842     }
7843
7844   return 0;
7845 }
7846
7847 #define foreach_l2_next                         \
7848 _(drop, DROP)                                   \
7849 _(ethernet, ETHERNET_INPUT)                     \
7850 _(ip4, IP4_INPUT)                               \
7851 _(ip6, IP6_INPUT)
7852
7853 uword
7854 unformat_l2_next_index (unformat_input_t * input, va_list * args)
7855 {
7856   u32 *miss_next_indexp = va_arg (*args, u32 *);
7857   u32 next_index = 0;
7858   u32 tmp;
7859
7860 #define _(n,N) \
7861   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
7862   foreach_l2_next;
7863 #undef _
7864
7865   if (unformat (input, "%d", &tmp))
7866     {
7867       next_index = tmp;
7868       goto out;
7869     }
7870
7871   return 0;
7872
7873 out:
7874   *miss_next_indexp = next_index;
7875   return 1;
7876 }
7877
7878 #define foreach_ip_next                         \
7879 _(miss, MISS)                                   \
7880 _(drop, DROP)                                   \
7881 _(local, LOCAL)                                 \
7882 _(rewrite, REWRITE)
7883
7884 uword
7885 unformat_ip_next_index (unformat_input_t * input, va_list * args)
7886 {
7887   u32 *miss_next_indexp = va_arg (*args, u32 *);
7888   u32 next_index = 0;
7889   u32 tmp;
7890
7891 #define _(n,N) \
7892   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7893   foreach_ip_next;
7894 #undef _
7895
7896   if (unformat (input, "%d", &tmp))
7897     {
7898       next_index = tmp;
7899       goto out;
7900     }
7901
7902   return 0;
7903
7904 out:
7905   *miss_next_indexp = next_index;
7906   return 1;
7907 }
7908
7909 #define foreach_acl_next                        \
7910 _(deny, DENY)
7911
7912 uword
7913 unformat_acl_next_index (unformat_input_t * input, va_list * args)
7914 {
7915   u32 *miss_next_indexp = va_arg (*args, u32 *);
7916   u32 next_index = 0;
7917   u32 tmp;
7918
7919 #define _(n,N) \
7920   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7921   foreach_acl_next;
7922 #undef _
7923
7924   if (unformat (input, "permit"))
7925     {
7926       next_index = ~0;
7927       goto out;
7928     }
7929   else if (unformat (input, "%d", &tmp))
7930     {
7931       next_index = tmp;
7932       goto out;
7933     }
7934
7935   return 0;
7936
7937 out:
7938   *miss_next_indexp = next_index;
7939   return 1;
7940 }
7941
7942 uword
7943 unformat_policer_precolor (unformat_input_t * input, va_list * args)
7944 {
7945   u32 *r = va_arg (*args, u32 *);
7946
7947   if (unformat (input, "conform-color"))
7948     *r = POLICE_CONFORM;
7949   else if (unformat (input, "exceed-color"))
7950     *r = POLICE_EXCEED;
7951   else
7952     return 0;
7953
7954   return 1;
7955 }
7956
7957 static int
7958 api_classify_add_del_table (vat_main_t * vam)
7959 {
7960   unformat_input_t *i = vam->input;
7961   vl_api_classify_add_del_table_t *mp;
7962
7963   u32 nbuckets = 2;
7964   u32 skip = ~0;
7965   u32 match = ~0;
7966   int is_add = 1;
7967   u32 table_index = ~0;
7968   u32 next_table_index = ~0;
7969   u32 miss_next_index = ~0;
7970   u32 memory_size = 32 << 20;
7971   u8 *mask = 0;
7972   f64 timeout;
7973
7974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7975     {
7976       if (unformat (i, "del"))
7977         is_add = 0;
7978       else if (unformat (i, "buckets %d", &nbuckets))
7979         ;
7980       else if (unformat (i, "memory_size %d", &memory_size))
7981         ;
7982       else if (unformat (i, "skip %d", &skip))
7983         ;
7984       else if (unformat (i, "match %d", &match))
7985         ;
7986       else if (unformat (i, "table %d", &table_index))
7987         ;
7988       else if (unformat (i, "mask %U", unformat_classify_mask,
7989                          &mask, &skip, &match))
7990         ;
7991       else if (unformat (i, "next-table %d", &next_table_index))
7992         ;
7993       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
7994                          &miss_next_index))
7995         ;
7996       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
7997                          &miss_next_index))
7998         ;
7999       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8000                          &miss_next_index))
8001         ;
8002       else
8003         break;
8004     }
8005
8006   if (is_add && mask == 0)
8007     {
8008       errmsg ("Mask required\n");
8009       return -99;
8010     }
8011
8012   if (is_add && skip == ~0)
8013     {
8014       errmsg ("skip count required\n");
8015       return -99;
8016     }
8017
8018   if (is_add && match == ~0)
8019     {
8020       errmsg ("match count required\n");
8021       return -99;
8022     }
8023
8024   if (!is_add && table_index == ~0)
8025     {
8026       errmsg ("table index required for delete\n");
8027       return -99;
8028     }
8029
8030   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8031
8032   mp->is_add = is_add;
8033   mp->table_index = ntohl (table_index);
8034   mp->nbuckets = ntohl (nbuckets);
8035   mp->memory_size = ntohl (memory_size);
8036   mp->skip_n_vectors = ntohl (skip);
8037   mp->match_n_vectors = ntohl (match);
8038   mp->next_table_index = ntohl (next_table_index);
8039   mp->miss_next_index = ntohl (miss_next_index);
8040   clib_memcpy (mp->mask, mask, vec_len (mask));
8041
8042   vec_free (mask);
8043
8044   S;
8045   W;
8046   /* NOTREACHED */
8047 }
8048
8049 uword
8050 unformat_ip4_match (unformat_input_t * input, va_list * args)
8051 {
8052   u8 **matchp = va_arg (*args, u8 **);
8053   u8 *match = 0;
8054   ip4_header_t *ip;
8055   int version = 0;
8056   u32 version_val;
8057   int hdr_length = 0;
8058   u32 hdr_length_val;
8059   int src = 0, dst = 0;
8060   ip4_address_t src_val, dst_val;
8061   int proto = 0;
8062   u32 proto_val;
8063   int tos = 0;
8064   u32 tos_val;
8065   int length = 0;
8066   u32 length_val;
8067   int fragment_id = 0;
8068   u32 fragment_id_val;
8069   int ttl = 0;
8070   int ttl_val;
8071   int checksum = 0;
8072   u32 checksum_val;
8073
8074   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8075     {
8076       if (unformat (input, "version %d", &version_val))
8077         version = 1;
8078       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8079         hdr_length = 1;
8080       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8081         src = 1;
8082       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8083         dst = 1;
8084       else if (unformat (input, "proto %d", &proto_val))
8085         proto = 1;
8086       else if (unformat (input, "tos %d", &tos_val))
8087         tos = 1;
8088       else if (unformat (input, "length %d", &length_val))
8089         length = 1;
8090       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8091         fragment_id = 1;
8092       else if (unformat (input, "ttl %d", &ttl_val))
8093         ttl = 1;
8094       else if (unformat (input, "checksum %d", &checksum_val))
8095         checksum = 1;
8096       else
8097         break;
8098     }
8099
8100   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8101       + ttl + checksum == 0)
8102     return 0;
8103
8104   /*
8105    * Aligned because we use the real comparison functions
8106    */
8107   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8108
8109   ip = (ip4_header_t *) match;
8110
8111   /* These are realistically matched in practice */
8112   if (src)
8113     ip->src_address.as_u32 = src_val.as_u32;
8114
8115   if (dst)
8116     ip->dst_address.as_u32 = dst_val.as_u32;
8117
8118   if (proto)
8119     ip->protocol = proto_val;
8120
8121
8122   /* These are not, but they're included for completeness */
8123   if (version)
8124     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8125
8126   if (hdr_length)
8127     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8128
8129   if (tos)
8130     ip->tos = tos_val;
8131
8132   if (length)
8133     ip->length = length_val;
8134
8135   if (ttl)
8136     ip->ttl = ttl_val;
8137
8138   if (checksum)
8139     ip->checksum = checksum_val;
8140
8141   *matchp = match;
8142   return 1;
8143 }
8144
8145 uword
8146 unformat_ip6_match (unformat_input_t * input, va_list * args)
8147 {
8148   u8 **matchp = va_arg (*args, u8 **);
8149   u8 *match = 0;
8150   ip6_header_t *ip;
8151   int version = 0;
8152   u32 version_val;
8153   u8 traffic_class = 0;
8154   u32 traffic_class_val = 0;
8155   u8 flow_label = 0;
8156   u8 flow_label_val;
8157   int src = 0, dst = 0;
8158   ip6_address_t src_val, dst_val;
8159   int proto = 0;
8160   u32 proto_val;
8161   int payload_length = 0;
8162   u32 payload_length_val;
8163   int hop_limit = 0;
8164   int hop_limit_val;
8165   u32 ip_version_traffic_class_and_flow_label;
8166
8167   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8168     {
8169       if (unformat (input, "version %d", &version_val))
8170         version = 1;
8171       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8172         traffic_class = 1;
8173       else if (unformat (input, "flow_label %d", &flow_label_val))
8174         flow_label = 1;
8175       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8176         src = 1;
8177       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8178         dst = 1;
8179       else if (unformat (input, "proto %d", &proto_val))
8180         proto = 1;
8181       else if (unformat (input, "payload_length %d", &payload_length_val))
8182         payload_length = 1;
8183       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8184         hop_limit = 1;
8185       else
8186         break;
8187     }
8188
8189   if (version + traffic_class + flow_label + src + dst + proto +
8190       payload_length + hop_limit == 0)
8191     return 0;
8192
8193   /*
8194    * Aligned because we use the real comparison functions
8195    */
8196   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8197
8198   ip = (ip6_header_t *) match;
8199
8200   if (src)
8201     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8202
8203   if (dst)
8204     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8205
8206   if (proto)
8207     ip->protocol = proto_val;
8208
8209   ip_version_traffic_class_and_flow_label = 0;
8210
8211   if (version)
8212     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8213
8214   if (traffic_class)
8215     ip_version_traffic_class_and_flow_label |=
8216       (traffic_class_val & 0xFF) << 20;
8217
8218   if (flow_label)
8219     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8220
8221   ip->ip_version_traffic_class_and_flow_label =
8222     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8223
8224   if (payload_length)
8225     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8226
8227   if (hop_limit)
8228     ip->hop_limit = hop_limit_val;
8229
8230   *matchp = match;
8231   return 1;
8232 }
8233
8234 uword
8235 unformat_l3_match (unformat_input_t * input, va_list * args)
8236 {
8237   u8 **matchp = va_arg (*args, u8 **);
8238
8239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8240     {
8241       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8242         return 1;
8243       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8244         return 1;
8245       else
8246         break;
8247     }
8248   return 0;
8249 }
8250
8251 uword
8252 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8253 {
8254   u8 *tagp = va_arg (*args, u8 *);
8255   u32 tag;
8256
8257   if (unformat (input, "%d", &tag))
8258     {
8259       tagp[0] = (tag >> 8) & 0x0F;
8260       tagp[1] = tag & 0xFF;
8261       return 1;
8262     }
8263
8264   return 0;
8265 }
8266
8267 uword
8268 unformat_l2_match (unformat_input_t * input, va_list * args)
8269 {
8270   u8 **matchp = va_arg (*args, u8 **);
8271   u8 *match = 0;
8272   u8 src = 0;
8273   u8 src_val[6];
8274   u8 dst = 0;
8275   u8 dst_val[6];
8276   u8 proto = 0;
8277   u16 proto_val;
8278   u8 tag1 = 0;
8279   u8 tag1_val[2];
8280   u8 tag2 = 0;
8281   u8 tag2_val[2];
8282   int len = 14;
8283   u8 ignore_tag1 = 0;
8284   u8 ignore_tag2 = 0;
8285   u8 cos1 = 0;
8286   u8 cos2 = 0;
8287   u32 cos1_val = 0;
8288   u32 cos2_val = 0;
8289
8290   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8291     {
8292       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8293         src = 1;
8294       else
8295         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8296         dst = 1;
8297       else if (unformat (input, "proto %U",
8298                          unformat_ethernet_type_host_byte_order, &proto_val))
8299         proto = 1;
8300       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8301         tag1 = 1;
8302       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8303         tag2 = 1;
8304       else if (unformat (input, "ignore-tag1"))
8305         ignore_tag1 = 1;
8306       else if (unformat (input, "ignore-tag2"))
8307         ignore_tag2 = 1;
8308       else if (unformat (input, "cos1 %d", &cos1_val))
8309         cos1 = 1;
8310       else if (unformat (input, "cos2 %d", &cos2_val))
8311         cos2 = 1;
8312       else
8313         break;
8314     }
8315   if ((src + dst + proto + tag1 + tag2 +
8316        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8317     return 0;
8318
8319   if (tag1 || ignore_tag1 || cos1)
8320     len = 18;
8321   if (tag2 || ignore_tag2 || cos2)
8322     len = 22;
8323
8324   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8325
8326   if (dst)
8327     clib_memcpy (match, dst_val, 6);
8328
8329   if (src)
8330     clib_memcpy (match + 6, src_val, 6);
8331
8332   if (tag2)
8333     {
8334       /* inner vlan tag */
8335       match[19] = tag2_val[1];
8336       match[18] = tag2_val[0];
8337       if (cos2)
8338         match[18] |= (cos2_val & 0x7) << 5;
8339       if (proto)
8340         {
8341           match[21] = proto_val & 0xff;
8342           match[20] = proto_val >> 8;
8343         }
8344       if (tag1)
8345         {
8346           match[15] = tag1_val[1];
8347           match[14] = tag1_val[0];
8348         }
8349       if (cos1)
8350         match[14] |= (cos1_val & 0x7) << 5;
8351       *matchp = match;
8352       return 1;
8353     }
8354   if (tag1)
8355     {
8356       match[15] = tag1_val[1];
8357       match[14] = tag1_val[0];
8358       if (proto)
8359         {
8360           match[17] = proto_val & 0xff;
8361           match[16] = proto_val >> 8;
8362         }
8363       if (cos1)
8364         match[14] |= (cos1_val & 0x7) << 5;
8365
8366       *matchp = match;
8367       return 1;
8368     }
8369   if (cos2)
8370     match[18] |= (cos2_val & 0x7) << 5;
8371   if (cos1)
8372     match[14] |= (cos1_val & 0x7) << 5;
8373   if (proto)
8374     {
8375       match[13] = proto_val & 0xff;
8376       match[12] = proto_val >> 8;
8377     }
8378
8379   *matchp = match;
8380   return 1;
8381 }
8382
8383
8384 uword
8385 unformat_classify_match (unformat_input_t * input, va_list * args)
8386 {
8387   u8 **matchp = va_arg (*args, u8 **);
8388   u32 skip_n_vectors = va_arg (*args, u32);
8389   u32 match_n_vectors = va_arg (*args, u32);
8390
8391   u8 *match = 0;
8392   u8 *l2 = 0;
8393   u8 *l3 = 0;
8394
8395   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8396     {
8397       if (unformat (input, "hex %U", unformat_hex_string, &match))
8398         ;
8399       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8400         ;
8401       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8402         ;
8403       else
8404         break;
8405     }
8406
8407   if (match || l2 || l3)
8408     {
8409       if (l2 || l3)
8410         {
8411           /* "Win a free Ethernet header in every packet" */
8412           if (l2 == 0)
8413             vec_validate_aligned (l2, 13, sizeof (u32x4));
8414           match = l2;
8415           if (vec_len (l3))
8416             {
8417               vec_append_aligned (match, l3, sizeof (u32x4));
8418               vec_free (l3);
8419             }
8420         }
8421
8422       /* Make sure the vector is big enough even if key is all 0's */
8423       vec_validate_aligned
8424         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8425          sizeof (u32x4));
8426
8427       /* Set size, include skipped vectors */
8428       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8429
8430       *matchp = match;
8431
8432       return 1;
8433     }
8434
8435   return 0;
8436 }
8437
8438 static int
8439 api_classify_add_del_session (vat_main_t * vam)
8440 {
8441   unformat_input_t *i = vam->input;
8442   vl_api_classify_add_del_session_t *mp;
8443   int is_add = 1;
8444   u32 table_index = ~0;
8445   u32 hit_next_index = ~0;
8446   u32 opaque_index = ~0;
8447   u8 *match = 0;
8448   i32 advance = 0;
8449   f64 timeout;
8450   u32 skip_n_vectors = 0;
8451   u32 match_n_vectors = 0;
8452
8453   /*
8454    * Warning: you have to supply skip_n and match_n
8455    * because the API client cant simply look at the classify
8456    * table object.
8457    */
8458
8459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8460     {
8461       if (unformat (i, "del"))
8462         is_add = 0;
8463       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8464                          &hit_next_index))
8465         ;
8466       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8467                          &hit_next_index))
8468         ;
8469       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8470                          &hit_next_index))
8471         ;
8472       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8473         ;
8474       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8475         ;
8476       else if (unformat (i, "opaque-index %d", &opaque_index))
8477         ;
8478       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8479         ;
8480       else if (unformat (i, "match_n %d", &match_n_vectors))
8481         ;
8482       else if (unformat (i, "match %U", unformat_classify_match,
8483                          &match, skip_n_vectors, match_n_vectors))
8484         ;
8485       else if (unformat (i, "advance %d", &advance))
8486         ;
8487       else if (unformat (i, "table-index %d", &table_index))
8488         ;
8489       else
8490         break;
8491     }
8492
8493   if (table_index == ~0)
8494     {
8495       errmsg ("Table index required\n");
8496       return -99;
8497     }
8498
8499   if (is_add && match == 0)
8500     {
8501       errmsg ("Match value required\n");
8502       return -99;
8503     }
8504
8505   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8506
8507   mp->is_add = is_add;
8508   mp->table_index = ntohl (table_index);
8509   mp->hit_next_index = ntohl (hit_next_index);
8510   mp->opaque_index = ntohl (opaque_index);
8511   mp->advance = ntohl (advance);
8512   clib_memcpy (mp->match, match, vec_len (match));
8513   vec_free (match);
8514
8515   S;
8516   W;
8517   /* NOTREACHED */
8518 }
8519
8520 static int
8521 api_classify_set_interface_ip_table (vat_main_t * vam)
8522 {
8523   unformat_input_t *i = vam->input;
8524   vl_api_classify_set_interface_ip_table_t *mp;
8525   f64 timeout;
8526   u32 sw_if_index;
8527   int sw_if_index_set;
8528   u32 table_index = ~0;
8529   u8 is_ipv6 = 0;
8530
8531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8532     {
8533       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8534         sw_if_index_set = 1;
8535       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8536         sw_if_index_set = 1;
8537       else if (unformat (i, "table %d", &table_index))
8538         ;
8539       else
8540         {
8541           clib_warning ("parse error '%U'", format_unformat_error, i);
8542           return -99;
8543         }
8544     }
8545
8546   if (sw_if_index_set == 0)
8547     {
8548       errmsg ("missing interface name or sw_if_index\n");
8549       return -99;
8550     }
8551
8552
8553   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8554
8555   mp->sw_if_index = ntohl (sw_if_index);
8556   mp->table_index = ntohl (table_index);
8557   mp->is_ipv6 = is_ipv6;
8558
8559   S;
8560   W;
8561   /* NOTREACHED */
8562   return 0;
8563 }
8564
8565 static int
8566 api_classify_set_interface_l2_tables (vat_main_t * vam)
8567 {
8568   unformat_input_t *i = vam->input;
8569   vl_api_classify_set_interface_l2_tables_t *mp;
8570   f64 timeout;
8571   u32 sw_if_index;
8572   int sw_if_index_set;
8573   u32 ip4_table_index = ~0;
8574   u32 ip6_table_index = ~0;
8575   u32 other_table_index = ~0;
8576   u32 is_input = 1;
8577
8578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8579     {
8580       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8581         sw_if_index_set = 1;
8582       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8583         sw_if_index_set = 1;
8584       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8585         ;
8586       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8587         ;
8588       else if (unformat (i, "other-table %d", &other_table_index))
8589         ;
8590       else if (unformat (i, "is-input %d", &is_input))
8591         ;
8592       else
8593         {
8594           clib_warning ("parse error '%U'", format_unformat_error, i);
8595           return -99;
8596         }
8597     }
8598
8599   if (sw_if_index_set == 0)
8600     {
8601       errmsg ("missing interface name or sw_if_index\n");
8602       return -99;
8603     }
8604
8605
8606   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8607
8608   mp->sw_if_index = ntohl (sw_if_index);
8609   mp->ip4_table_index = ntohl (ip4_table_index);
8610   mp->ip6_table_index = ntohl (ip6_table_index);
8611   mp->other_table_index = ntohl (other_table_index);
8612   mp->is_input = (u8) is_input;
8613
8614   S;
8615   W;
8616   /* NOTREACHED */
8617   return 0;
8618 }
8619
8620 static int
8621 api_ipfix_enable (vat_main_t * vam)
8622 {
8623   unformat_input_t *i = vam->input;
8624   vl_api_ipfix_enable_t *mp;
8625   ip4_address_t collector_address;
8626   u8 collector_address_set = 0;
8627   u32 collector_port = ~0;
8628   ip4_address_t src_address;
8629   u8 src_address_set = 0;
8630   u32 vrf_id = ~0;
8631   u32 path_mtu = ~0;
8632   u32 template_interval = ~0;
8633   f64 timeout;
8634
8635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8636     {
8637       if (unformat (i, "collector_address %U", unformat_ip4_address,
8638                     &collector_address))
8639         collector_address_set = 1;
8640       else if (unformat (i, "collector_port %d", &collector_port))
8641         ;
8642       else if (unformat (i, "src_address %U", unformat_ip4_address,
8643                          &src_address))
8644         src_address_set = 1;
8645       else if (unformat (i, "vrf_id %d", &vrf_id))
8646         ;
8647       else if (unformat (i, "path_mtu %d", &path_mtu))
8648         ;
8649       else if (unformat (i, "template_interval %d", &template_interval))
8650         ;
8651       else
8652         break;
8653     }
8654
8655   if (collector_address_set == 0)
8656     {
8657       errmsg ("collector_address required\n");
8658       return -99;
8659     }
8660
8661   if (src_address_set == 0)
8662     {
8663       errmsg ("src_address required\n");
8664       return -99;
8665     }
8666
8667   M (IPFIX_ENABLE, ipfix_enable);
8668
8669   memcpy (mp->collector_address, collector_address.data,
8670           sizeof (collector_address.data));
8671   mp->collector_port = htons ((u16) collector_port);
8672   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8673   mp->vrf_id = htonl (vrf_id);
8674   mp->path_mtu = htonl (path_mtu);
8675   mp->template_interval = htonl (template_interval);
8676
8677   S;
8678   W;
8679   /* NOTREACHED */
8680 }
8681
8682 static int
8683 api_get_node_index (vat_main_t * vam)
8684 {
8685   unformat_input_t *i = vam->input;
8686   vl_api_get_node_index_t *mp;
8687   f64 timeout;
8688   u8 *name = 0;
8689
8690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8691     {
8692       if (unformat (i, "node %s", &name))
8693         ;
8694       else
8695         break;
8696     }
8697   if (name == 0)
8698     {
8699       errmsg ("node name required\n");
8700       return -99;
8701     }
8702   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8703     {
8704       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8705       return -99;
8706     }
8707
8708   M (GET_NODE_INDEX, get_node_index);
8709   clib_memcpy (mp->node_name, name, vec_len (name));
8710   vec_free (name);
8711
8712   S;
8713   W;
8714   /* NOTREACHED */
8715   return 0;
8716 }
8717
8718 static int
8719 api_get_next_index (vat_main_t * vam)
8720 {
8721   unformat_input_t *i = vam->input;
8722   vl_api_get_next_index_t *mp;
8723   f64 timeout;
8724   u8 *node_name = 0, *next_node_name = 0;
8725
8726   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8727     {
8728       if (unformat (i, "node-name %s", &node_name))
8729         ;
8730       else if (unformat (i, "next-node-name %s", &next_node_name))
8731         break;
8732     }
8733
8734   if (node_name == 0)
8735     {
8736       errmsg ("node name required\n");
8737       return -99;
8738     }
8739   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
8740     {
8741       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8742       return -99;
8743     }
8744
8745   if (next_node_name == 0)
8746     {
8747       errmsg ("next node name required\n");
8748       return -99;
8749     }
8750   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
8751     {
8752       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
8753       return -99;
8754     }
8755
8756   M (GET_NEXT_INDEX, get_next_index);
8757   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
8758   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
8759   vec_free (node_name);
8760   vec_free (next_node_name);
8761
8762   S;
8763   W;
8764   /* NOTREACHED */
8765   return 0;
8766 }
8767
8768 static int
8769 api_add_node_next (vat_main_t * vam)
8770 {
8771   unformat_input_t *i = vam->input;
8772   vl_api_add_node_next_t *mp;
8773   f64 timeout;
8774   u8 *name = 0;
8775   u8 *next = 0;
8776
8777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8778     {
8779       if (unformat (i, "node %s", &name))
8780         ;
8781       else if (unformat (i, "next %s", &next))
8782         ;
8783       else
8784         break;
8785     }
8786   if (name == 0)
8787     {
8788       errmsg ("node name required\n");
8789       return -99;
8790     }
8791   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8792     {
8793       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8794       return -99;
8795     }
8796   if (next == 0)
8797     {
8798       errmsg ("next node required\n");
8799       return -99;
8800     }
8801   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
8802     {
8803       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
8804       return -99;
8805     }
8806
8807   M (ADD_NODE_NEXT, add_node_next);
8808   clib_memcpy (mp->node_name, name, vec_len (name));
8809   clib_memcpy (mp->next_name, next, vec_len (next));
8810   vec_free (name);
8811   vec_free (next);
8812
8813   S;
8814   W;
8815   /* NOTREACHED */
8816   return 0;
8817 }
8818
8819 static int
8820 api_l2tpv3_create_tunnel (vat_main_t * vam)
8821 {
8822   unformat_input_t *i = vam->input;
8823   ip6_address_t client_address, our_address;
8824   int client_address_set = 0;
8825   int our_address_set = 0;
8826   u32 local_session_id = 0;
8827   u32 remote_session_id = 0;
8828   u64 local_cookie = 0;
8829   u64 remote_cookie = 0;
8830   u8 l2_sublayer_present = 0;
8831   vl_api_l2tpv3_create_tunnel_t *mp;
8832   f64 timeout;
8833
8834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8835     {
8836       if (unformat (i, "client_address %U", unformat_ip6_address,
8837                     &client_address))
8838         client_address_set = 1;
8839       else if (unformat (i, "our_address %U", unformat_ip6_address,
8840                          &our_address))
8841         our_address_set = 1;
8842       else if (unformat (i, "local_session_id %d", &local_session_id))
8843         ;
8844       else if (unformat (i, "remote_session_id %d", &remote_session_id))
8845         ;
8846       else if (unformat (i, "local_cookie %lld", &local_cookie))
8847         ;
8848       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
8849         ;
8850       else if (unformat (i, "l2-sublayer-present"))
8851         l2_sublayer_present = 1;
8852       else
8853         break;
8854     }
8855
8856   if (client_address_set == 0)
8857     {
8858       errmsg ("client_address required\n");
8859       return -99;
8860     }
8861
8862   if (our_address_set == 0)
8863     {
8864       errmsg ("our_address required\n");
8865       return -99;
8866     }
8867
8868   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
8869
8870   clib_memcpy (mp->client_address, client_address.as_u8,
8871                sizeof (mp->client_address));
8872
8873   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
8874
8875   mp->local_session_id = ntohl (local_session_id);
8876   mp->remote_session_id = ntohl (remote_session_id);
8877   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
8878   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
8879   mp->l2_sublayer_present = l2_sublayer_present;
8880   mp->is_ipv6 = 1;
8881
8882   S;
8883   W;
8884   /* NOTREACHED */
8885   return 0;
8886 }
8887
8888 static int
8889 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
8890 {
8891   unformat_input_t *i = vam->input;
8892   u32 sw_if_index;
8893   u8 sw_if_index_set = 0;
8894   u64 new_local_cookie = 0;
8895   u64 new_remote_cookie = 0;
8896   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
8897   f64 timeout;
8898
8899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8900     {
8901       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8902         sw_if_index_set = 1;
8903       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8904         sw_if_index_set = 1;
8905       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
8906         ;
8907       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
8908         ;
8909       else
8910         break;
8911     }
8912
8913   if (sw_if_index_set == 0)
8914     {
8915       errmsg ("missing interface name or sw_if_index\n");
8916       return -99;
8917     }
8918
8919   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
8920
8921   mp->sw_if_index = ntohl (sw_if_index);
8922   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
8923   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
8924
8925   S;
8926   W;
8927   /* NOTREACHED */
8928   return 0;
8929 }
8930
8931 static int
8932 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
8933 {
8934   unformat_input_t *i = vam->input;
8935   vl_api_l2tpv3_interface_enable_disable_t *mp;
8936   f64 timeout;
8937   u32 sw_if_index;
8938   u8 sw_if_index_set = 0;
8939   u8 enable_disable = 1;
8940
8941   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8942     {
8943       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8944         sw_if_index_set = 1;
8945       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8946         sw_if_index_set = 1;
8947       else if (unformat (i, "enable"))
8948         enable_disable = 1;
8949       else if (unformat (i, "disable"))
8950         enable_disable = 0;
8951       else
8952         break;
8953     }
8954
8955   if (sw_if_index_set == 0)
8956     {
8957       errmsg ("missing interface name or sw_if_index\n");
8958       return -99;
8959     }
8960
8961   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
8962
8963   mp->sw_if_index = ntohl (sw_if_index);
8964   mp->enable_disable = enable_disable;
8965
8966   S;
8967   W;
8968   /* NOTREACHED */
8969   return 0;
8970 }
8971
8972 static int
8973 api_l2tpv3_set_lookup_key (vat_main_t * vam)
8974 {
8975   unformat_input_t *i = vam->input;
8976   vl_api_l2tpv3_set_lookup_key_t *mp;
8977   f64 timeout;
8978   u8 key = ~0;
8979
8980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8981     {
8982       if (unformat (i, "lookup_v6_src"))
8983         key = L2T_LOOKUP_SRC_ADDRESS;
8984       else if (unformat (i, "lookup_v6_dst"))
8985         key = L2T_LOOKUP_DST_ADDRESS;
8986       else if (unformat (i, "lookup_session_id"))
8987         key = L2T_LOOKUP_SESSION_ID;
8988       else
8989         break;
8990     }
8991
8992   if (key == (u8) ~ 0)
8993     {
8994       errmsg ("l2tp session lookup key unset\n");
8995       return -99;
8996     }
8997
8998   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
8999
9000   mp->key = key;
9001
9002   S;
9003   W;
9004   /* NOTREACHED */
9005   return 0;
9006 }
9007
9008 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9009   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9010 {
9011   vat_main_t *vam = &vat_main;
9012
9013   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9014            format_ip6_address, mp->our_address,
9015            format_ip6_address, mp->client_address,
9016            clib_net_to_host_u32 (mp->sw_if_index));
9017
9018   fformat (vam->ofp,
9019            "   local cookies %016llx %016llx remote cookie %016llx\n",
9020            clib_net_to_host_u64 (mp->local_cookie[0]),
9021            clib_net_to_host_u64 (mp->local_cookie[1]),
9022            clib_net_to_host_u64 (mp->remote_cookie));
9023
9024   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9025            clib_net_to_host_u32 (mp->local_session_id),
9026            clib_net_to_host_u32 (mp->remote_session_id));
9027
9028   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9029            mp->l2_sublayer_present ? "preset" : "absent");
9030
9031 }
9032
9033 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9034   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9035 {
9036   vat_main_t *vam = &vat_main;
9037   vat_json_node_t *node = NULL;
9038   struct in6_addr addr;
9039
9040   if (VAT_JSON_ARRAY != vam->json_tree.type)
9041     {
9042       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9043       vat_json_init_array (&vam->json_tree);
9044     }
9045   node = vat_json_array_add (&vam->json_tree);
9046
9047   vat_json_init_object (node);
9048
9049   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9050   vat_json_object_add_ip6 (node, "our_address", addr);
9051   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9052   vat_json_object_add_ip6 (node, "client_address", addr);
9053
9054   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9055   vat_json_init_array (lc);
9056   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9057   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9058   vat_json_object_add_uint (node, "remote_cookie",
9059                             clib_net_to_host_u64 (mp->remote_cookie));
9060
9061   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9062   vat_json_object_add_uint (node, "local_session_id",
9063                             clib_net_to_host_u32 (mp->local_session_id));
9064   vat_json_object_add_uint (node, "remote_session_id",
9065                             clib_net_to_host_u32 (mp->remote_session_id));
9066   vat_json_object_add_string_copy (node, "l2_sublayer",
9067                                    mp->l2_sublayer_present ? (u8 *) "present"
9068                                    : (u8 *) "absent");
9069 }
9070
9071 static int
9072 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9073 {
9074   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9075   f64 timeout;
9076
9077   /* Get list of l2tpv3-tunnel interfaces */
9078   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9079   S;
9080
9081   /* Use a control ping for synchronization */
9082   {
9083     vl_api_control_ping_t *mp;
9084     M (CONTROL_PING, control_ping);
9085     S;
9086   }
9087   W;
9088 }
9089
9090
9091 static void vl_api_sw_interface_tap_details_t_handler
9092   (vl_api_sw_interface_tap_details_t * mp)
9093 {
9094   vat_main_t *vam = &vat_main;
9095
9096   fformat (vam->ofp, "%-16s %d\n",
9097            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9098 }
9099
9100 static void vl_api_sw_interface_tap_details_t_handler_json
9101   (vl_api_sw_interface_tap_details_t * mp)
9102 {
9103   vat_main_t *vam = &vat_main;
9104   vat_json_node_t *node = NULL;
9105
9106   if (VAT_JSON_ARRAY != vam->json_tree.type)
9107     {
9108       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9109       vat_json_init_array (&vam->json_tree);
9110     }
9111   node = vat_json_array_add (&vam->json_tree);
9112
9113   vat_json_init_object (node);
9114   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9115   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9116 }
9117
9118 static int
9119 api_sw_interface_tap_dump (vat_main_t * vam)
9120 {
9121   vl_api_sw_interface_tap_dump_t *mp;
9122   f64 timeout;
9123
9124   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9125   /* Get list of tap interfaces */
9126   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9127   S;
9128
9129   /* Use a control ping for synchronization */
9130   {
9131     vl_api_control_ping_t *mp;
9132     M (CONTROL_PING, control_ping);
9133     S;
9134   }
9135   W;
9136 }
9137
9138 static uword unformat_vxlan_decap_next
9139   (unformat_input_t * input, va_list * args)
9140 {
9141   u32 *result = va_arg (*args, u32 *);
9142   u32 tmp;
9143
9144   if (unformat (input, "drop"))
9145     *result = VXLAN_INPUT_NEXT_DROP;
9146   else if (unformat (input, "ip4"))
9147     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9148   else if (unformat (input, "ip6"))
9149     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9150   else if (unformat (input, "l2"))
9151     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9152   else if (unformat (input, "%d", &tmp))
9153     *result = tmp;
9154   else
9155     return 0;
9156   return 1;
9157 }
9158
9159 static int
9160 api_vxlan_add_del_tunnel (vat_main_t * vam)
9161 {
9162   unformat_input_t *line_input = vam->input;
9163   vl_api_vxlan_add_del_tunnel_t *mp;
9164   f64 timeout;
9165   ip4_address_t src4, dst4;
9166   ip6_address_t src6, dst6;
9167   u8 is_add = 1;
9168   u8 ipv4_set = 0, ipv6_set = 0;
9169   u8 src_set = 0;
9170   u8 dst_set = 0;
9171   u32 encap_vrf_id = 0;
9172   u32 decap_next_index = ~0;
9173   u32 vni = 0;
9174
9175   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9176     {
9177       if (unformat (line_input, "del"))
9178         is_add = 0;
9179       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9180         {
9181           ipv4_set = 1;
9182           src_set = 1;
9183         }
9184       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9185         {
9186           ipv4_set = 1;
9187           dst_set = 1;
9188         }
9189       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9190         {
9191           ipv6_set = 1;
9192           src_set = 1;
9193         }
9194       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9195         {
9196           ipv6_set = 1;
9197           dst_set = 1;
9198         }
9199       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9200         ;
9201       else if (unformat (line_input, "decap-next %U",
9202                          unformat_vxlan_decap_next, &decap_next_index))
9203         ;
9204       else if (unformat (line_input, "vni %d", &vni))
9205         ;
9206       else
9207         {
9208           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9209           return -99;
9210         }
9211     }
9212
9213   if (src_set == 0)
9214     {
9215       errmsg ("tunnel src address not specified\n");
9216       return -99;
9217     }
9218   if (dst_set == 0)
9219     {
9220       errmsg ("tunnel dst address not specified\n");
9221       return -99;
9222     }
9223
9224   if (ipv4_set && ipv6_set)
9225     {
9226       errmsg ("both IPv4 and IPv6 addresses specified");
9227       return -99;
9228     }
9229
9230   if ((vni == 0) || (vni >> 24))
9231     {
9232       errmsg ("vni not specified or out of range\n");
9233       return -99;
9234     }
9235
9236   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9237
9238   if (ipv6_set)
9239     {
9240       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9241       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9242     }
9243   else
9244     {
9245       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9246       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9247     }
9248   mp->encap_vrf_id = ntohl (encap_vrf_id);
9249   mp->decap_next_index = ntohl (decap_next_index);
9250   mp->vni = ntohl (vni);
9251   mp->is_add = is_add;
9252   mp->is_ipv6 = ipv6_set;
9253
9254   S;
9255   W;
9256   /* NOTREACHED */
9257   return 0;
9258 }
9259
9260 static void vl_api_vxlan_tunnel_details_t_handler
9261   (vl_api_vxlan_tunnel_details_t * mp)
9262 {
9263   vat_main_t *vam = &vat_main;
9264
9265   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9266            ntohl (mp->sw_if_index),
9267            format_ip46_address, &(mp->src_address[0]),
9268            IP46_TYPE_ANY,
9269            format_ip46_address, &(mp->dst_address[0]),
9270            IP46_TYPE_ANY,
9271            ntohl (mp->encap_vrf_id),
9272            ntohl (mp->decap_next_index), ntohl (mp->vni));
9273 }
9274
9275 static void vl_api_vxlan_tunnel_details_t_handler_json
9276   (vl_api_vxlan_tunnel_details_t * mp)
9277 {
9278   vat_main_t *vam = &vat_main;
9279   vat_json_node_t *node = NULL;
9280   struct in_addr ip4;
9281   struct in6_addr ip6;
9282
9283   if (VAT_JSON_ARRAY != vam->json_tree.type)
9284     {
9285       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9286       vat_json_init_array (&vam->json_tree);
9287     }
9288   node = vat_json_array_add (&vam->json_tree);
9289
9290   vat_json_init_object (node);
9291   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9292   if (mp->is_ipv6)
9293     {
9294       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9295       vat_json_object_add_ip6 (node, "src_address", ip6);
9296       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9297       vat_json_object_add_ip6 (node, "dst_address", ip6);
9298     }
9299   else
9300     {
9301       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9302       vat_json_object_add_ip4 (node, "src_address", ip4);
9303       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9304       vat_json_object_add_ip4 (node, "dst_address", ip4);
9305     }
9306   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9307   vat_json_object_add_uint (node, "decap_next_index",
9308                             ntohl (mp->decap_next_index));
9309   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9310   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9311 }
9312
9313 static int
9314 api_vxlan_tunnel_dump (vat_main_t * vam)
9315 {
9316   unformat_input_t *i = vam->input;
9317   vl_api_vxlan_tunnel_dump_t *mp;
9318   f64 timeout;
9319   u32 sw_if_index;
9320   u8 sw_if_index_set = 0;
9321
9322   /* Parse args required to build the message */
9323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9324     {
9325       if (unformat (i, "sw_if_index %d", &sw_if_index))
9326         sw_if_index_set = 1;
9327       else
9328         break;
9329     }
9330
9331   if (sw_if_index_set == 0)
9332     {
9333       sw_if_index = ~0;
9334     }
9335
9336   if (!vam->json_output)
9337     {
9338       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9339                "sw_if_index", "src_address", "dst_address",
9340                "encap_vrf_id", "decap_next_index", "vni");
9341     }
9342
9343   /* Get list of vxlan-tunnel interfaces */
9344   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9345
9346   mp->sw_if_index = htonl (sw_if_index);
9347
9348   S;
9349
9350   /* Use a control ping for synchronization */
9351   {
9352     vl_api_control_ping_t *mp;
9353     M (CONTROL_PING, control_ping);
9354     S;
9355   }
9356   W;
9357 }
9358
9359 static int
9360 api_gre_add_del_tunnel (vat_main_t * vam)
9361 {
9362   unformat_input_t *line_input = vam->input;
9363   vl_api_gre_add_del_tunnel_t *mp;
9364   f64 timeout;
9365   ip4_address_t src4, dst4;
9366   u8 is_add = 1;
9367   u8 src_set = 0;
9368   u8 dst_set = 0;
9369   u32 outer_fib_id = 0;
9370
9371   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9372     {
9373       if (unformat (line_input, "del"))
9374         is_add = 0;
9375       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9376         src_set = 1;
9377       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9378         dst_set = 1;
9379       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9380         ;
9381       else
9382         {
9383           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9384           return -99;
9385         }
9386     }
9387
9388   if (src_set == 0)
9389     {
9390       errmsg ("tunnel src address not specified\n");
9391       return -99;
9392     }
9393   if (dst_set == 0)
9394     {
9395       errmsg ("tunnel dst address not specified\n");
9396       return -99;
9397     }
9398
9399
9400   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9401
9402   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9403   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9404   mp->outer_fib_id = ntohl (outer_fib_id);
9405   mp->is_add = is_add;
9406
9407   S;
9408   W;
9409   /* NOTREACHED */
9410   return 0;
9411 }
9412
9413 static void vl_api_gre_tunnel_details_t_handler
9414   (vl_api_gre_tunnel_details_t * mp)
9415 {
9416   vat_main_t *vam = &vat_main;
9417
9418   fformat (vam->ofp, "%11d%15U%15U%14d\n",
9419            ntohl (mp->sw_if_index),
9420            format_ip4_address, &mp->src_address,
9421            format_ip4_address, &mp->dst_address, ntohl (mp->outer_fib_id));
9422 }
9423
9424 static void vl_api_gre_tunnel_details_t_handler_json
9425   (vl_api_gre_tunnel_details_t * mp)
9426 {
9427   vat_main_t *vam = &vat_main;
9428   vat_json_node_t *node = NULL;
9429   struct in_addr ip4;
9430
9431   if (VAT_JSON_ARRAY != vam->json_tree.type)
9432     {
9433       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9434       vat_json_init_array (&vam->json_tree);
9435     }
9436   node = vat_json_array_add (&vam->json_tree);
9437
9438   vat_json_init_object (node);
9439   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9440   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9441   vat_json_object_add_ip4 (node, "src_address", ip4);
9442   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9443   vat_json_object_add_ip4 (node, "dst_address", ip4);
9444   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9445 }
9446
9447 static int
9448 api_gre_tunnel_dump (vat_main_t * vam)
9449 {
9450   unformat_input_t *i = vam->input;
9451   vl_api_gre_tunnel_dump_t *mp;
9452   f64 timeout;
9453   u32 sw_if_index;
9454   u8 sw_if_index_set = 0;
9455
9456   /* Parse args required to build the message */
9457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9458     {
9459       if (unformat (i, "sw_if_index %d", &sw_if_index))
9460         sw_if_index_set = 1;
9461       else
9462         break;
9463     }
9464
9465   if (sw_if_index_set == 0)
9466     {
9467       sw_if_index = ~0;
9468     }
9469
9470   if (!vam->json_output)
9471     {
9472       fformat (vam->ofp, "%11s%15s%15s%14s\n",
9473                "sw_if_index", "src_address", "dst_address", "outer_fib_id");
9474     }
9475
9476   /* Get list of gre-tunnel interfaces */
9477   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9478
9479   mp->sw_if_index = htonl (sw_if_index);
9480
9481   S;
9482
9483   /* Use a control ping for synchronization */
9484   {
9485     vl_api_control_ping_t *mp;
9486     M (CONTROL_PING, control_ping);
9487     S;
9488   }
9489   W;
9490 }
9491
9492 static int
9493 api_l2_fib_clear_table (vat_main_t * vam)
9494 {
9495 //  unformat_input_t * i = vam->input;
9496   vl_api_l2_fib_clear_table_t *mp;
9497   f64 timeout;
9498
9499   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9500
9501   S;
9502   W;
9503   /* NOTREACHED */
9504   return 0;
9505 }
9506
9507 static int
9508 api_l2_interface_efp_filter (vat_main_t * vam)
9509 {
9510   unformat_input_t *i = vam->input;
9511   vl_api_l2_interface_efp_filter_t *mp;
9512   f64 timeout;
9513   u32 sw_if_index;
9514   u8 enable = 1;
9515   u8 sw_if_index_set = 0;
9516
9517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9518     {
9519       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9520         sw_if_index_set = 1;
9521       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9522         sw_if_index_set = 1;
9523       else if (unformat (i, "enable"))
9524         enable = 1;
9525       else if (unformat (i, "disable"))
9526         enable = 0;
9527       else
9528         {
9529           clib_warning ("parse error '%U'", format_unformat_error, i);
9530           return -99;
9531         }
9532     }
9533
9534   if (sw_if_index_set == 0)
9535     {
9536       errmsg ("missing sw_if_index\n");
9537       return -99;
9538     }
9539
9540   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9541
9542   mp->sw_if_index = ntohl (sw_if_index);
9543   mp->enable_disable = enable;
9544
9545   S;
9546   W;
9547   /* NOTREACHED */
9548   return 0;
9549 }
9550
9551 #define foreach_vtr_op                          \
9552 _("disable",  L2_VTR_DISABLED)                  \
9553 _("push-1",  L2_VTR_PUSH_1)                     \
9554 _("push-2",  L2_VTR_PUSH_2)                     \
9555 _("pop-1",  L2_VTR_POP_1)                       \
9556 _("pop-2",  L2_VTR_POP_2)                       \
9557 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9558 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9559 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9560 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9561
9562 static int
9563 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9564 {
9565   unformat_input_t *i = vam->input;
9566   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9567   f64 timeout;
9568   u32 sw_if_index;
9569   u8 sw_if_index_set = 0;
9570   u8 vtr_op_set = 0;
9571   u32 vtr_op = 0;
9572   u32 push_dot1q = 1;
9573   u32 tag1 = ~0;
9574   u32 tag2 = ~0;
9575
9576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9577     {
9578       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9579         sw_if_index_set = 1;
9580       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9581         sw_if_index_set = 1;
9582       else if (unformat (i, "vtr_op %d", &vtr_op))
9583         vtr_op_set = 1;
9584 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9585       foreach_vtr_op
9586 #undef _
9587         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9588         ;
9589       else if (unformat (i, "tag1 %d", &tag1))
9590         ;
9591       else if (unformat (i, "tag2 %d", &tag2))
9592         ;
9593       else
9594         {
9595           clib_warning ("parse error '%U'", format_unformat_error, i);
9596           return -99;
9597         }
9598     }
9599
9600   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9601     {
9602       errmsg ("missing vtr operation or sw_if_index\n");
9603       return -99;
9604     }
9605
9606   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
9607     mp->sw_if_index = ntohl (sw_if_index);
9608   mp->vtr_op = ntohl (vtr_op);
9609   mp->push_dot1q = ntohl (push_dot1q);
9610   mp->tag1 = ntohl (tag1);
9611   mp->tag2 = ntohl (tag2);
9612
9613   S;
9614   W;
9615   /* NOTREACHED */
9616   return 0;
9617 }
9618
9619 static int
9620 api_create_vhost_user_if (vat_main_t * vam)
9621 {
9622   unformat_input_t *i = vam->input;
9623   vl_api_create_vhost_user_if_t *mp;
9624   f64 timeout;
9625   u8 *file_name;
9626   u8 is_server = 0;
9627   u8 file_name_set = 0;
9628   u32 custom_dev_instance = ~0;
9629   u8 hwaddr[6];
9630   u8 use_custom_mac = 0;
9631
9632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9633     {
9634       if (unformat (i, "socket %s", &file_name))
9635         {
9636           file_name_set = 1;
9637         }
9638       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9639         ;
9640       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9641         use_custom_mac = 1;
9642       else if (unformat (i, "server"))
9643         is_server = 1;
9644       else
9645         break;
9646     }
9647
9648   if (file_name_set == 0)
9649     {
9650       errmsg ("missing socket file name\n");
9651       return -99;
9652     }
9653
9654   if (vec_len (file_name) > 255)
9655     {
9656       errmsg ("socket file name too long\n");
9657       return -99;
9658     }
9659   vec_add1 (file_name, 0);
9660
9661   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
9662
9663   mp->is_server = is_server;
9664   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9665   vec_free (file_name);
9666   if (custom_dev_instance != ~0)
9667     {
9668       mp->renumber = 1;
9669       mp->custom_dev_instance = ntohl (custom_dev_instance);
9670     }
9671   mp->use_custom_mac = use_custom_mac;
9672   clib_memcpy (mp->mac_address, hwaddr, 6);
9673
9674   S;
9675   W;
9676   /* NOTREACHED */
9677   return 0;
9678 }
9679
9680 static int
9681 api_modify_vhost_user_if (vat_main_t * vam)
9682 {
9683   unformat_input_t *i = vam->input;
9684   vl_api_modify_vhost_user_if_t *mp;
9685   f64 timeout;
9686   u8 *file_name;
9687   u8 is_server = 0;
9688   u8 file_name_set = 0;
9689   u32 custom_dev_instance = ~0;
9690   u8 sw_if_index_set = 0;
9691   u32 sw_if_index = (u32) ~ 0;
9692
9693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9694     {
9695       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9696         sw_if_index_set = 1;
9697       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9698         sw_if_index_set = 1;
9699       else if (unformat (i, "socket %s", &file_name))
9700         {
9701           file_name_set = 1;
9702         }
9703       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9704         ;
9705       else if (unformat (i, "server"))
9706         is_server = 1;
9707       else
9708         break;
9709     }
9710
9711   if (sw_if_index_set == 0)
9712     {
9713       errmsg ("missing sw_if_index or interface name\n");
9714       return -99;
9715     }
9716
9717   if (file_name_set == 0)
9718     {
9719       errmsg ("missing socket file name\n");
9720       return -99;
9721     }
9722
9723   if (vec_len (file_name) > 255)
9724     {
9725       errmsg ("socket file name too long\n");
9726       return -99;
9727     }
9728   vec_add1 (file_name, 0);
9729
9730   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
9731
9732   mp->sw_if_index = ntohl (sw_if_index);
9733   mp->is_server = is_server;
9734   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9735   vec_free (file_name);
9736   if (custom_dev_instance != ~0)
9737     {
9738       mp->renumber = 1;
9739       mp->custom_dev_instance = ntohl (custom_dev_instance);
9740     }
9741
9742   S;
9743   W;
9744   /* NOTREACHED */
9745   return 0;
9746 }
9747
9748 static int
9749 api_delete_vhost_user_if (vat_main_t * vam)
9750 {
9751   unformat_input_t *i = vam->input;
9752   vl_api_delete_vhost_user_if_t *mp;
9753   f64 timeout;
9754   u32 sw_if_index = ~0;
9755   u8 sw_if_index_set = 0;
9756
9757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9758     {
9759       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9760         sw_if_index_set = 1;
9761       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9762         sw_if_index_set = 1;
9763       else
9764         break;
9765     }
9766
9767   if (sw_if_index_set == 0)
9768     {
9769       errmsg ("missing sw_if_index or interface name\n");
9770       return -99;
9771     }
9772
9773
9774   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
9775
9776   mp->sw_if_index = ntohl (sw_if_index);
9777
9778   S;
9779   W;
9780   /* NOTREACHED */
9781   return 0;
9782 }
9783
9784 static void vl_api_sw_interface_vhost_user_details_t_handler
9785   (vl_api_sw_interface_vhost_user_details_t * mp)
9786 {
9787   vat_main_t *vam = &vat_main;
9788
9789   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
9790            (char *) mp->interface_name,
9791            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
9792            clib_net_to_host_u64 (mp->features), mp->is_server,
9793            ntohl (mp->num_regions), (char *) mp->sock_filename);
9794   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
9795 }
9796
9797 static void vl_api_sw_interface_vhost_user_details_t_handler_json
9798   (vl_api_sw_interface_vhost_user_details_t * mp)
9799 {
9800   vat_main_t *vam = &vat_main;
9801   vat_json_node_t *node = NULL;
9802
9803   if (VAT_JSON_ARRAY != vam->json_tree.type)
9804     {
9805       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9806       vat_json_init_array (&vam->json_tree);
9807     }
9808   node = vat_json_array_add (&vam->json_tree);
9809
9810   vat_json_init_object (node);
9811   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9812   vat_json_object_add_string_copy (node, "interface_name",
9813                                    mp->interface_name);
9814   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
9815                             ntohl (mp->virtio_net_hdr_sz));
9816   vat_json_object_add_uint (node, "features",
9817                             clib_net_to_host_u64 (mp->features));
9818   vat_json_object_add_uint (node, "is_server", mp->is_server);
9819   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
9820   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
9821   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
9822 }
9823
9824 static int
9825 api_sw_interface_vhost_user_dump (vat_main_t * vam)
9826 {
9827   vl_api_sw_interface_vhost_user_dump_t *mp;
9828   f64 timeout;
9829   fformat (vam->ofp,
9830            "Interface name           idx hdr_sz features server regions filename\n");
9831
9832   /* Get list of vhost-user interfaces */
9833   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
9834   S;
9835
9836   /* Use a control ping for synchronization */
9837   {
9838     vl_api_control_ping_t *mp;
9839     M (CONTROL_PING, control_ping);
9840     S;
9841   }
9842   W;
9843 }
9844
9845 static int
9846 api_show_version (vat_main_t * vam)
9847 {
9848   vl_api_show_version_t *mp;
9849   f64 timeout;
9850
9851   M (SHOW_VERSION, show_version);
9852
9853   S;
9854   W;
9855   /* NOTREACHED */
9856   return 0;
9857 }
9858
9859
9860 static int
9861 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
9862 {
9863   unformat_input_t *line_input = vam->input;
9864   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
9865   f64 timeout;
9866   ip4_address_t local4, remote4;
9867   ip6_address_t local6, remote6;
9868   u8 is_add = 1;
9869   u8 ipv4_set = 0, ipv6_set = 0;
9870   u8 local_set = 0;
9871   u8 remote_set = 0;
9872   u32 encap_vrf_id = 0;
9873   u32 decap_vrf_id = 0;
9874   u8 protocol = ~0;
9875   u32 vni;
9876   u8 vni_set = 0;
9877
9878   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9879     {
9880       if (unformat (line_input, "del"))
9881         is_add = 0;
9882       else if (unformat (line_input, "local %U",
9883                          unformat_ip4_address, &local4))
9884         {
9885           local_set = 1;
9886           ipv4_set = 1;
9887         }
9888       else if (unformat (line_input, "remote %U",
9889                          unformat_ip4_address, &remote4))
9890         {
9891           remote_set = 1;
9892           ipv4_set = 1;
9893         }
9894       else if (unformat (line_input, "local %U",
9895                          unformat_ip6_address, &local6))
9896         {
9897           local_set = 1;
9898           ipv6_set = 1;
9899         }
9900       else if (unformat (line_input, "remote %U",
9901                          unformat_ip6_address, &remote6))
9902         {
9903           remote_set = 1;
9904           ipv6_set = 1;
9905         }
9906       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9907         ;
9908       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
9909         ;
9910       else if (unformat (line_input, "vni %d", &vni))
9911         vni_set = 1;
9912       else if (unformat (line_input, "next-ip4"))
9913         protocol = 1;
9914       else if (unformat (line_input, "next-ip6"))
9915         protocol = 2;
9916       else if (unformat (line_input, "next-ethernet"))
9917         protocol = 3;
9918       else if (unformat (line_input, "next-nsh"))
9919         protocol = 4;
9920       else
9921         {
9922           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9923           return -99;
9924         }
9925     }
9926
9927   if (local_set == 0)
9928     {
9929       errmsg ("tunnel local address not specified\n");
9930       return -99;
9931     }
9932   if (remote_set == 0)
9933     {
9934       errmsg ("tunnel remote address not specified\n");
9935       return -99;
9936     }
9937   if (ipv4_set && ipv6_set)
9938     {
9939       errmsg ("both IPv4 and IPv6 addresses specified");
9940       return -99;
9941     }
9942
9943   if (vni_set == 0)
9944     {
9945       errmsg ("vni not specified\n");
9946       return -99;
9947     }
9948
9949   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
9950
9951
9952   if (ipv6_set)
9953     {
9954       clib_memcpy (&mp->local, &local6, sizeof (local6));
9955       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
9956     }
9957   else
9958     {
9959       clib_memcpy (&mp->local, &local4, sizeof (local4));
9960       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
9961     }
9962
9963   mp->encap_vrf_id = ntohl (encap_vrf_id);
9964   mp->decap_vrf_id = ntohl (decap_vrf_id);
9965   mp->protocol = ntohl (protocol);
9966   mp->vni = ntohl (vni);
9967   mp->is_add = is_add;
9968   mp->is_ipv6 = ipv6_set;
9969
9970   S;
9971   W;
9972   /* NOTREACHED */
9973   return 0;
9974 }
9975
9976 static void vl_api_vxlan_gpe_tunnel_details_t_handler
9977   (vl_api_vxlan_gpe_tunnel_details_t * mp)
9978 {
9979   vat_main_t *vam = &vat_main;
9980
9981   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
9982            ntohl (mp->sw_if_index),
9983            format_ip46_address, &(mp->local[0]),
9984            format_ip46_address, &(mp->remote[0]),
9985            ntohl (mp->vni),
9986            ntohl (mp->protocol),
9987            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
9988 }
9989
9990 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
9991   (vl_api_vxlan_gpe_tunnel_details_t * mp)
9992 {
9993   vat_main_t *vam = &vat_main;
9994   vat_json_node_t *node = NULL;
9995   struct in_addr ip4;
9996   struct in6_addr ip6;
9997
9998   if (VAT_JSON_ARRAY != vam->json_tree.type)
9999     {
10000       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10001       vat_json_init_array (&vam->json_tree);
10002     }
10003   node = vat_json_array_add (&vam->json_tree);
10004
10005   vat_json_init_object (node);
10006   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10007   if (mp->is_ipv6)
10008     {
10009       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10010       vat_json_object_add_ip6 (node, "local", ip6);
10011       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10012       vat_json_object_add_ip6 (node, "remote", ip6);
10013     }
10014   else
10015     {
10016       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10017       vat_json_object_add_ip4 (node, "local", ip4);
10018       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10019       vat_json_object_add_ip4 (node, "remote", ip4);
10020     }
10021   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10022   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10023   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10024   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10025   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10026 }
10027
10028 static int
10029 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10030 {
10031   unformat_input_t *i = vam->input;
10032   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10033   f64 timeout;
10034   u32 sw_if_index;
10035   u8 sw_if_index_set = 0;
10036
10037   /* Parse args required to build the message */
10038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10039     {
10040       if (unformat (i, "sw_if_index %d", &sw_if_index))
10041         sw_if_index_set = 1;
10042       else
10043         break;
10044     }
10045
10046   if (sw_if_index_set == 0)
10047     {
10048       sw_if_index = ~0;
10049     }
10050
10051   if (!vam->json_output)
10052     {
10053       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10054                "sw_if_index", "local", "remote", "vni",
10055                "protocol", "encap_vrf_id", "decap_vrf_id");
10056     }
10057
10058   /* Get list of vxlan-tunnel interfaces */
10059   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10060
10061   mp->sw_if_index = htonl (sw_if_index);
10062
10063   S;
10064
10065   /* Use a control ping for synchronization */
10066   {
10067     vl_api_control_ping_t *mp;
10068     M (CONTROL_PING, control_ping);
10069     S;
10070   }
10071   W;
10072 }
10073
10074 u8 *
10075 format_l2_fib_mac_address (u8 * s, va_list * args)
10076 {
10077   u8 *a = va_arg (*args, u8 *);
10078
10079   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10080                  a[2], a[3], a[4], a[5], a[6], a[7]);
10081 }
10082
10083 static void vl_api_l2_fib_table_entry_t_handler
10084   (vl_api_l2_fib_table_entry_t * mp)
10085 {
10086   vat_main_t *vam = &vat_main;
10087
10088   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10089            "       %d       %d     %d\n",
10090            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10091            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10092            mp->bvi_mac);
10093 }
10094
10095 static void vl_api_l2_fib_table_entry_t_handler_json
10096   (vl_api_l2_fib_table_entry_t * mp)
10097 {
10098   vat_main_t *vam = &vat_main;
10099   vat_json_node_t *node = NULL;
10100
10101   if (VAT_JSON_ARRAY != vam->json_tree.type)
10102     {
10103       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10104       vat_json_init_array (&vam->json_tree);
10105     }
10106   node = vat_json_array_add (&vam->json_tree);
10107
10108   vat_json_init_object (node);
10109   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10110   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10111   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10112   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10113   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10114   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10115 }
10116
10117 static int
10118 api_l2_fib_table_dump (vat_main_t * vam)
10119 {
10120   unformat_input_t *i = vam->input;
10121   vl_api_l2_fib_table_dump_t *mp;
10122   f64 timeout;
10123   u32 bd_id;
10124   u8 bd_id_set = 0;
10125
10126   /* Parse args required to build the message */
10127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10128     {
10129       if (unformat (i, "bd_id %d", &bd_id))
10130         bd_id_set = 1;
10131       else
10132         break;
10133     }
10134
10135   if (bd_id_set == 0)
10136     {
10137       errmsg ("missing bridge domain\n");
10138       return -99;
10139     }
10140
10141   fformat (vam->ofp,
10142            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10143
10144   /* Get list of l2 fib entries */
10145   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10146
10147   mp->bd_id = ntohl (bd_id);
10148   S;
10149
10150   /* Use a control ping for synchronization */
10151   {
10152     vl_api_control_ping_t *mp;
10153     M (CONTROL_PING, control_ping);
10154     S;
10155   }
10156   W;
10157 }
10158
10159
10160 static int
10161 api_interface_name_renumber (vat_main_t * vam)
10162 {
10163   unformat_input_t *line_input = vam->input;
10164   vl_api_interface_name_renumber_t *mp;
10165   u32 sw_if_index = ~0;
10166   f64 timeout;
10167   u32 new_show_dev_instance = ~0;
10168
10169   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10170     {
10171       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10172                     &sw_if_index))
10173         ;
10174       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10175         ;
10176       else if (unformat (line_input, "new_show_dev_instance %d",
10177                          &new_show_dev_instance))
10178         ;
10179       else
10180         break;
10181     }
10182
10183   if (sw_if_index == ~0)
10184     {
10185       errmsg ("missing interface name or sw_if_index\n");
10186       return -99;
10187     }
10188
10189   if (new_show_dev_instance == ~0)
10190     {
10191       errmsg ("missing new_show_dev_instance\n");
10192       return -99;
10193     }
10194
10195   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10196
10197   mp->sw_if_index = ntohl (sw_if_index);
10198   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10199
10200   S;
10201   W;
10202 }
10203
10204 static int
10205 api_want_ip4_arp_events (vat_main_t * vam)
10206 {
10207   unformat_input_t *line_input = vam->input;
10208   vl_api_want_ip4_arp_events_t *mp;
10209   f64 timeout;
10210   ip4_address_t address;
10211   int address_set = 0;
10212   u32 enable_disable = 1;
10213
10214   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10215     {
10216       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10217         address_set = 1;
10218       else if (unformat (line_input, "del"))
10219         enable_disable = 0;
10220       else
10221         break;
10222     }
10223
10224   if (address_set == 0)
10225     {
10226       errmsg ("missing addresses\n");
10227       return -99;
10228     }
10229
10230   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10231   mp->enable_disable = enable_disable;
10232   mp->pid = getpid ();
10233   mp->address = address.as_u32;
10234
10235   S;
10236   W;
10237 }
10238
10239 static int
10240 api_want_ip6_nd_events (vat_main_t * vam)
10241 {
10242   unformat_input_t *line_input = vam->input;
10243   vl_api_want_ip6_nd_events_t *mp;
10244   f64 timeout;
10245   ip6_address_t address;
10246   int address_set = 0;
10247   u32 enable_disable = 1;
10248
10249   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10250     {
10251       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
10252         address_set = 1;
10253       else if (unformat (line_input, "del"))
10254         enable_disable = 0;
10255       else
10256         break;
10257     }
10258
10259   if (address_set == 0)
10260     {
10261       errmsg ("missing addresses\n");
10262       return -99;
10263     }
10264
10265   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
10266   mp->enable_disable = enable_disable;
10267   mp->pid = getpid ();
10268   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
10269
10270   S;
10271   W;
10272 }
10273
10274 static int
10275 api_input_acl_set_interface (vat_main_t * vam)
10276 {
10277   unformat_input_t *i = vam->input;
10278   vl_api_input_acl_set_interface_t *mp;
10279   f64 timeout;
10280   u32 sw_if_index;
10281   int sw_if_index_set;
10282   u32 ip4_table_index = ~0;
10283   u32 ip6_table_index = ~0;
10284   u32 l2_table_index = ~0;
10285   u8 is_add = 1;
10286
10287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10288     {
10289       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10290         sw_if_index_set = 1;
10291       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10292         sw_if_index_set = 1;
10293       else if (unformat (i, "del"))
10294         is_add = 0;
10295       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10296         ;
10297       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10298         ;
10299       else if (unformat (i, "l2-table %d", &l2_table_index))
10300         ;
10301       else
10302         {
10303           clib_warning ("parse error '%U'", format_unformat_error, i);
10304           return -99;
10305         }
10306     }
10307
10308   if (sw_if_index_set == 0)
10309     {
10310       errmsg ("missing interface name or sw_if_index\n");
10311       return -99;
10312     }
10313
10314   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10315
10316   mp->sw_if_index = ntohl (sw_if_index);
10317   mp->ip4_table_index = ntohl (ip4_table_index);
10318   mp->ip6_table_index = ntohl (ip6_table_index);
10319   mp->l2_table_index = ntohl (l2_table_index);
10320   mp->is_add = is_add;
10321
10322   S;
10323   W;
10324   /* NOTREACHED */
10325   return 0;
10326 }
10327
10328 static int
10329 api_ip_address_dump (vat_main_t * vam)
10330 {
10331   unformat_input_t *i = vam->input;
10332   vl_api_ip_address_dump_t *mp;
10333   u32 sw_if_index = ~0;
10334   u8 sw_if_index_set = 0;
10335   u8 ipv4_set = 0;
10336   u8 ipv6_set = 0;
10337   f64 timeout;
10338
10339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10340     {
10341       if (unformat (i, "sw_if_index %d", &sw_if_index))
10342         sw_if_index_set = 1;
10343       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10344         sw_if_index_set = 1;
10345       else if (unformat (i, "ipv4"))
10346         ipv4_set = 1;
10347       else if (unformat (i, "ipv6"))
10348         ipv6_set = 1;
10349       else
10350         break;
10351     }
10352
10353   if (ipv4_set && ipv6_set)
10354     {
10355       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10356       return -99;
10357     }
10358
10359   if ((!ipv4_set) && (!ipv6_set))
10360     {
10361       errmsg ("no ipv4 nor ipv6 flag set\n");
10362       return -99;
10363     }
10364
10365   if (sw_if_index_set == 0)
10366     {
10367       errmsg ("missing interface name or sw_if_index\n");
10368       return -99;
10369     }
10370
10371   vam->current_sw_if_index = sw_if_index;
10372   vam->is_ipv6 = ipv6_set;
10373
10374   M (IP_ADDRESS_DUMP, ip_address_dump);
10375   mp->sw_if_index = ntohl (sw_if_index);
10376   mp->is_ipv6 = ipv6_set;
10377   S;
10378
10379   /* Use a control ping for synchronization */
10380   {
10381     vl_api_control_ping_t *mp;
10382     M (CONTROL_PING, control_ping);
10383     S;
10384   }
10385   W;
10386 }
10387
10388 static int
10389 api_ip_dump (vat_main_t * vam)
10390 {
10391   vl_api_ip_dump_t *mp;
10392   unformat_input_t *in = vam->input;
10393   int ipv4_set = 0;
10394   int ipv6_set = 0;
10395   int is_ipv6;
10396   f64 timeout;
10397   int i;
10398
10399   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10400     {
10401       if (unformat (in, "ipv4"))
10402         ipv4_set = 1;
10403       else if (unformat (in, "ipv6"))
10404         ipv6_set = 1;
10405       else
10406         break;
10407     }
10408
10409   if (ipv4_set && ipv6_set)
10410     {
10411       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10412       return -99;
10413     }
10414
10415   if ((!ipv4_set) && (!ipv6_set))
10416     {
10417       errmsg ("no ipv4 nor ipv6 flag set\n");
10418       return -99;
10419     }
10420
10421   is_ipv6 = ipv6_set;
10422   vam->is_ipv6 = is_ipv6;
10423
10424   /* free old data */
10425   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10426     {
10427       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10428     }
10429   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10430
10431   M (IP_DUMP, ip_dump);
10432   mp->is_ipv6 = ipv6_set;
10433   S;
10434
10435   /* Use a control ping for synchronization */
10436   {
10437     vl_api_control_ping_t *mp;
10438     M (CONTROL_PING, control_ping);
10439     S;
10440   }
10441   W;
10442 }
10443
10444 static int
10445 api_ipsec_spd_add_del (vat_main_t * vam)
10446 {
10447 #if DPDK > 0
10448   unformat_input_t *i = vam->input;
10449   vl_api_ipsec_spd_add_del_t *mp;
10450   f64 timeout;
10451   u32 spd_id = ~0;
10452   u8 is_add = 1;
10453
10454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10455     {
10456       if (unformat (i, "spd_id %d", &spd_id))
10457         ;
10458       else if (unformat (i, "del"))
10459         is_add = 0;
10460       else
10461         {
10462           clib_warning ("parse error '%U'", format_unformat_error, i);
10463           return -99;
10464         }
10465     }
10466   if (spd_id == ~0)
10467     {
10468       errmsg ("spd_id must be set\n");
10469       return -99;
10470     }
10471
10472   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10473
10474   mp->spd_id = ntohl (spd_id);
10475   mp->is_add = is_add;
10476
10477   S;
10478   W;
10479   /* NOTREACHED */
10480   return 0;
10481 #else
10482   clib_warning ("unsupported (no dpdk)");
10483   return -99;
10484 #endif
10485 }
10486
10487 static int
10488 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10489 {
10490 #if DPDK > 0
10491   unformat_input_t *i = vam->input;
10492   vl_api_ipsec_interface_add_del_spd_t *mp;
10493   f64 timeout;
10494   u32 sw_if_index;
10495   u8 sw_if_index_set = 0;
10496   u32 spd_id = (u32) ~ 0;
10497   u8 is_add = 1;
10498
10499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10500     {
10501       if (unformat (i, "del"))
10502         is_add = 0;
10503       else if (unformat (i, "spd_id %d", &spd_id))
10504         ;
10505       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10506         sw_if_index_set = 1;
10507       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10508         sw_if_index_set = 1;
10509       else
10510         {
10511           clib_warning ("parse error '%U'", format_unformat_error, i);
10512           return -99;
10513         }
10514
10515     }
10516
10517   if (spd_id == (u32) ~ 0)
10518     {
10519       errmsg ("spd_id must be set\n");
10520       return -99;
10521     }
10522
10523   if (sw_if_index_set == 0)
10524     {
10525       errmsg ("missing interface name or sw_if_index\n");
10526       return -99;
10527     }
10528
10529   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10530
10531   mp->spd_id = ntohl (spd_id);
10532   mp->sw_if_index = ntohl (sw_if_index);
10533   mp->is_add = is_add;
10534
10535   S;
10536   W;
10537   /* NOTREACHED */
10538   return 0;
10539 #else
10540   clib_warning ("unsupported (no dpdk)");
10541   return -99;
10542 #endif
10543 }
10544
10545 static int
10546 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10547 {
10548 #if DPDK > 0
10549   unformat_input_t *i = vam->input;
10550   vl_api_ipsec_spd_add_del_entry_t *mp;
10551   f64 timeout;
10552   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10553   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10554   i32 priority = 0;
10555   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10556   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10557   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10558   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10559
10560   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10561   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10562   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10563   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10564   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10565   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10566
10567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10568     {
10569       if (unformat (i, "del"))
10570         is_add = 0;
10571       if (unformat (i, "outbound"))
10572         is_outbound = 1;
10573       if (unformat (i, "inbound"))
10574         is_outbound = 0;
10575       else if (unformat (i, "spd_id %d", &spd_id))
10576         ;
10577       else if (unformat (i, "sa_id %d", &sa_id))
10578         ;
10579       else if (unformat (i, "priority %d", &priority))
10580         ;
10581       else if (unformat (i, "protocol %d", &protocol))
10582         ;
10583       else if (unformat (i, "lport_start %d", &lport_start))
10584         ;
10585       else if (unformat (i, "lport_stop %d", &lport_stop))
10586         ;
10587       else if (unformat (i, "rport_start %d", &rport_start))
10588         ;
10589       else if (unformat (i, "rport_stop %d", &rport_stop))
10590         ;
10591       else
10592         if (unformat
10593             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10594         {
10595           is_ipv6 = 0;
10596           is_ip_any = 0;
10597         }
10598       else
10599         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10600         {
10601           is_ipv6 = 0;
10602           is_ip_any = 0;
10603         }
10604       else
10605         if (unformat
10606             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
10607         {
10608           is_ipv6 = 0;
10609           is_ip_any = 0;
10610         }
10611       else
10612         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
10613         {
10614           is_ipv6 = 0;
10615           is_ip_any = 0;
10616         }
10617       else
10618         if (unformat
10619             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
10620         {
10621           is_ipv6 = 1;
10622           is_ip_any = 0;
10623         }
10624       else
10625         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
10626         {
10627           is_ipv6 = 1;
10628           is_ip_any = 0;
10629         }
10630       else
10631         if (unformat
10632             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
10633         {
10634           is_ipv6 = 1;
10635           is_ip_any = 0;
10636         }
10637       else
10638         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
10639         {
10640           is_ipv6 = 1;
10641           is_ip_any = 0;
10642         }
10643       else
10644         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10645         {
10646           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10647             {
10648               clib_warning ("unsupported action: 'resolve'");
10649               return -99;
10650             }
10651         }
10652       else
10653         {
10654           clib_warning ("parse error '%U'", format_unformat_error, i);
10655           return -99;
10656         }
10657
10658     }
10659
10660   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
10661
10662   mp->spd_id = ntohl (spd_id);
10663   mp->priority = ntohl (priority);
10664   mp->is_outbound = is_outbound;
10665
10666   mp->is_ipv6 = is_ipv6;
10667   if (is_ipv6 || is_ip_any)
10668     {
10669       clib_memcpy (mp->remote_address_start, &raddr6_start,
10670                    sizeof (ip6_address_t));
10671       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
10672                    sizeof (ip6_address_t));
10673       clib_memcpy (mp->local_address_start, &laddr6_start,
10674                    sizeof (ip6_address_t));
10675       clib_memcpy (mp->local_address_stop, &laddr6_stop,
10676                    sizeof (ip6_address_t));
10677     }
10678   else
10679     {
10680       clib_memcpy (mp->remote_address_start, &raddr4_start,
10681                    sizeof (ip4_address_t));
10682       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
10683                    sizeof (ip4_address_t));
10684       clib_memcpy (mp->local_address_start, &laddr4_start,
10685                    sizeof (ip4_address_t));
10686       clib_memcpy (mp->local_address_stop, &laddr4_stop,
10687                    sizeof (ip4_address_t));
10688     }
10689   mp->protocol = (u8) protocol;
10690   mp->local_port_start = ntohs ((u16) lport_start);
10691   mp->local_port_stop = ntohs ((u16) lport_stop);
10692   mp->remote_port_start = ntohs ((u16) rport_start);
10693   mp->remote_port_stop = ntohs ((u16) rport_stop);
10694   mp->policy = (u8) policy;
10695   mp->sa_id = ntohl (sa_id);
10696   mp->is_add = is_add;
10697   mp->is_ip_any = is_ip_any;
10698   S;
10699   W;
10700   /* NOTREACHED */
10701   return 0;
10702 #else
10703   clib_warning ("unsupported (no dpdk)");
10704   return -99;
10705 #endif
10706 }
10707
10708 static int
10709 api_ipsec_sad_add_del_entry (vat_main_t * vam)
10710 {
10711 #if DPDK > 0
10712   unformat_input_t *i = vam->input;
10713   vl_api_ipsec_sad_add_del_entry_t *mp;
10714   f64 timeout;
10715   u32 sad_id = 0, spi = 0;
10716   u8 *ck = 0, *ik = 0;
10717   u8 is_add = 1;
10718
10719   u8 protocol = IPSEC_PROTOCOL_AH;
10720   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
10721   u32 crypto_alg = 0, integ_alg = 0;
10722   ip4_address_t tun_src4;
10723   ip4_address_t tun_dst4;
10724   ip6_address_t tun_src6;
10725   ip6_address_t tun_dst6;
10726
10727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10728     {
10729       if (unformat (i, "del"))
10730         is_add = 0;
10731       else if (unformat (i, "sad_id %d", &sad_id))
10732         ;
10733       else if (unformat (i, "spi %d", &spi))
10734         ;
10735       else if (unformat (i, "esp"))
10736         protocol = IPSEC_PROTOCOL_ESP;
10737       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
10738         {
10739           is_tunnel = 1;
10740           is_tunnel_ipv6 = 0;
10741         }
10742       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
10743         {
10744           is_tunnel = 1;
10745           is_tunnel_ipv6 = 0;
10746         }
10747       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
10748         {
10749           is_tunnel = 1;
10750           is_tunnel_ipv6 = 1;
10751         }
10752       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
10753         {
10754           is_tunnel = 1;
10755           is_tunnel_ipv6 = 1;
10756         }
10757       else
10758         if (unformat
10759             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
10760         {
10761           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
10762               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
10763             {
10764               clib_warning ("unsupported crypto-alg: '%U'",
10765                             format_ipsec_crypto_alg, crypto_alg);
10766               return -99;
10767             }
10768         }
10769       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10770         ;
10771       else
10772         if (unformat
10773             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
10774         {
10775           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
10776               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
10777             {
10778               clib_warning ("unsupported integ-alg: '%U'",
10779                             format_ipsec_integ_alg, integ_alg);
10780               return -99;
10781             }
10782         }
10783       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10784         ;
10785       else
10786         {
10787           clib_warning ("parse error '%U'", format_unformat_error, i);
10788           return -99;
10789         }
10790
10791     }
10792
10793   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
10794
10795   mp->sad_id = ntohl (sad_id);
10796   mp->is_add = is_add;
10797   mp->protocol = protocol;
10798   mp->spi = ntohl (spi);
10799   mp->is_tunnel = is_tunnel;
10800   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
10801   mp->crypto_algorithm = crypto_alg;
10802   mp->integrity_algorithm = integ_alg;
10803   mp->crypto_key_length = vec_len (ck);
10804   mp->integrity_key_length = vec_len (ik);
10805
10806   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10807     mp->crypto_key_length = sizeof (mp->crypto_key);
10808
10809   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10810     mp->integrity_key_length = sizeof (mp->integrity_key);
10811
10812   if (ck)
10813     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10814   if (ik)
10815     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10816
10817   if (is_tunnel)
10818     {
10819       if (is_tunnel_ipv6)
10820         {
10821           clib_memcpy (mp->tunnel_src_address, &tun_src6,
10822                        sizeof (ip6_address_t));
10823           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
10824                        sizeof (ip6_address_t));
10825         }
10826       else
10827         {
10828           clib_memcpy (mp->tunnel_src_address, &tun_src4,
10829                        sizeof (ip4_address_t));
10830           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
10831                        sizeof (ip4_address_t));
10832         }
10833     }
10834
10835   S;
10836   W;
10837   /* NOTREACHED */
10838   return 0;
10839 #else
10840   clib_warning ("unsupported (no dpdk)");
10841   return -99;
10842 #endif
10843 }
10844
10845 static int
10846 api_ipsec_sa_set_key (vat_main_t * vam)
10847 {
10848 #if DPDK > 0
10849   unformat_input_t *i = vam->input;
10850   vl_api_ipsec_sa_set_key_t *mp;
10851   f64 timeout;
10852   u32 sa_id;
10853   u8 *ck = 0, *ik = 0;
10854
10855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10856     {
10857       if (unformat (i, "sa_id %d", &sa_id))
10858         ;
10859       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10860         ;
10861       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10862         ;
10863       else
10864         {
10865           clib_warning ("parse error '%U'", format_unformat_error, i);
10866           return -99;
10867         }
10868     }
10869
10870   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
10871
10872   mp->sa_id = ntohl (sa_id);
10873   mp->crypto_key_length = vec_len (ck);
10874   mp->integrity_key_length = vec_len (ik);
10875
10876   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10877     mp->crypto_key_length = sizeof (mp->crypto_key);
10878
10879   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10880     mp->integrity_key_length = sizeof (mp->integrity_key);
10881
10882   if (ck)
10883     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10884   if (ik)
10885     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10886
10887   S;
10888   W;
10889   /* NOTREACHED */
10890   return 0;
10891 #else
10892   clib_warning ("unsupported (no dpdk)");
10893   return -99;
10894 #endif
10895 }
10896
10897 static int
10898 api_ikev2_profile_add_del (vat_main_t * vam)
10899 {
10900 #if DPDK > 0
10901   unformat_input_t *i = vam->input;
10902   vl_api_ikev2_profile_add_del_t *mp;
10903   f64 timeout;
10904   u8 is_add = 1;
10905   u8 *name = 0;
10906
10907   const char *valid_chars = "a-zA-Z0-9_";
10908
10909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10910     {
10911       if (unformat (i, "del"))
10912         is_add = 0;
10913       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10914         vec_add1 (name, 0);
10915       else
10916         {
10917           errmsg ("parse error '%U'", format_unformat_error, i);
10918           return -99;
10919         }
10920     }
10921
10922   if (!vec_len (name))
10923     {
10924       errmsg ("profile name must be specified");
10925       return -99;
10926     }
10927
10928   if (vec_len (name) > 64)
10929     {
10930       errmsg ("profile name too long");
10931       return -99;
10932     }
10933
10934   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
10935
10936   clib_memcpy (mp->name, name, vec_len (name));
10937   mp->is_add = is_add;
10938   vec_free (name);
10939
10940   S;
10941   W;
10942   /* NOTREACHED */
10943   return 0;
10944 #else
10945   clib_warning ("unsupported (no dpdk)");
10946   return -99;
10947 #endif
10948 }
10949
10950 static int
10951 api_ikev2_profile_set_auth (vat_main_t * vam)
10952 {
10953 #if DPDK > 0
10954   unformat_input_t *i = vam->input;
10955   vl_api_ikev2_profile_set_auth_t *mp;
10956   f64 timeout;
10957   u8 *name = 0;
10958   u8 *data = 0;
10959   u32 auth_method = 0;
10960   u8 is_hex = 0;
10961
10962   const char *valid_chars = "a-zA-Z0-9_";
10963
10964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10965     {
10966       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10967         vec_add1 (name, 0);
10968       else if (unformat (i, "auth_method %U",
10969                          unformat_ikev2_auth_method, &auth_method))
10970         ;
10971       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
10972         is_hex = 1;
10973       else if (unformat (i, "auth_data %v", &data))
10974         ;
10975       else
10976         {
10977           errmsg ("parse error '%U'", format_unformat_error, i);
10978           return -99;
10979         }
10980     }
10981
10982   if (!vec_len (name))
10983     {
10984       errmsg ("profile name must be specified");
10985       return -99;
10986     }
10987
10988   if (vec_len (name) > 64)
10989     {
10990       errmsg ("profile name too long");
10991       return -99;
10992     }
10993
10994   if (!vec_len (data))
10995     {
10996       errmsg ("auth_data must be specified");
10997       return -99;
10998     }
10999
11000   if (!auth_method)
11001     {
11002       errmsg ("auth_method must be specified");
11003       return -99;
11004     }
11005
11006   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11007
11008   mp->is_hex = is_hex;
11009   mp->auth_method = (u8) auth_method;
11010   mp->data_len = vec_len (data);
11011   clib_memcpy (mp->name, name, vec_len (name));
11012   clib_memcpy (mp->data, data, vec_len (data));
11013   vec_free (name);
11014   vec_free (data);
11015
11016   S;
11017   W;
11018   /* NOTREACHED */
11019   return 0;
11020 #else
11021   clib_warning ("unsupported (no dpdk)");
11022   return -99;
11023 #endif
11024 }
11025
11026 static int
11027 api_ikev2_profile_set_id (vat_main_t * vam)
11028 {
11029 #if DPDK > 0
11030   unformat_input_t *i = vam->input;
11031   vl_api_ikev2_profile_set_id_t *mp;
11032   f64 timeout;
11033   u8 *name = 0;
11034   u8 *data = 0;
11035   u8 is_local = 0;
11036   u32 id_type = 0;
11037   ip4_address_t ip4;
11038
11039   const char *valid_chars = "a-zA-Z0-9_";
11040
11041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11042     {
11043       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11044         vec_add1 (name, 0);
11045       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11046         ;
11047       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11048         {
11049           data = vec_new (u8, 4);
11050           clib_memcpy (data, ip4.as_u8, 4);
11051         }
11052       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11053         ;
11054       else if (unformat (i, "id_data %v", &data))
11055         ;
11056       else if (unformat (i, "local"))
11057         is_local = 1;
11058       else if (unformat (i, "remote"))
11059         is_local = 0;
11060       else
11061         {
11062           errmsg ("parse error '%U'", format_unformat_error, i);
11063           return -99;
11064         }
11065     }
11066
11067   if (!vec_len (name))
11068     {
11069       errmsg ("profile name must be specified");
11070       return -99;
11071     }
11072
11073   if (vec_len (name) > 64)
11074     {
11075       errmsg ("profile name too long");
11076       return -99;
11077     }
11078
11079   if (!vec_len (data))
11080     {
11081       errmsg ("id_data must be specified");
11082       return -99;
11083     }
11084
11085   if (!id_type)
11086     {
11087       errmsg ("id_type must be specified");
11088       return -99;
11089     }
11090
11091   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11092
11093   mp->is_local = is_local;
11094   mp->id_type = (u8) id_type;
11095   mp->data_len = vec_len (data);
11096   clib_memcpy (mp->name, name, vec_len (name));
11097   clib_memcpy (mp->data, data, vec_len (data));
11098   vec_free (name);
11099   vec_free (data);
11100
11101   S;
11102   W;
11103   /* NOTREACHED */
11104   return 0;
11105 #else
11106   clib_warning ("unsupported (no dpdk)");
11107   return -99;
11108 #endif
11109 }
11110
11111 static int
11112 api_ikev2_profile_set_ts (vat_main_t * vam)
11113 {
11114 #if DPDK > 0
11115   unformat_input_t *i = vam->input;
11116   vl_api_ikev2_profile_set_ts_t *mp;
11117   f64 timeout;
11118   u8 *name = 0;
11119   u8 is_local = 0;
11120   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11121   ip4_address_t start_addr, end_addr;
11122
11123   const char *valid_chars = "a-zA-Z0-9_";
11124
11125   start_addr.as_u32 = 0;
11126   end_addr.as_u32 = (u32) ~ 0;
11127
11128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11129     {
11130       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11131         vec_add1 (name, 0);
11132       else if (unformat (i, "protocol %d", &proto))
11133         ;
11134       else if (unformat (i, "start_port %d", &start_port))
11135         ;
11136       else if (unformat (i, "end_port %d", &end_port))
11137         ;
11138       else
11139         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11140         ;
11141       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11142         ;
11143       else if (unformat (i, "local"))
11144         is_local = 1;
11145       else if (unformat (i, "remote"))
11146         is_local = 0;
11147       else
11148         {
11149           errmsg ("parse error '%U'", format_unformat_error, i);
11150           return -99;
11151         }
11152     }
11153
11154   if (!vec_len (name))
11155     {
11156       errmsg ("profile name must be specified");
11157       return -99;
11158     }
11159
11160   if (vec_len (name) > 64)
11161     {
11162       errmsg ("profile name too long");
11163       return -99;
11164     }
11165
11166   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11167
11168   mp->is_local = is_local;
11169   mp->proto = (u8) proto;
11170   mp->start_port = (u16) start_port;
11171   mp->end_port = (u16) end_port;
11172   mp->start_addr = start_addr.as_u32;
11173   mp->end_addr = end_addr.as_u32;
11174   clib_memcpy (mp->name, name, vec_len (name));
11175   vec_free (name);
11176
11177   S;
11178   W;
11179   /* NOTREACHED */
11180   return 0;
11181 #else
11182   clib_warning ("unsupported (no dpdk)");
11183   return -99;
11184 #endif
11185 }
11186
11187 static int
11188 api_ikev2_set_local_key (vat_main_t * vam)
11189 {
11190 #if DPDK > 0
11191   unformat_input_t *i = vam->input;
11192   vl_api_ikev2_set_local_key_t *mp;
11193   f64 timeout;
11194   u8 *file = 0;
11195
11196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11197     {
11198       if (unformat (i, "file %v", &file))
11199         vec_add1 (file, 0);
11200       else
11201         {
11202           errmsg ("parse error '%U'", format_unformat_error, i);
11203           return -99;
11204         }
11205     }
11206
11207   if (!vec_len (file))
11208     {
11209       errmsg ("RSA key file must be specified");
11210       return -99;
11211     }
11212
11213   if (vec_len (file) > 256)
11214     {
11215       errmsg ("file name too long");
11216       return -99;
11217     }
11218
11219   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11220
11221   clib_memcpy (mp->key_file, file, vec_len (file));
11222   vec_free (file);
11223
11224   S;
11225   W;
11226   /* NOTREACHED */
11227   return 0;
11228 #else
11229   clib_warning ("unsupported (no dpdk)");
11230   return -99;
11231 #endif
11232 }
11233
11234 /*
11235  * MAP
11236  */
11237 static int
11238 api_map_add_domain (vat_main_t * vam)
11239 {
11240   unformat_input_t *i = vam->input;
11241   vl_api_map_add_domain_t *mp;
11242   f64 timeout;
11243
11244   ip4_address_t ip4_prefix;
11245   ip6_address_t ip6_prefix;
11246   ip6_address_t ip6_src;
11247   u32 num_m_args = 0;
11248   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11249     0, psid_length = 0;
11250   u8 is_translation = 0;
11251   u32 mtu = 0;
11252   u32 ip6_src_len = 128;
11253
11254   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11255     {
11256       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11257                     &ip4_prefix, &ip4_prefix_len))
11258         num_m_args++;
11259       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11260                          &ip6_prefix, &ip6_prefix_len))
11261         num_m_args++;
11262       else
11263         if (unformat
11264             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11265              &ip6_src_len))
11266         num_m_args++;
11267       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11268         num_m_args++;
11269       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11270         num_m_args++;
11271       else if (unformat (i, "psid-offset %d", &psid_offset))
11272         num_m_args++;
11273       else if (unformat (i, "psid-len %d", &psid_length))
11274         num_m_args++;
11275       else if (unformat (i, "mtu %d", &mtu))
11276         num_m_args++;
11277       else if (unformat (i, "map-t"))
11278         is_translation = 1;
11279       else
11280         {
11281           clib_warning ("parse error '%U'", format_unformat_error, i);
11282           return -99;
11283         }
11284     }
11285
11286   if (num_m_args < 3)
11287     {
11288       errmsg ("mandatory argument(s) missing\n");
11289       return -99;
11290     }
11291
11292   /* Construct the API message */
11293   M (MAP_ADD_DOMAIN, map_add_domain);
11294
11295   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11296   mp->ip4_prefix_len = ip4_prefix_len;
11297
11298   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11299   mp->ip6_prefix_len = ip6_prefix_len;
11300
11301   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11302   mp->ip6_src_prefix_len = ip6_src_len;
11303
11304   mp->ea_bits_len = ea_bits_len;
11305   mp->psid_offset = psid_offset;
11306   mp->psid_length = psid_length;
11307   mp->is_translation = is_translation;
11308   mp->mtu = htons (mtu);
11309
11310   /* send it... */
11311   S;
11312
11313   /* Wait for a reply, return good/bad news  */
11314   W;
11315 }
11316
11317 static int
11318 api_map_del_domain (vat_main_t * vam)
11319 {
11320   unformat_input_t *i = vam->input;
11321   vl_api_map_del_domain_t *mp;
11322   f64 timeout;
11323
11324   u32 num_m_args = 0;
11325   u32 index;
11326
11327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11328     {
11329       if (unformat (i, "index %d", &index))
11330         num_m_args++;
11331       else
11332         {
11333           clib_warning ("parse error '%U'", format_unformat_error, i);
11334           return -99;
11335         }
11336     }
11337
11338   if (num_m_args != 1)
11339     {
11340       errmsg ("mandatory argument(s) missing\n");
11341       return -99;
11342     }
11343
11344   /* Construct the API message */
11345   M (MAP_DEL_DOMAIN, map_del_domain);
11346
11347   mp->index = ntohl (index);
11348
11349   /* send it... */
11350   S;
11351
11352   /* Wait for a reply, return good/bad news  */
11353   W;
11354 }
11355
11356 static int
11357 api_map_add_del_rule (vat_main_t * vam)
11358 {
11359   unformat_input_t *i = vam->input;
11360   vl_api_map_add_del_rule_t *mp;
11361   f64 timeout;
11362   u8 is_add = 1;
11363   ip6_address_t ip6_dst;
11364   u32 num_m_args = 0, index, psid = 0;
11365
11366   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11367     {
11368       if (unformat (i, "index %d", &index))
11369         num_m_args++;
11370       else if (unformat (i, "psid %d", &psid))
11371         num_m_args++;
11372       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11373         num_m_args++;
11374       else if (unformat (i, "del"))
11375         {
11376           is_add = 0;
11377         }
11378       else
11379         {
11380           clib_warning ("parse error '%U'", format_unformat_error, i);
11381           return -99;
11382         }
11383     }
11384
11385   /* Construct the API message */
11386   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11387
11388   mp->index = ntohl (index);
11389   mp->is_add = is_add;
11390   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11391   mp->psid = ntohs (psid);
11392
11393   /* send it... */
11394   S;
11395
11396   /* Wait for a reply, return good/bad news  */
11397   W;
11398 }
11399
11400 static int
11401 api_map_domain_dump (vat_main_t * vam)
11402 {
11403   vl_api_map_domain_dump_t *mp;
11404   f64 timeout;
11405
11406   /* Construct the API message */
11407   M (MAP_DOMAIN_DUMP, map_domain_dump);
11408
11409   /* send it... */
11410   S;
11411
11412   /* Use a control ping for synchronization */
11413   {
11414     vl_api_control_ping_t *mp;
11415     M (CONTROL_PING, control_ping);
11416     S;
11417   }
11418   W;
11419 }
11420
11421 static int
11422 api_map_rule_dump (vat_main_t * vam)
11423 {
11424   unformat_input_t *i = vam->input;
11425   vl_api_map_rule_dump_t *mp;
11426   f64 timeout;
11427   u32 domain_index = ~0;
11428
11429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11430     {
11431       if (unformat (i, "index %u", &domain_index))
11432         ;
11433       else
11434         break;
11435     }
11436
11437   if (domain_index == ~0)
11438     {
11439       clib_warning ("parse error: domain index expected");
11440       return -99;
11441     }
11442
11443   /* Construct the API message */
11444   M (MAP_RULE_DUMP, map_rule_dump);
11445
11446   mp->domain_index = htonl (domain_index);
11447
11448   /* send it... */
11449   S;
11450
11451   /* Use a control ping for synchronization */
11452   {
11453     vl_api_control_ping_t *mp;
11454     M (CONTROL_PING, control_ping);
11455     S;
11456   }
11457   W;
11458 }
11459
11460 static void vl_api_map_add_domain_reply_t_handler
11461   (vl_api_map_add_domain_reply_t * mp)
11462 {
11463   vat_main_t *vam = &vat_main;
11464   i32 retval = ntohl (mp->retval);
11465
11466   if (vam->async_mode)
11467     {
11468       vam->async_errors += (retval < 0);
11469     }
11470   else
11471     {
11472       vam->retval = retval;
11473       vam->result_ready = 1;
11474     }
11475 }
11476
11477 static void vl_api_map_add_domain_reply_t_handler_json
11478   (vl_api_map_add_domain_reply_t * mp)
11479 {
11480   vat_main_t *vam = &vat_main;
11481   vat_json_node_t node;
11482
11483   vat_json_init_object (&node);
11484   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11485   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11486
11487   vat_json_print (vam->ofp, &node);
11488   vat_json_free (&node);
11489
11490   vam->retval = ntohl (mp->retval);
11491   vam->result_ready = 1;
11492 }
11493
11494 static int
11495 api_get_first_msg_id (vat_main_t * vam)
11496 {
11497   vl_api_get_first_msg_id_t *mp;
11498   f64 timeout;
11499   unformat_input_t *i = vam->input;
11500   u8 *name;
11501   u8 name_set = 0;
11502
11503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11504     {
11505       if (unformat (i, "client %s", &name))
11506         name_set = 1;
11507       else
11508         break;
11509     }
11510
11511   if (name_set == 0)
11512     {
11513       errmsg ("missing client name\n");
11514       return -99;
11515     }
11516   vec_add1 (name, 0);
11517
11518   if (vec_len (name) > 63)
11519     {
11520       errmsg ("client name too long\n");
11521       return -99;
11522     }
11523
11524   M (GET_FIRST_MSG_ID, get_first_msg_id);
11525   clib_memcpy (mp->name, name, vec_len (name));
11526   S;
11527   W;
11528   /* NOTREACHED */
11529   return 0;
11530 }
11531
11532 static int
11533 api_cop_interface_enable_disable (vat_main_t * vam)
11534 {
11535   unformat_input_t *line_input = vam->input;
11536   vl_api_cop_interface_enable_disable_t *mp;
11537   f64 timeout;
11538   u32 sw_if_index = ~0;
11539   u8 enable_disable = 1;
11540
11541   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11542     {
11543       if (unformat (line_input, "disable"))
11544         enable_disable = 0;
11545       if (unformat (line_input, "enable"))
11546         enable_disable = 1;
11547       else if (unformat (line_input, "%U", unformat_sw_if_index,
11548                          vam, &sw_if_index))
11549         ;
11550       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11551         ;
11552       else
11553         break;
11554     }
11555
11556   if (sw_if_index == ~0)
11557     {
11558       errmsg ("missing interface name or sw_if_index\n");
11559       return -99;
11560     }
11561
11562   /* Construct the API message */
11563   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11564   mp->sw_if_index = ntohl (sw_if_index);
11565   mp->enable_disable = enable_disable;
11566
11567   /* send it... */
11568   S;
11569   /* Wait for the reply */
11570   W;
11571 }
11572
11573 static int
11574 api_cop_whitelist_enable_disable (vat_main_t * vam)
11575 {
11576   unformat_input_t *line_input = vam->input;
11577   vl_api_cop_whitelist_enable_disable_t *mp;
11578   f64 timeout;
11579   u32 sw_if_index = ~0;
11580   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11581   u32 fib_id = 0;
11582
11583   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11584     {
11585       if (unformat (line_input, "ip4"))
11586         ip4 = 1;
11587       else if (unformat (line_input, "ip6"))
11588         ip6 = 1;
11589       else if (unformat (line_input, "default"))
11590         default_cop = 1;
11591       else if (unformat (line_input, "%U", unformat_sw_if_index,
11592                          vam, &sw_if_index))
11593         ;
11594       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11595         ;
11596       else if (unformat (line_input, "fib-id %d", &fib_id))
11597         ;
11598       else
11599         break;
11600     }
11601
11602   if (sw_if_index == ~0)
11603     {
11604       errmsg ("missing interface name or sw_if_index\n");
11605       return -99;
11606     }
11607
11608   /* Construct the API message */
11609   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
11610   mp->sw_if_index = ntohl (sw_if_index);
11611   mp->fib_id = ntohl (fib_id);
11612   mp->ip4 = ip4;
11613   mp->ip6 = ip6;
11614   mp->default_cop = default_cop;
11615
11616   /* send it... */
11617   S;
11618   /* Wait for the reply */
11619   W;
11620 }
11621
11622 static int
11623 api_get_node_graph (vat_main_t * vam)
11624 {
11625   vl_api_get_node_graph_t *mp;
11626   f64 timeout;
11627
11628   M (GET_NODE_GRAPH, get_node_graph);
11629
11630   /* send it... */
11631   S;
11632   /* Wait for the reply */
11633   W;
11634 }
11635
11636 /* *INDENT-OFF* */
11637 /** Used for parsing LISP eids */
11638 typedef CLIB_PACKED(struct{
11639   u8 addr[16];   /**< eid address */
11640   u32 len;       /**< prefix length if IP */
11641   u8 type;      /**< type of eid */
11642 }) lisp_eid_vat_t;
11643 /* *INDENT-ON* */
11644
11645 static uword
11646 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
11647 {
11648   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
11649
11650   memset (a, 0, sizeof (a[0]));
11651
11652   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
11653     {
11654       a->type = 0;              /* ipv4 type */
11655     }
11656   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
11657     {
11658       a->type = 1;              /* ipv6 type */
11659     }
11660   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
11661     {
11662       a->type = 2;              /* mac type */
11663     }
11664   else
11665     {
11666       return 0;
11667     }
11668
11669   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
11670     {
11671       return 0;
11672     }
11673
11674   return 1;
11675 }
11676
11677 static int
11678 lisp_eid_size_vat (u8 type)
11679 {
11680   switch (type)
11681     {
11682     case 0:
11683       return 4;
11684     case 1:
11685       return 16;
11686     case 2:
11687       return 6;
11688     }
11689   return 0;
11690 }
11691
11692 static void
11693 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
11694 {
11695   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
11696 }
11697
11698 /* *INDENT-OFF* */
11699 /** Used for transferring locators via VPP API */
11700 typedef CLIB_PACKED(struct
11701 {
11702   u32 sw_if_index; /**< locator sw_if_index */
11703   u8 priority; /**< locator priority */
11704   u8 weight;   /**< locator weight */
11705 }) ls_locator_t;
11706 /* *INDENT-ON* */
11707
11708 static int
11709 api_lisp_add_del_locator_set (vat_main_t * vam)
11710 {
11711   unformat_input_t *input = vam->input;
11712   vl_api_lisp_add_del_locator_set_t *mp;
11713   f64 timeout = ~0;
11714   u8 is_add = 1;
11715   u8 *locator_set_name = NULL;
11716   u8 locator_set_name_set = 0;
11717   ls_locator_t locator, *locators = 0;
11718   u32 sw_if_index, priority, weight;
11719
11720   /* Parse args required to build the message */
11721   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11722     {
11723       if (unformat (input, "del"))
11724         {
11725           is_add = 0;
11726         }
11727       else if (unformat (input, "locator-set %s", &locator_set_name))
11728         {
11729           locator_set_name_set = 1;
11730         }
11731       else if (unformat (input, "sw_if_index %u p %u w %u",
11732                          &sw_if_index, &priority, &weight))
11733         {
11734           locator.sw_if_index = htonl (sw_if_index);
11735           locator.priority = priority;
11736           locator.weight = weight;
11737           vec_add1 (locators, locator);
11738         }
11739       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
11740                          vam, &sw_if_index, &priority, &weight))
11741         {
11742           locator.sw_if_index = htonl (sw_if_index);
11743           locator.priority = priority;
11744           locator.weight = weight;
11745           vec_add1 (locators, locator);
11746         }
11747       else
11748         break;
11749     }
11750
11751   if (locator_set_name_set == 0)
11752     {
11753       errmsg ("missing locator-set name");
11754       vec_free (locators);
11755       return -99;
11756     }
11757
11758   if (vec_len (locator_set_name) > 64)
11759     {
11760       errmsg ("locator-set name too long\n");
11761       vec_free (locator_set_name);
11762       vec_free (locators);
11763       return -99;
11764     }
11765   vec_add1 (locator_set_name, 0);
11766
11767   /* Construct the API message */
11768   M (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
11769
11770   mp->is_add = is_add;
11771   clib_memcpy (mp->locator_set_name, locator_set_name,
11772                vec_len (locator_set_name));
11773   vec_free (locator_set_name);
11774
11775   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
11776   if (locators)
11777     clib_memcpy (mp->locators, locators,
11778                  (sizeof (ls_locator_t) * vec_len (locators)));
11779   vec_free (locators);
11780
11781   /* send it... */
11782   S;
11783
11784   /* Wait for a reply... */
11785   W;
11786
11787   /* NOTREACHED */
11788   return 0;
11789 }
11790
11791 static int
11792 api_lisp_add_del_locator (vat_main_t * vam)
11793 {
11794   unformat_input_t *input = vam->input;
11795   vl_api_lisp_add_del_locator_t *mp;
11796   f64 timeout = ~0;
11797   u32 tmp_if_index = ~0;
11798   u32 sw_if_index = ~0;
11799   u8 sw_if_index_set = 0;
11800   u8 sw_if_index_if_name_set = 0;
11801   u32 priority = ~0;
11802   u8 priority_set = 0;
11803   u32 weight = ~0;
11804   u8 weight_set = 0;
11805   u8 is_add = 1;
11806   u8 *locator_set_name = NULL;
11807   u8 locator_set_name_set = 0;
11808
11809   /* Parse args required to build the message */
11810   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11811     {
11812       if (unformat (input, "del"))
11813         {
11814           is_add = 0;
11815         }
11816       else if (unformat (input, "locator-set %s", &locator_set_name))
11817         {
11818           locator_set_name_set = 1;
11819         }
11820       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
11821                          &tmp_if_index))
11822         {
11823           sw_if_index_if_name_set = 1;
11824           sw_if_index = tmp_if_index;
11825         }
11826       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
11827         {
11828           sw_if_index_set = 1;
11829           sw_if_index = tmp_if_index;
11830         }
11831       else if (unformat (input, "p %d", &priority))
11832         {
11833           priority_set = 1;
11834         }
11835       else if (unformat (input, "w %d", &weight))
11836         {
11837           weight_set = 1;
11838         }
11839       else
11840         break;
11841     }
11842
11843   if (locator_set_name_set == 0)
11844     {
11845       errmsg ("missing locator-set name");
11846       return -99;
11847     }
11848
11849   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
11850     {
11851       errmsg ("missing sw_if_index");
11852       vec_free (locator_set_name);
11853       return -99;
11854     }
11855
11856   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
11857     {
11858       errmsg ("cannot use both params interface name and sw_if_index");
11859       vec_free (locator_set_name);
11860       return -99;
11861     }
11862
11863   if (priority_set == 0)
11864     {
11865       errmsg ("missing locator-set priority\n");
11866       vec_free (locator_set_name);
11867       return -99;
11868     }
11869
11870   if (weight_set == 0)
11871     {
11872       errmsg ("missing locator-set weight\n");
11873       vec_free (locator_set_name);
11874       return -99;
11875     }
11876
11877   if (vec_len (locator_set_name) > 64)
11878     {
11879       errmsg ("locator-set name too long\n");
11880       vec_free (locator_set_name);
11881       return -99;
11882     }
11883   vec_add1 (locator_set_name, 0);
11884
11885   /* Construct the API message */
11886   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
11887
11888   mp->is_add = is_add;
11889   mp->sw_if_index = ntohl (sw_if_index);
11890   mp->priority = priority;
11891   mp->weight = weight;
11892   clib_memcpy (mp->locator_set_name, locator_set_name,
11893                vec_len (locator_set_name));
11894   vec_free (locator_set_name);
11895
11896   /* send it... */
11897   S;
11898
11899   /* Wait for a reply... */
11900   W;
11901
11902   /* NOTREACHED */
11903   return 0;
11904 }
11905
11906 static int
11907 api_lisp_add_del_local_eid (vat_main_t * vam)
11908 {
11909   unformat_input_t *input = vam->input;
11910   vl_api_lisp_add_del_local_eid_t *mp;
11911   f64 timeout = ~0;
11912   u8 is_add = 1;
11913   u8 eid_set = 0;
11914   lisp_eid_vat_t _eid, *eid = &_eid;
11915   u8 *locator_set_name = 0;
11916   u8 locator_set_name_set = 0;
11917   u32 vni = 0;
11918
11919   /* Parse args required to build the message */
11920   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11921     {
11922       if (unformat (input, "del"))
11923         {
11924           is_add = 0;
11925         }
11926       else if (unformat (input, "vni %d", &vni))
11927         {
11928           ;
11929         }
11930       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
11931         {
11932           eid_set = 1;
11933         }
11934       else if (unformat (input, "locator-set %s", &locator_set_name))
11935         {
11936           locator_set_name_set = 1;
11937         }
11938       else
11939         break;
11940     }
11941
11942   if (locator_set_name_set == 0)
11943     {
11944       errmsg ("missing locator-set name\n");
11945       return -99;
11946     }
11947
11948   if (0 == eid_set)
11949     {
11950       errmsg ("EID address not set!");
11951       vec_free (locator_set_name);
11952       return -99;
11953     }
11954
11955   if (vec_len (locator_set_name) > 64)
11956     {
11957       errmsg ("locator-set name too long\n");
11958       vec_free (locator_set_name);
11959       return -99;
11960     }
11961   vec_add1 (locator_set_name, 0);
11962
11963   /* Construct the API message */
11964   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
11965
11966   mp->is_add = is_add;
11967   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
11968   mp->eid_type = eid->type;
11969   mp->prefix_len = eid->len;
11970   mp->vni = clib_host_to_net_u32 (vni);
11971   clib_memcpy (mp->locator_set_name, locator_set_name,
11972                vec_len (locator_set_name));
11973
11974   vec_free (locator_set_name);
11975
11976   /* send it... */
11977   S;
11978
11979   /* Wait for a reply... */
11980   W;
11981
11982   /* NOTREACHED */
11983   return 0;
11984 }
11985
11986 /* *INDENT-OFF* */
11987 /** Used for transferring locators via VPP API */
11988 typedef CLIB_PACKED(struct
11989 {
11990   u8 is_ip4; /**< is locator an IPv4 address? */
11991   u8 priority; /**< locator priority */
11992   u8 weight;   /**< locator weight */
11993   u8 addr[16]; /**< IPv4/IPv6 address */
11994 }) rloc_t;
11995 /* *INDENT-ON* */
11996
11997 static int
11998 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
11999 {
12000   unformat_input_t *input = vam->input;
12001   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12002   f64 timeout = ~0;
12003   u8 is_add = 1;
12004   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12005   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12006   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12007   u32 action = ~0, p, w;
12008   ip4_address_t rmt_rloc4, lcl_rloc4;
12009   ip6_address_t rmt_rloc6, lcl_rloc6;
12010   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12011
12012   memset (&rloc, 0, sizeof (rloc));
12013
12014   /* Parse args required to build the message */
12015   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12016     {
12017       if (unformat (input, "del"))
12018         {
12019           is_add = 0;
12020         }
12021       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12022         {
12023           rmt_eid_set = 1;
12024         }
12025       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12026         {
12027           lcl_eid_set = 1;
12028         }
12029       else if (unformat (input, "p %d w %d", &p, &w))
12030         {
12031           if (!curr_rloc)
12032             {
12033               errmsg ("No RLOC configured for setting priority/weight!");
12034               return -99;
12035             }
12036           curr_rloc->priority = p;
12037           curr_rloc->weight = w;
12038         }
12039       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12040                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12041         {
12042           rloc.is_ip4 = 1;
12043
12044           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12045           rloc.priority = rloc.weight = 0;
12046           vec_add1 (lcl_locs, rloc);
12047
12048           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12049           vec_add1 (rmt_locs, rloc);
12050           /* priority and weight saved in rmt loc */
12051           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12052         }
12053       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12054                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12055         {
12056           rloc.is_ip4 = 0;
12057           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12058           rloc.priority = rloc.weight = 0;
12059           vec_add1 (lcl_locs, rloc);
12060
12061           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12062           vec_add1 (rmt_locs, rloc);
12063           /* priority and weight saved in rmt loc */
12064           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12065         }
12066       else if (unformat (input, "action %d", &action))
12067         {
12068           ;
12069         }
12070       else
12071         {
12072           clib_warning ("parse error '%U'", format_unformat_error, input);
12073           return -99;
12074         }
12075     }
12076
12077   if (!rmt_eid_set)
12078     {
12079       errmsg ("remote eid addresses not set\n");
12080       return -99;
12081     }
12082
12083   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12084     {
12085       errmsg ("eid types don't match\n");
12086       return -99;
12087     }
12088
12089   if (0 == rmt_locs && (u32) ~ 0 == action)
12090     {
12091       errmsg ("action not set for negative mapping\n");
12092       return -99;
12093     }
12094
12095   /* Construct the API message */
12096   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12097
12098   mp->is_add = is_add;
12099   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12100   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12101   mp->eid_type = rmt_eid->type;
12102   mp->rmt_len = rmt_eid->len;
12103   mp->lcl_len = lcl_eid->len;
12104   mp->action = action;
12105
12106   if (0 != rmt_locs && 0 != lcl_locs)
12107     {
12108       mp->loc_num = vec_len (rmt_locs);
12109       clib_memcpy (mp->lcl_locs, lcl_locs,
12110                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12111       clib_memcpy (mp->rmt_locs, rmt_locs,
12112                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12113     }
12114   vec_free (lcl_locs);
12115   vec_free (rmt_locs);
12116
12117   /* send it... */
12118   S;
12119
12120   /* Wait for a reply... */
12121   W;
12122
12123   /* NOTREACHED */
12124   return 0;
12125 }
12126
12127 static int
12128 api_lisp_add_del_map_resolver (vat_main_t * vam)
12129 {
12130   unformat_input_t *input = vam->input;
12131   vl_api_lisp_add_del_map_resolver_t *mp;
12132   f64 timeout = ~0;
12133   u8 is_add = 1;
12134   u8 ipv4_set = 0;
12135   u8 ipv6_set = 0;
12136   ip4_address_t ipv4;
12137   ip6_address_t ipv6;
12138
12139   /* Parse args required to build the message */
12140   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12141     {
12142       if (unformat (input, "del"))
12143         {
12144           is_add = 0;
12145         }
12146       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12147         {
12148           ipv4_set = 1;
12149         }
12150       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12151         {
12152           ipv6_set = 1;
12153         }
12154       else
12155         break;
12156     }
12157
12158   if (ipv4_set && ipv6_set)
12159     {
12160       errmsg ("both eid v4 and v6 addresses set\n");
12161       return -99;
12162     }
12163
12164   if (!ipv4_set && !ipv6_set)
12165     {
12166       errmsg ("eid addresses not set\n");
12167       return -99;
12168     }
12169
12170   /* Construct the API message */
12171   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12172
12173   mp->is_add = is_add;
12174   if (ipv6_set)
12175     {
12176       mp->is_ipv6 = 1;
12177       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12178     }
12179   else
12180     {
12181       mp->is_ipv6 = 0;
12182       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12183     }
12184
12185   /* send it... */
12186   S;
12187
12188   /* Wait for a reply... */
12189   W;
12190
12191   /* NOTREACHED */
12192   return 0;
12193 }
12194
12195 static int
12196 api_lisp_gpe_enable_disable (vat_main_t * vam)
12197 {
12198   unformat_input_t *input = vam->input;
12199   vl_api_lisp_gpe_enable_disable_t *mp;
12200   f64 timeout = ~0;
12201   u8 is_set = 0;
12202   u8 is_en = 1;
12203
12204   /* Parse args required to build the message */
12205   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12206     {
12207       if (unformat (input, "enable"))
12208         {
12209           is_set = 1;
12210           is_en = 1;
12211         }
12212       else if (unformat (input, "disable"))
12213         {
12214           is_set = 1;
12215           is_en = 0;
12216         }
12217       else
12218         break;
12219     }
12220
12221   if (is_set == 0)
12222     {
12223       errmsg ("Value not set\n");
12224       return -99;
12225     }
12226
12227   /* Construct the API message */
12228   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12229
12230   mp->is_en = is_en;
12231
12232   /* send it... */
12233   S;
12234
12235   /* Wait for a reply... */
12236   W;
12237
12238   /* NOTREACHED */
12239   return 0;
12240 }
12241
12242 static int
12243 api_lisp_enable_disable (vat_main_t * vam)
12244 {
12245   unformat_input_t *input = vam->input;
12246   vl_api_lisp_enable_disable_t *mp;
12247   f64 timeout = ~0;
12248   u8 is_set = 0;
12249   u8 is_en = 0;
12250
12251   /* Parse args required to build the message */
12252   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12253     {
12254       if (unformat (input, "enable"))
12255         {
12256           is_set = 1;
12257           is_en = 1;
12258         }
12259       else if (unformat (input, "disable"))
12260         {
12261           is_set = 1;
12262         }
12263       else
12264         break;
12265     }
12266
12267   if (!is_set)
12268     {
12269       errmsg ("Value not set\n");
12270       return -99;
12271     }
12272
12273   /* Construct the API message */
12274   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12275
12276   mp->is_en = is_en;
12277
12278   /* send it... */
12279   S;
12280
12281   /* Wait for a reply... */
12282   W;
12283
12284   /* NOTREACHED */
12285   return 0;
12286 }
12287
12288 /**
12289  * Enable/disable LISP proxy ITR.
12290  *
12291  * @param vam vpp API test context
12292  * @return return code
12293  */
12294 static int
12295 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12296 {
12297   f64 timeout = ~0;
12298   u8 ls_name_set = 0;
12299   unformat_input_t *input = vam->input;
12300   vl_api_lisp_pitr_set_locator_set_t *mp;
12301   u8 is_add = 1;
12302   u8 *ls_name = 0;
12303
12304   /* Parse args required to build the message */
12305   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12306     {
12307       if (unformat (input, "del"))
12308         is_add = 0;
12309       else if (unformat (input, "locator-set %s", &ls_name))
12310         ls_name_set = 1;
12311       else
12312         {
12313           errmsg ("parse error '%U'", format_unformat_error, input);
12314           return -99;
12315         }
12316     }
12317
12318   if (!ls_name_set)
12319     {
12320       errmsg ("locator-set name not set!");
12321       return -99;
12322     }
12323
12324   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12325
12326   mp->is_add = is_add;
12327   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12328   vec_free (ls_name);
12329
12330   /* send */
12331   S;
12332
12333   /* wait for reply */
12334   W;
12335
12336   /* notreached */
12337   return 0;
12338 }
12339
12340 static int
12341 api_show_lisp_pitr (vat_main_t * vam)
12342 {
12343   vl_api_show_lisp_pitr_t *mp;
12344   f64 timeout = ~0;
12345
12346   if (!vam->json_output)
12347     {
12348       fformat (vam->ofp, "%=20s\n", "lisp status:");
12349     }
12350
12351   M (SHOW_LISP_PITR, show_lisp_pitr);
12352   /* send it... */
12353   S;
12354
12355   /* Wait for a reply... */
12356   W;
12357
12358   /* NOTREACHED */
12359   return 0;
12360 }
12361
12362 /**
12363  * Add/delete mapping between vni and vrf
12364  */
12365 static int
12366 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12367 {
12368   f64 timeout = ~0;
12369   unformat_input_t *input = vam->input;
12370   vl_api_lisp_eid_table_add_del_map_t *mp;
12371   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12372   u32 vni, vrf, bd_index;
12373
12374   /* Parse args required to build the message */
12375   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12376     {
12377       if (unformat (input, "del"))
12378         is_add = 0;
12379       else if (unformat (input, "vrf %d", &vrf))
12380         vrf_set = 1;
12381       else if (unformat (input, "bd_index %d", &bd_index))
12382         bd_index_set = 1;
12383       else if (unformat (input, "vni %d", &vni))
12384         vni_set = 1;
12385       else
12386         break;
12387     }
12388
12389   if (!vni_set || (!vrf_set && !bd_index_set))
12390     {
12391       errmsg ("missing arguments!");
12392       return -99;
12393     }
12394
12395   if (vrf_set && bd_index_set)
12396     {
12397       errmsg ("error: both vrf and bd entered!");
12398       return -99;
12399     }
12400
12401   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12402
12403   mp->is_add = is_add;
12404   mp->vni = htonl (vni);
12405   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
12406   mp->is_l2 = bd_index_set;
12407
12408   /* send */
12409   S;
12410
12411   /* wait for reply */
12412   W;
12413
12414   /* notreached */
12415   return 0;
12416 }
12417
12418 /**
12419  * Add/del remote mapping to/from LISP control plane
12420  *
12421  * @param vam vpp API test context
12422  * @return return code
12423  */
12424 static int
12425 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12426 {
12427   unformat_input_t *input = vam->input;
12428   vl_api_lisp_add_del_remote_mapping_t *mp;
12429   f64 timeout = ~0;
12430   u32 vni = 0;
12431   //TODO: seid need remove
12432   lisp_eid_vat_t _eid, *eid = &_eid;
12433   lisp_eid_vat_t _seid, *seid = &_seid;
12434   u8 is_add = 1, del_all = 0, eid_set = 0;
12435   u32 action = ~0, p, w;
12436   ip4_address_t rloc4;
12437   ip6_address_t rloc6;
12438   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12439
12440   memset (&rloc, 0, sizeof (rloc));
12441
12442   /* Parse args required to build the message */
12443   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12444     {
12445       if (unformat (input, "del-all"))
12446         {
12447           del_all = 1;
12448         }
12449       else if (unformat (input, "del"))
12450         {
12451           is_add = 0;
12452         }
12453       else if (unformat (input, "add"))
12454         {
12455           is_add = 1;
12456         }
12457       else if (unformat (input, "deid %U", unformat_lisp_eid_vat, eid))
12458         {
12459           eid_set = 1;
12460         }
12461       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, &seid))
12462         {
12463           //TODO: Need remove, but first must be remove from CSIT test
12464         }
12465       else if (unformat (input, "vni %d", &vni))
12466         {
12467           ;
12468         }
12469       else if (unformat (input, "p %d w %d", &p, &w))
12470         {
12471           if (!curr_rloc)
12472             {
12473               errmsg ("No RLOC configured for setting priority/weight!");
12474               return -99;
12475             }
12476           curr_rloc->priority = p;
12477           curr_rloc->weight = w;
12478         }
12479       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12480         {
12481           rloc.is_ip4 = 1;
12482           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12483           vec_add1 (rlocs, rloc);
12484           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12485         }
12486       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12487         {
12488           rloc.is_ip4 = 0;
12489           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12490           vec_add1 (rlocs, rloc);
12491           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12492         }
12493       else if (unformat (input, "action %d", &action))
12494         {
12495           ;
12496         }
12497       else
12498         {
12499           clib_warning ("parse error '%U'", format_unformat_error, input);
12500           return -99;
12501         }
12502     }
12503
12504   if (0 == eid_set)
12505     {
12506       errmsg ("missing params!");
12507       return -99;
12508     }
12509
12510   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12511     {
12512       errmsg ("no action set for negative map-reply!");
12513       return -99;
12514     }
12515
12516   M (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
12517   mp->is_add = is_add;
12518   mp->vni = htonl (vni);
12519   mp->action = (u8) action;
12520   mp->eid_len = eid->len;
12521   mp->del_all = del_all;
12522   mp->eid_type = eid->type;
12523   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12524
12525   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
12526   clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
12527   vec_free (rlocs);
12528
12529   /* send it... */
12530   S;
12531
12532   /* Wait for a reply... */
12533   W;
12534
12535   /* NOTREACHED */
12536   return 0;
12537 }
12538
12539 /**
12540  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
12541  * forwarding entries in data-plane accordingly.
12542  *
12543  * @param vam vpp API test context
12544  * @return return code
12545  */
12546 static int
12547 api_lisp_add_del_adjacency (vat_main_t * vam)
12548 {
12549   unformat_input_t *input = vam->input;
12550   vl_api_lisp_add_del_adjacency_t *mp;
12551   f64 timeout = ~0;
12552   u32 vni = 0;
12553   ip4_address_t seid4, deid4;
12554   ip6_address_t seid6, deid6;
12555   u8 deid_mac[6] = { 0 };
12556   u8 seid_mac[6] = { 0 };
12557   u8 deid_type, seid_type;
12558   u32 seid_len = 0, deid_len = 0, len;
12559   u8 is_add = 1;
12560
12561   seid_type = deid_type = (u8) ~ 0;
12562
12563   /* Parse args required to build the message */
12564   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12565     {
12566       if (unformat (input, "del"))
12567         {
12568           is_add = 0;
12569         }
12570       else if (unformat (input, "add"))
12571         {
12572           is_add = 1;
12573         }
12574       else if (unformat (input, "deid %U/%d", unformat_ip4_address,
12575                          &deid4, &len))
12576         {
12577           deid_type = 0;        /* ipv4 */
12578           deid_len = len;
12579         }
12580       else if (unformat (input, "deid %U/%d", unformat_ip6_address,
12581                          &deid6, &len))
12582         {
12583           deid_type = 1;        /* ipv6 */
12584           deid_len = len;
12585         }
12586       else if (unformat (input, "deid %U", unformat_ethernet_address,
12587                          deid_mac))
12588         {
12589           deid_type = 2;        /* mac */
12590         }
12591       else if (unformat (input, "seid %U/%d", unformat_ip4_address,
12592                          &seid4, &len))
12593         {
12594           seid_type = 0;        /* ipv4 */
12595           seid_len = len;
12596         }
12597       else if (unformat (input, "seid %U/%d", unformat_ip6_address,
12598                          &seid6, &len))
12599         {
12600           seid_type = 1;        /* ipv6 */
12601           seid_len = len;
12602         }
12603       else if (unformat (input, "seid %U", unformat_ethernet_address,
12604                          seid_mac))
12605         {
12606           seid_type = 2;        /* mac */
12607         }
12608       else if (unformat (input, "vni %d", &vni))
12609         {
12610           ;
12611         }
12612       else
12613         {
12614           errmsg ("parse error '%U'", format_unformat_error, input);
12615           return -99;
12616         }
12617     }
12618
12619   if ((u8) ~ 0 == deid_type)
12620     {
12621       errmsg ("missing params!");
12622       return -99;
12623     }
12624
12625   if (seid_type != deid_type)
12626     {
12627       errmsg ("source and destination EIDs are of different types!");
12628       return -99;
12629     }
12630
12631   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
12632   mp->is_add = is_add;
12633   mp->vni = htonl (vni);
12634   mp->seid_len = seid_len;
12635   mp->deid_len = deid_len;
12636   mp->eid_type = deid_type;
12637
12638   switch (mp->eid_type)
12639     {
12640     case 0:
12641       clib_memcpy (mp->seid, &seid4, sizeof (seid4));
12642       clib_memcpy (mp->deid, &deid4, sizeof (deid4));
12643       break;
12644     case 1:
12645       clib_memcpy (mp->seid, &seid6, sizeof (seid6));
12646       clib_memcpy (mp->deid, &deid6, sizeof (deid6));
12647       break;
12648     case 2:
12649       clib_memcpy (mp->seid, seid_mac, 6);
12650       clib_memcpy (mp->deid, deid_mac, 6);
12651       break;
12652     default:
12653       errmsg ("unknown EID type %d!", mp->eid_type);
12654       return 0;
12655     }
12656
12657   /* send it... */
12658   S;
12659
12660   /* Wait for a reply... */
12661   W;
12662
12663   /* NOTREACHED */
12664   return 0;
12665 }
12666
12667 static int
12668 api_lisp_gpe_add_del_iface (vat_main_t * vam)
12669 {
12670   unformat_input_t *input = vam->input;
12671   vl_api_lisp_gpe_add_del_iface_t *mp;
12672   f64 timeout = ~0;
12673   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
12674   u32 dp_table = 0, vni = 0;
12675
12676   /* Parse args required to build the message */
12677   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12678     {
12679       if (unformat (input, "up"))
12680         {
12681           action_set = 1;
12682           is_add = 1;
12683         }
12684       else if (unformat (input, "down"))
12685         {
12686           action_set = 1;
12687           is_add = 0;
12688         }
12689       else if (unformat (input, "table_id %d", &dp_table))
12690         {
12691           dp_table_set = 1;
12692         }
12693       else if (unformat (input, "bd_id %d", &dp_table))
12694         {
12695           dp_table_set = 1;
12696           is_l2 = 1;
12697         }
12698       else if (unformat (input, "vni %d", &vni))
12699         {
12700           vni_set = 1;
12701         }
12702       else
12703         break;
12704     }
12705
12706   if (action_set == 0)
12707     {
12708       errmsg ("Action not set\n");
12709       return -99;
12710     }
12711   if (dp_table_set == 0 || vni_set == 0)
12712     {
12713       errmsg ("vni and dp_table must be set\n");
12714       return -99;
12715     }
12716
12717   /* Construct the API message */
12718   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
12719
12720   mp->is_add = is_add;
12721   mp->dp_table = dp_table;
12722   mp->is_l2 = is_l2;
12723   mp->vni = vni;
12724
12725   /* send it... */
12726   S;
12727
12728   /* Wait for a reply... */
12729   W;
12730
12731   /* NOTREACHED */
12732   return 0;
12733 }
12734
12735 /**
12736  * Add/del map request itr rlocs from LISP control plane and updates
12737  *
12738  * @param vam vpp API test context
12739  * @return return code
12740  */
12741 static int
12742 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
12743 {
12744   unformat_input_t *input = vam->input;
12745   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
12746   f64 timeout = ~0;
12747   u8 *locator_set_name = 0;
12748   u8 locator_set_name_set = 0;
12749   u8 is_add = 1;
12750
12751   /* Parse args required to build the message */
12752   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12753     {
12754       if (unformat (input, "del"))
12755         {
12756           is_add = 0;
12757         }
12758       else if (unformat (input, "%_%v%_", &locator_set_name))
12759         {
12760           locator_set_name_set = 1;
12761         }
12762       else
12763         {
12764           clib_warning ("parse error '%U'", format_unformat_error, input);
12765           return -99;
12766         }
12767     }
12768
12769   if (is_add && !locator_set_name_set)
12770     {
12771       errmsg ("itr-rloc is not set!");
12772       return -99;
12773     }
12774
12775   if (is_add && vec_len (locator_set_name) > 64)
12776     {
12777       errmsg ("itr-rloc locator-set name too long\n");
12778       vec_free (locator_set_name);
12779       return -99;
12780     }
12781
12782   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
12783   mp->is_add = is_add;
12784   if (is_add)
12785     {
12786       clib_memcpy (mp->locator_set_name, locator_set_name,
12787                    vec_len (locator_set_name));
12788     }
12789   else
12790     {
12791       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
12792     }
12793   vec_free (locator_set_name);
12794
12795   /* send it... */
12796   S;
12797
12798   /* Wait for a reply... */
12799   W;
12800
12801   /* NOTREACHED */
12802   return 0;
12803 }
12804
12805 static int
12806 lisp_locator_dump_send_msg (vat_main_t * vam, u32 locator_set_index,
12807                             u8 filter)
12808 {
12809   vl_api_lisp_locator_dump_t *mp;
12810   f64 timeout = ~0;
12811
12812   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
12813
12814   mp->locator_set_index = htonl (locator_set_index);
12815   mp->filter = filter;
12816
12817   /* send it... */
12818   S;
12819
12820   /* Use a control ping for synchronization */
12821   {
12822     vl_api_noprint_control_ping_t *mp;
12823     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12824     S;
12825   }
12826   /* Wait for a reply... */
12827   W;
12828 }
12829
12830 static inline void
12831 clean_locator_set_message (vat_main_t * vam)
12832 {
12833   locator_set_msg_t *ls = 0;
12834
12835   vec_foreach (ls, vam->locator_set_msg)
12836   {
12837     vec_free (ls->locator_set_name);
12838   }
12839
12840   vec_free (vam->locator_set_msg);
12841 }
12842
12843 static int
12844 print_locator_in_locator_set (vat_main_t * vam, u8 filter)
12845 {
12846   locator_set_msg_t *ls;
12847   locator_msg_t *loc;
12848   u8 *tmp_str = 0;
12849   int i = 0, ret = 0;
12850
12851   vec_foreach (ls, vam->locator_set_msg)
12852   {
12853     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12854     if (ret)
12855       {
12856         vec_free (vam->locator_msg);
12857         clean_locator_set_message (vam);
12858         return ret;
12859       }
12860
12861     tmp_str = format (0, "%=20s%=16d%s", ls->locator_set_name,
12862                       ls->locator_set_index,
12863                       vec_len (vam->locator_msg) ? "" : "\n");
12864     i = 0;
12865     vec_foreach (loc, vam->locator_msg)
12866     {
12867       if (i)
12868         {
12869           tmp_str = format (tmp_str, "%=37s", " ");
12870         }
12871       if (loc->local)
12872         {
12873           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
12874                             loc->sw_if_index, loc->priority, loc->weight);
12875         }
12876       else
12877         {
12878           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
12879                             loc->is_ipv6 ? format_ip6_address :
12880                             format_ip4_address,
12881                             loc->ip_address, loc->priority, loc->weight);
12882         }
12883       i++;
12884     }
12885
12886     fformat (vam->ofp, "%s", tmp_str);
12887     vec_free (tmp_str);
12888     vec_free (vam->locator_msg);
12889   }
12890
12891   clean_locator_set_message (vam);
12892
12893   return ret;
12894 }
12895
12896 static int
12897 json_locator_in_locator_set (vat_main_t * vam, u8 filter)
12898 {
12899   locator_set_msg_t *ls;
12900   locator_msg_t *loc;
12901   vat_json_node_t *node = NULL;
12902   vat_json_node_t *locator_array;
12903   vat_json_node_t *locator;
12904   struct in6_addr ip6;
12905   struct in_addr ip4;
12906   int ret = 0;
12907
12908   if (!vec_len (vam->locator_set_msg))
12909     {
12910       /* just print [] */
12911       vat_json_init_array (&vam->json_tree);
12912       vat_json_print (vam->ofp, &vam->json_tree);
12913       vam->json_tree.type = VAT_JSON_NONE;
12914       return ret;
12915     }
12916
12917   if (VAT_JSON_ARRAY != vam->json_tree.type)
12918     {
12919       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12920       vat_json_init_array (&vam->json_tree);
12921     }
12922
12923   vec_foreach (ls, vam->locator_set_msg)
12924   {
12925     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12926     if (ret)
12927       {
12928         vec_free (ls->locator_set_name);
12929         vec_free (vam->locator_msg);
12930         vec_free (vam->locator_set_msg);
12931         vat_json_free (&vam->json_tree);
12932         vam->json_tree.type = VAT_JSON_NONE;
12933         return ret;
12934       }
12935
12936     node = vat_json_array_add (&vam->json_tree);
12937     vat_json_init_object (node);
12938
12939     vat_json_object_add_uint (node, "locator-set-index",
12940                               ls->locator_set_index);
12941     vat_json_object_add_string_copy (node, "locator-set",
12942                                      ls->locator_set_name);
12943     locator_array = vat_json_object_add_list (node, "locator");
12944     vec_foreach (loc, vam->locator_msg)
12945     {
12946       locator = vat_json_array_add (locator_array);
12947       vat_json_init_object (locator);
12948       if (loc->local)
12949         {
12950           vat_json_object_add_uint (locator, "locator-index",
12951                                     loc->sw_if_index);
12952         }
12953       else
12954         {
12955           if (loc->is_ipv6)
12956             {
12957               clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
12958               vat_json_object_add_ip6 (locator, "locator", ip6);
12959             }
12960           else
12961             {
12962               clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
12963               vat_json_object_add_ip4 (locator, "locator", ip4);
12964             }
12965         }
12966       vat_json_object_add_uint (locator, "priority", loc->priority);
12967       vat_json_object_add_uint (locator, "weight", loc->weight);
12968     }
12969
12970     vec_free (ls->locator_set_name);
12971     vec_free (vam->locator_msg);
12972   }
12973
12974   vat_json_print (vam->ofp, &vam->json_tree);
12975   vat_json_free (&vam->json_tree);
12976   vam->json_tree.type = VAT_JSON_NONE;
12977
12978   vec_free (vam->locator_set_msg);
12979
12980   return ret;
12981 }
12982
12983 static int
12984 get_locator_set_index_from_msg (vat_main_t * vam, u8 * locator_set,
12985                                 u32 * locator_set_index)
12986 {
12987   locator_set_msg_t *ls;
12988   int ret = 0;
12989
12990   *locator_set_index = ~0;
12991
12992   if (!vec_len (vam->locator_set_msg))
12993     {
12994       return ret;
12995     }
12996
12997   vec_foreach (ls, vam->locator_set_msg)
12998   {
12999     if (!strcmp ((char *) locator_set, (char *) ls->locator_set_name))
13000       {
13001         *locator_set_index = ls->locator_set_index;
13002         vec_free (vam->locator_set_msg);
13003         return ret;
13004       }
13005   }
13006
13007   vec_free (vam->locator_set_msg);
13008
13009   return ret;
13010 }
13011
13012 static int
13013 get_locator_set_index (vat_main_t * vam, u8 * locator_set,
13014                        u32 * locator_set_index)
13015 {
13016   vl_api_lisp_locator_set_dump_t *mp;
13017   f64 timeout = ~0;
13018
13019   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13020   /* send it... */
13021   S;
13022
13023   /* Use a control ping for synchronization */
13024   {
13025     vl_api_noprint_control_ping_t *mp;
13026     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13027     S;
13028   }
13029
13030   vam->noprint_msg = 1;
13031   /* Wait for a reply... */
13032   /* *INDENT-OFF* */
13033   W_L
13034   ({
13035     get_locator_set_index_from_msg (vam, locator_set, locator_set_index);
13036     vam->noprint_msg = 0;
13037   });
13038   /* *INDENT-ON* */
13039
13040   /* NOTREACHED */
13041   return 0;
13042 }
13043
13044 static inline int
13045 lisp_locator_dump (vat_main_t * vam, u32 locator_set_index, u8 * locator_set,
13046                    u8 filter)
13047 {
13048   int ret = 0;
13049
13050   ASSERT (vam);
13051
13052   if (!vam->json_output)
13053     {
13054       fformat (vam->ofp, "%=20s%=16s%=16s\n",
13055                "locator", "priority", "weight");
13056     }
13057
13058   if (locator_set)
13059     {
13060       ret = get_locator_set_index (vam, locator_set, &locator_set_index);
13061     }
13062
13063   if (!ret && ~0 == locator_set_index)
13064     {
13065       return -99;
13066     }
13067
13068   ret = lisp_locator_dump_send_msg (vam, locator_set_index, filter);
13069
13070   return ret;
13071 }
13072
13073 static int
13074 lisp_locator_set_dump (vat_main_t * vam, u8 filter)
13075 {
13076   vl_api_lisp_locator_set_dump_t *mp;
13077   f64 timeout = ~0;
13078
13079   if (!vam->json_output)
13080     {
13081       fformat (vam->ofp, "%=20s%=16s%=16s%=16s%=16s\n",
13082                "locator-set", "locator-set-index", "locator", "priority",
13083                "weight");
13084     }
13085
13086   vam->noprint_msg = 1;
13087
13088   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13089
13090   mp->filter = filter;
13091
13092   /* send it... */
13093   S;
13094
13095   /* Use a control ping for synchronization */
13096   {
13097     vl_api_noprint_control_ping_t *mp;
13098     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13099     S;
13100   }
13101
13102   /* Wait for a reply... */
13103   /* *INDENT-OFF* */
13104   W_L
13105   ({
13106     if (vam->noprint_msg)
13107       {
13108         if (!vam->json_output)
13109           {
13110             print_locator_in_locator_set(vam, filter);
13111           }
13112         else
13113           {
13114             json_locator_in_locator_set(vam, filter);
13115           }
13116       }
13117     vam->noprint_msg = 0;
13118   });
13119   /* *INDENT-ON* */
13120
13121   /* NOTREACHED */
13122   return 0;
13123 }
13124
13125 static int
13126 api_lisp_locator_set_dump (vat_main_t * vam)
13127 {
13128   unformat_input_t *input = vam->input;
13129   vam->noprint_msg = 0;
13130   u32 locator_set_index = ~0;
13131   u8 locator_set_index_set = 0;
13132   u8 *locator_set = 0;
13133   u8 locator_set_set = 0;
13134   u8 filter = 0;
13135   int ret = 0;
13136
13137   /* Parse args required to build the message */
13138   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13139     {
13140       if (unformat (input, "locator-set-index %u", &locator_set_index))
13141         {
13142           locator_set_index_set = 1;
13143         }
13144       else if (unformat (input, "locator-set %s", &locator_set))
13145         {
13146           locator_set_set = 1;
13147         }
13148       else if (unformat (input, "local"))
13149         {
13150           filter = 1;
13151         }
13152       else if (unformat (input, "remote"))
13153         {
13154           filter = 2;
13155         }
13156       else
13157         {
13158           break;
13159         }
13160     }
13161
13162   if (locator_set_index_set && locator_set_set)
13163     {
13164       errmsg ("use only input parameter!\n");
13165       return -99;
13166     }
13167
13168   if (locator_set_index_set || locator_set_set)
13169     {
13170       ret = lisp_locator_dump (vam, locator_set_index, locator_set, filter);
13171     }
13172   else
13173     {
13174       ret = lisp_locator_set_dump (vam, filter);
13175     }
13176
13177   vec_free (locator_set);
13178
13179   return ret;
13180 }
13181
13182 static int
13183 api_lisp_eid_table_map_dump (vat_main_t * vam)
13184 {
13185   u8 is_l2 = 0;
13186   u8 mode_set = 0;
13187   unformat_input_t *input = vam->input;
13188   vl_api_lisp_eid_table_map_dump_t *mp;
13189   f64 timeout = ~0;
13190
13191   /* Parse args required to build the message */
13192   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13193     {
13194       if (unformat (input, "l2"))
13195         {
13196           is_l2 = 1;
13197           mode_set = 1;
13198         }
13199       else if (unformat (input, "l3"))
13200         {
13201           is_l2 = 0;
13202           mode_set = 1;
13203         }
13204       else
13205         {
13206           errmsg ("parse error '%U'", format_unformat_error, input);
13207           return -99;
13208         }
13209     }
13210
13211   if (!mode_set)
13212     {
13213       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13214       return -99;
13215     }
13216
13217   if (!vam->json_output)
13218     {
13219       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13220     }
13221
13222   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13223   mp->is_l2 = is_l2;
13224
13225   /* send it... */
13226   S;
13227
13228   /* Use a control ping for synchronization */
13229   {
13230     vl_api_control_ping_t *mp;
13231     M (CONTROL_PING, control_ping);
13232     S;
13233   }
13234   /* Wait for a reply... */
13235   W;
13236
13237   /* NOTREACHED */
13238   return 0;
13239 }
13240
13241 static int
13242 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13243 {
13244   vl_api_lisp_eid_table_vni_dump_t *mp;
13245   f64 timeout = ~0;
13246
13247   if (!vam->json_output)
13248     {
13249       fformat (vam->ofp, "VNI\n");
13250     }
13251
13252   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13253
13254   /* send it... */
13255   S;
13256
13257   /* Use a control ping for synchronization */
13258   {
13259     vl_api_control_ping_t *mp;
13260     M (CONTROL_PING, control_ping);
13261     S;
13262   }
13263   /* Wait for a reply... */
13264   W;
13265
13266   /* NOTREACHED */
13267   return 0;
13268 }
13269
13270 static int
13271 get_locator_set (vat_main_t * vam)
13272 {
13273   vl_api_lisp_locator_set_dump_t *mp;
13274   f64 timeout = ~0;
13275
13276   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13277   /* send it... */
13278   S;
13279
13280   /* Use a control ping for synchronization */
13281   {
13282     vl_api_noprint_control_ping_t *mp;
13283     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13284     S;
13285   }
13286
13287   /* Wait for a reply... */
13288   W;
13289
13290   /* NOTREACHED */
13291   return 0;
13292 }
13293
13294 static inline u8 *
13295 format_eid_for_eid_table (vat_main_t * vam, u8 * str, eid_table_t * eid_table,
13296                           int *ret)
13297 {
13298   u8 *(*format_eid) (u8 *, va_list *) = 0;
13299
13300   ASSERT (vam != NULL);
13301   ASSERT (eid_table != NULL);
13302
13303   if (ret)
13304     {
13305       *ret = 0;
13306     }
13307
13308   switch (eid_table->eid_type)
13309     {
13310     case 0:
13311     case 1:
13312       format_eid = (eid_table->eid_type ? format_ip6_address :
13313                     format_ip4_address);
13314       str = format (0, "[%d] %U/%d", eid_table->vni,
13315                     format_eid, eid_table->eid, eid_table->eid_prefix_len);
13316       break;
13317     case 2:
13318       str = format (0, "[%d] %U", eid_table->vni,
13319                     format_ethernet_address, eid_table->eid);
13320       break;
13321     default:
13322       errmsg ("unknown EID type %d!", eid_table->eid_type);
13323       if (ret)
13324         {
13325           *ret = -99;
13326         }
13327       return 0;
13328     }
13329
13330   return str;
13331 }
13332
13333 static inline u8 *
13334 format_locator_set_for_eid_table (vat_main_t * vam, u8 * str,
13335                                   eid_table_t * eid_table)
13336 {
13337   locator_set_msg_t *ls = 0;
13338
13339   ASSERT (vam != NULL);
13340   ASSERT (eid_table != NULL);
13341
13342   if (eid_table->is_local)
13343     {
13344       vec_foreach (ls, vam->locator_set_msg)
13345       {
13346         if (ls->locator_set_index == eid_table->locator_set_index)
13347           {
13348             str = format (0, "local(%s)", ls->locator_set_name);
13349             return str;
13350           }
13351       }
13352
13353       str = format (0, "local(N/A)");
13354     }
13355   else
13356     {
13357       str = format (0, "remote");
13358     }
13359
13360   return str;
13361 }
13362
13363 static inline u8 *
13364 format_locator_for_eid_table (vat_main_t * vam, u8 * str,
13365                               eid_table_t * eid_table)
13366 {
13367   locator_msg_t *loc = 0;
13368   int first_line = 1;
13369
13370   ASSERT (vam != NULL);
13371   ASSERT (eid_table != NULL);
13372
13373   if (~0 == eid_table->locator_set_index)
13374     {
13375       return format (0, "action: %d\n", eid_table->action);
13376     }
13377
13378   vec_foreach (loc, vam->locator_msg)
13379   {
13380     if (!first_line)
13381       {
13382         if (loc->local)
13383           {
13384             str = format (str, "%-55s%-d\n", " ", loc->sw_if_index);
13385           }
13386         else
13387           {
13388             str = format (str, "%=55s%-U\n", " ",
13389                           loc->is_ipv6 ? format_ip6_address :
13390                           format_ip4_address, loc->ip_address);
13391           }
13392
13393         continue;
13394       }
13395
13396     if (loc->local)
13397       {
13398         str = format (str, "%-30d%-20u%-u\n", loc->sw_if_index,
13399                       eid_table->ttl, eid_table->authoritative);
13400       }
13401     else
13402       {
13403         str = format (str, "%-30U%-20u%-u\n",
13404                       loc->is_ipv6 ? format_ip6_address :
13405                       format_ip4_address,
13406                       loc->ip_address, eid_table->ttl,
13407                       eid_table->authoritative);
13408       }
13409     first_line = 0;
13410   }
13411
13412   return str;
13413 }
13414
13415 static int
13416 print_lisp_eid_table_dump (vat_main_t * vam)
13417 {
13418   eid_table_t *eid_table = 0;
13419   u8 *tmp_str = 0, *tmp_str2 = 0;
13420   int ret = 0;
13421
13422   ASSERT (vam != NULL);
13423
13424   ret = get_locator_set (vam);
13425   if (ret)
13426     {
13427       vec_free (vam->eid_tables);
13428       return ret;
13429     }
13430
13431   fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type", "locators",
13432            "ttl", "authoritative");
13433
13434   vec_foreach (eid_table, vam->eid_tables)
13435   {
13436     if (~0 != eid_table->locator_set_index)
13437       {
13438         ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index,
13439                                           0);
13440         if (ret)
13441           {
13442             vec_free (vam->locator_msg);
13443             clean_locator_set_message (vam);
13444             vec_free (vam->eid_tables);
13445             return ret;
13446           }
13447       }
13448
13449     tmp_str2 = format_eid_for_eid_table (vam, tmp_str2, eid_table, &ret);
13450     if (ret)
13451       {
13452         vec_free (vam->locator_msg);
13453         clean_locator_set_message (vam);
13454         vec_free (vam->eid_tables);
13455         return ret;
13456       }
13457
13458     tmp_str = format (0, "%-35s", tmp_str2);
13459     vec_free (tmp_str2);
13460
13461     tmp_str2 = format_locator_set_for_eid_table (vam, tmp_str2, eid_table);
13462     tmp_str = format (tmp_str, "%-20s", tmp_str2);
13463     vec_free (tmp_str2);
13464
13465     tmp_str2 = format_locator_for_eid_table (vam, tmp_str2, eid_table);
13466     tmp_str = format (tmp_str, "%-s", tmp_str2);
13467     vec_free (tmp_str2);
13468
13469     fformat (vam->ofp, "%s", tmp_str);
13470     vec_free (tmp_str);
13471     vec_free (vam->locator_msg);
13472   }
13473
13474   clean_locator_set_message (vam);
13475   vec_free (vam->eid_tables);
13476
13477   return ret;
13478 }
13479
13480 static inline void
13481 json_locator_set_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13482                                 eid_table_t * eid_table)
13483 {
13484   locator_set_msg_t *ls = 0;
13485   u8 *s = 0;
13486
13487   ASSERT (vam != NULL);
13488   ASSERT (node != NULL);
13489   ASSERT (eid_table != NULL);
13490
13491   if (eid_table->is_local)
13492     {
13493       vec_foreach (ls, vam->locator_set_msg)
13494       {
13495         if (ls->locator_set_index == eid_table->locator_set_index)
13496           {
13497             vat_json_object_add_string_copy (node, "locator-set",
13498                                              ls->locator_set_name);
13499             return;
13500           }
13501       }
13502
13503       s = format (0, "N/A");
13504       vec_add1 (s, 0);
13505       vat_json_object_add_string_copy (node, "locator-set", s);
13506       vec_free (s);
13507     }
13508   else
13509     {
13510       s = format (0, "remote");
13511       vec_add1 (s, 0);
13512       vat_json_object_add_string_copy (node, "locator-set", s);
13513       vec_free (s);
13514     }
13515 }
13516
13517 static inline int
13518 json_eid_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13519                         eid_table_t * eid_table)
13520 {
13521   u8 *s = 0;
13522   struct in6_addr ip6;
13523   struct in_addr ip4;
13524
13525   ASSERT (vam != NULL);
13526   ASSERT (node != NULL);
13527   ASSERT (eid_table != NULL);
13528
13529   switch (eid_table->eid_type)
13530     {
13531     case 0:
13532       clib_memcpy (&ip4, eid_table->eid, sizeof (ip4));
13533       vat_json_object_add_ip4 (node, "eid", ip4);
13534       vat_json_object_add_uint (node, "eid-prefix-len",
13535                                 eid_table->eid_prefix_len);
13536       break;
13537     case 1:
13538       clib_memcpy (&ip6, eid_table->eid, sizeof (ip6));
13539       vat_json_object_add_ip6 (node, "eid", ip6);
13540       vat_json_object_add_uint (node, "eid-prefix-len",
13541                                 eid_table->eid_prefix_len);
13542       break;
13543     case 2:
13544       s = format (0, "%U", format_ethernet_address, eid_table->eid);
13545       vec_add1 (s, 0);
13546       vat_json_object_add_string_copy (node, "eid", s);
13547       vec_free (s);
13548       break;
13549     default:
13550       errmsg ("unknown EID type %d!", eid_table->eid_type);
13551       return -99;
13552     }
13553
13554   return 0;
13555 }
13556
13557 static inline void
13558 json_locator_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13559                             eid_table_t * eid_table)
13560 {
13561   locator_msg_t *loc = 0;
13562   vat_json_node_t *locator_array = 0;
13563   vat_json_node_t *locator = 0;
13564   struct in6_addr ip6;
13565   struct in_addr ip4;
13566
13567   ASSERT (vam != NULL);
13568   ASSERT (node != NULL);
13569   ASSERT (eid_table != NULL);
13570
13571   locator_array = vat_json_object_add_list (node, "locator");
13572   vec_foreach (loc, vam->locator_msg)
13573   {
13574     locator = vat_json_array_add (locator_array);
13575     vat_json_init_object (locator);
13576     if (loc->local)
13577       {
13578         vat_json_object_add_uint (locator, "locator-index", loc->sw_if_index);
13579       }
13580     else
13581       {
13582         if (loc->is_ipv6)
13583           {
13584             clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
13585             vat_json_object_add_ip6 (locator, "locator", ip6);
13586           }
13587         else
13588           {
13589             clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
13590             vat_json_object_add_ip4 (locator, "locator", ip4);
13591           }
13592       }
13593   }
13594 }
13595
13596 static int
13597 json_lisp_eid_table_dump (vat_main_t * vam)
13598 {
13599   eid_table_t *eid_table;
13600   vat_json_node_t *node = 0;
13601   int ret = 0;
13602
13603   ASSERT (vam != NULL);
13604
13605   ret = get_locator_set (vam);
13606   if (ret)
13607     {
13608       vec_free (vam->eid_tables);
13609       return ret;
13610     }
13611
13612   if (!vec_len (vam->eid_tables))
13613     {
13614       /* just print [] */
13615       vat_json_init_array (&vam->json_tree);
13616       vat_json_print (vam->ofp, &vam->json_tree);
13617       vam->json_tree.type = VAT_JSON_NONE;
13618       return ret;
13619     }
13620
13621   if (VAT_JSON_ARRAY != vam->json_tree.type)
13622     {
13623       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13624       vat_json_init_array (&vam->json_tree);
13625     }
13626
13627   vec_foreach (eid_table, vam->eid_tables)
13628   {
13629     ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index, 0);
13630     if (ret)
13631       {
13632         vec_free (vam->locator_msg);
13633         vec_free (vam->eid_tables);
13634         clean_locator_set_message (vam);
13635         vat_json_free (&vam->json_tree);
13636         vam->json_tree.type = VAT_JSON_NONE;
13637         return ret;
13638       }
13639
13640     node = vat_json_array_add (&vam->json_tree);
13641     vat_json_init_object (node);
13642
13643     vat_json_object_add_uint (node, "vni", eid_table->vni);
13644
13645     json_locator_set_for_eid_table (vam, node, eid_table);
13646     ret = json_eid_for_eid_table (vam, node, eid_table);
13647     if (ret)
13648       {
13649         vec_free (vam->locator_msg);
13650         vec_free (vam->eid_tables);
13651         clean_locator_set_message (vam);
13652         vat_json_free (&vam->json_tree);
13653         vam->json_tree.type = VAT_JSON_NONE;
13654         return ret;
13655       }
13656
13657     json_locator_for_eid_table (vam, node, eid_table);
13658
13659     vat_json_object_add_uint (node, "ttl", eid_table->ttl);
13660     vat_json_object_add_uint (node, "authoritative",
13661                               eid_table->authoritative);
13662
13663     vec_free (vam->locator_msg);
13664   }
13665
13666   vat_json_print (vam->ofp, &vam->json_tree);
13667   vat_json_free (&vam->json_tree);
13668   vam->json_tree.type = VAT_JSON_NONE;
13669
13670   clean_locator_set_message (vam);
13671   vec_free (vam->eid_tables);
13672
13673   return ret;
13674 }
13675
13676 static int
13677 api_lisp_eid_table_dump (vat_main_t * vam)
13678 {
13679   unformat_input_t *i = vam->input;
13680   vl_api_lisp_eid_table_dump_t *mp;
13681   f64 timeout = ~0;
13682   struct in_addr ip4;
13683   struct in6_addr ip6;
13684   u8 mac[6];
13685   u8 eid_type = ~0, eid_set = 0;
13686   u32 prefix_length = ~0, t, vni = 0;
13687   u8 filter = 0;
13688
13689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13690     {
13691       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13692         {
13693           eid_set = 1;
13694           eid_type = 0;
13695           prefix_length = t;
13696         }
13697       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13698         {
13699           eid_set = 1;
13700           eid_type = 1;
13701           prefix_length = t;
13702         }
13703       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13704         {
13705           eid_set = 1;
13706           eid_type = 2;
13707         }
13708       else if (unformat (i, "vni %d", &t))
13709         {
13710           vni = t;
13711         }
13712       else if (unformat (i, "local"))
13713         {
13714           filter = 1;
13715         }
13716       else if (unformat (i, "remote"))
13717         {
13718           filter = 2;
13719         }
13720       else
13721         {
13722           errmsg ("parse error '%U'", format_unformat_error, i);
13723           return -99;
13724         }
13725     }
13726
13727   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13728
13729   mp->filter = filter;
13730   if (eid_set)
13731     {
13732       mp->eid_set = 1;
13733       mp->vni = htonl (vni);
13734       mp->eid_type = eid_type;
13735       switch (eid_type)
13736         {
13737         case 0:
13738           mp->prefix_length = prefix_length;
13739           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13740           break;
13741         case 1:
13742           mp->prefix_length = prefix_length;
13743           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13744           break;
13745         case 2:
13746           clib_memcpy (mp->eid, mac, sizeof (mac));
13747           break;
13748         default:
13749           errmsg ("unknown EID type %d!", eid_type);
13750           return -99;
13751         }
13752     }
13753
13754   vam->noprint_msg = 1;
13755
13756   /* send it... */
13757   S;
13758
13759   /* Use a control ping for synchronization */
13760   {
13761     vl_api_noprint_control_ping_t *mp;
13762     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13763     S;
13764   }
13765
13766   /* Wait for a reply... */
13767   /* *INDENT-OFF* */
13768   W_L
13769   ({
13770     if (vam->noprint_msg)
13771       {
13772         if (!vam->json_output)
13773           {
13774             vam->retval = print_lisp_eid_table_dump(vam);
13775           }
13776         else
13777           {
13778             vam->retval = json_lisp_eid_table_dump(vam);
13779           }
13780       }
13781     vam->noprint_msg = 0;
13782   });
13783   /* *INDENT-ON* */
13784
13785   /* NOTREACHED */
13786   return 0;
13787 }
13788
13789 static int
13790 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13791 {
13792   vl_api_lisp_gpe_tunnel_dump_t *mp;
13793   f64 timeout = ~0;
13794
13795   if (!vam->json_output)
13796     {
13797       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13798                "%=16s%=16s%=16s%=16s%=16s\n",
13799                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13800                "Decap next", "Lisp version", "Flags", "Next protocol",
13801                "ver_res", "res", "iid");
13802     }
13803
13804   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13805   /* send it... */
13806   S;
13807
13808   /* Use a control ping for synchronization */
13809   {
13810     vl_api_control_ping_t *mp;
13811     M (CONTROL_PING, control_ping);
13812     S;
13813   }
13814   /* Wait for a reply... */
13815   W;
13816
13817   /* NOTREACHED */
13818   return 0;
13819 }
13820
13821 static int
13822 api_lisp_map_resolver_dump (vat_main_t * vam)
13823 {
13824   vl_api_lisp_map_resolver_dump_t *mp;
13825   f64 timeout = ~0;
13826
13827   if (!vam->json_output)
13828     {
13829       fformat (vam->ofp, "%=20s\n", "Map resolver");
13830     }
13831
13832   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13833   /* send it... */
13834   S;
13835
13836   /* Use a control ping for synchronization */
13837   {
13838     vl_api_control_ping_t *mp;
13839     M (CONTROL_PING, control_ping);
13840     S;
13841   }
13842   /* Wait for a reply... */
13843   W;
13844
13845   /* NOTREACHED */
13846   return 0;
13847 }
13848
13849 static int
13850 api_show_lisp_status (vat_main_t * vam)
13851 {
13852   vl_api_show_lisp_status_t *mp;
13853   f64 timeout = ~0;
13854
13855   if (!vam->json_output)
13856     {
13857       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13858     }
13859
13860   M (SHOW_LISP_STATUS, show_lisp_status);
13861   /* send it... */
13862   S;
13863   /* Wait for a reply... */
13864   W;
13865
13866   /* NOTREACHED */
13867   return 0;
13868 }
13869
13870 static int
13871 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13872 {
13873   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13874   f64 timeout = ~0;
13875
13876   if (!vam->json_output)
13877     {
13878       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13879     }
13880
13881   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13882   /* send it... */
13883   S;
13884   /* Wait for a reply... */
13885   W;
13886
13887   /* NOTREACHED */
13888   return 0;
13889 }
13890
13891 static int
13892 api_af_packet_create (vat_main_t * vam)
13893 {
13894   unformat_input_t *i = vam->input;
13895   vl_api_af_packet_create_t *mp;
13896   f64 timeout;
13897   u8 *host_if_name = 0;
13898   u8 hw_addr[6];
13899   u8 random_hw_addr = 1;
13900
13901   memset (hw_addr, 0, sizeof (hw_addr));
13902
13903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13904     {
13905       if (unformat (i, "name %s", &host_if_name))
13906         vec_add1 (host_if_name, 0);
13907       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13908         random_hw_addr = 0;
13909       else
13910         break;
13911     }
13912
13913   if (!vec_len (host_if_name))
13914     {
13915       errmsg ("host-interface name must be specified");
13916       return -99;
13917     }
13918
13919   if (vec_len (host_if_name) > 64)
13920     {
13921       errmsg ("host-interface name too long");
13922       return -99;
13923     }
13924
13925   M (AF_PACKET_CREATE, af_packet_create);
13926
13927   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13928   clib_memcpy (mp->hw_addr, hw_addr, 6);
13929   mp->use_random_hw_addr = random_hw_addr;
13930   vec_free (host_if_name);
13931
13932   S;
13933   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
13934   /* NOTREACHED */
13935   return 0;
13936 }
13937
13938 static int
13939 api_af_packet_delete (vat_main_t * vam)
13940 {
13941   unformat_input_t *i = vam->input;
13942   vl_api_af_packet_delete_t *mp;
13943   f64 timeout;
13944   u8 *host_if_name = 0;
13945
13946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13947     {
13948       if (unformat (i, "name %s", &host_if_name))
13949         vec_add1 (host_if_name, 0);
13950       else
13951         break;
13952     }
13953
13954   if (!vec_len (host_if_name))
13955     {
13956       errmsg ("host-interface name must be specified");
13957       return -99;
13958     }
13959
13960   if (vec_len (host_if_name) > 64)
13961     {
13962       errmsg ("host-interface name too long");
13963       return -99;
13964     }
13965
13966   M (AF_PACKET_DELETE, af_packet_delete);
13967
13968   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13969   vec_free (host_if_name);
13970
13971   S;
13972   W;
13973   /* NOTREACHED */
13974   return 0;
13975 }
13976
13977 static int
13978 api_policer_add_del (vat_main_t * vam)
13979 {
13980   unformat_input_t *i = vam->input;
13981   vl_api_policer_add_del_t *mp;
13982   f64 timeout;
13983   u8 is_add = 1;
13984   u8 *name = 0;
13985   u32 cir = 0;
13986   u32 eir = 0;
13987   u64 cb = 0;
13988   u64 eb = 0;
13989   u8 rate_type = 0;
13990   u8 round_type = 0;
13991   u8 type = 0;
13992   u8 color_aware = 0;
13993   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
13994
13995   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
13996   conform_action.dscp = 0;
13997   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
13998   exceed_action.dscp = 0;
13999   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14000   violate_action.dscp = 0;
14001
14002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14003     {
14004       if (unformat (i, "del"))
14005         is_add = 0;
14006       else if (unformat (i, "name %s", &name))
14007         vec_add1 (name, 0);
14008       else if (unformat (i, "cir %u", &cir))
14009         ;
14010       else if (unformat (i, "eir %u", &eir))
14011         ;
14012       else if (unformat (i, "cb %u", &cb))
14013         ;
14014       else if (unformat (i, "eb %u", &eb))
14015         ;
14016       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14017                          &rate_type))
14018         ;
14019       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14020                          &round_type))
14021         ;
14022       else if (unformat (i, "type %U", unformat_policer_type, &type))
14023         ;
14024       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14025                          &conform_action))
14026         ;
14027       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14028                          &exceed_action))
14029         ;
14030       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14031                          &violate_action))
14032         ;
14033       else if (unformat (i, "color-aware"))
14034         color_aware = 1;
14035       else
14036         break;
14037     }
14038
14039   if (!vec_len (name))
14040     {
14041       errmsg ("policer name must be specified");
14042       return -99;
14043     }
14044
14045   if (vec_len (name) > 64)
14046     {
14047       errmsg ("policer name too long");
14048       return -99;
14049     }
14050
14051   M (POLICER_ADD_DEL, policer_add_del);
14052
14053   clib_memcpy (mp->name, name, vec_len (name));
14054   vec_free (name);
14055   mp->is_add = is_add;
14056   mp->cir = cir;
14057   mp->eir = eir;
14058   mp->cb = cb;
14059   mp->eb = eb;
14060   mp->rate_type = rate_type;
14061   mp->round_type = round_type;
14062   mp->type = type;
14063   mp->conform_action_type = conform_action.action_type;
14064   mp->conform_dscp = conform_action.dscp;
14065   mp->exceed_action_type = exceed_action.action_type;
14066   mp->exceed_dscp = exceed_action.dscp;
14067   mp->violate_action_type = violate_action.action_type;
14068   mp->violate_dscp = violate_action.dscp;
14069   mp->color_aware = color_aware;
14070
14071   S;
14072   W;
14073   /* NOTREACHED */
14074   return 0;
14075 }
14076
14077 static int
14078 api_policer_dump (vat_main_t * vam)
14079 {
14080   unformat_input_t *i = vam->input;
14081   vl_api_policer_dump_t *mp;
14082   f64 timeout = ~0;
14083   u8 *match_name = 0;
14084   u8 match_name_valid = 0;
14085
14086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14087     {
14088       if (unformat (i, "name %s", &match_name))
14089         {
14090           vec_add1 (match_name, 0);
14091           match_name_valid = 1;
14092         }
14093       else
14094         break;
14095     }
14096
14097   M (POLICER_DUMP, policer_dump);
14098   mp->match_name_valid = match_name_valid;
14099   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14100   vec_free (match_name);
14101   /* send it... */
14102   S;
14103
14104   /* Use a control ping for synchronization */
14105   {
14106     vl_api_control_ping_t *mp;
14107     M (CONTROL_PING, control_ping);
14108     S;
14109   }
14110   /* Wait for a reply... */
14111   W;
14112
14113   /* NOTREACHED */
14114   return 0;
14115 }
14116
14117 static int
14118 api_policer_classify_set_interface (vat_main_t * vam)
14119 {
14120   unformat_input_t *i = vam->input;
14121   vl_api_policer_classify_set_interface_t *mp;
14122   f64 timeout;
14123   u32 sw_if_index;
14124   int sw_if_index_set;
14125   u32 ip4_table_index = ~0;
14126   u32 ip6_table_index = ~0;
14127   u32 l2_table_index = ~0;
14128   u8 is_add = 1;
14129
14130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14131     {
14132       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14133         sw_if_index_set = 1;
14134       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14135         sw_if_index_set = 1;
14136       else if (unformat (i, "del"))
14137         is_add = 0;
14138       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14139         ;
14140       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14141         ;
14142       else if (unformat (i, "l2-table %d", &l2_table_index))
14143         ;
14144       else
14145         {
14146           clib_warning ("parse error '%U'", format_unformat_error, i);
14147           return -99;
14148         }
14149     }
14150
14151   if (sw_if_index_set == 0)
14152     {
14153       errmsg ("missing interface name or sw_if_index\n");
14154       return -99;
14155     }
14156
14157   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14158
14159   mp->sw_if_index = ntohl (sw_if_index);
14160   mp->ip4_table_index = ntohl (ip4_table_index);
14161   mp->ip6_table_index = ntohl (ip6_table_index);
14162   mp->l2_table_index = ntohl (l2_table_index);
14163   mp->is_add = is_add;
14164
14165   S;
14166   W;
14167   /* NOTREACHED */
14168   return 0;
14169 }
14170
14171 static int
14172 api_policer_classify_dump (vat_main_t * vam)
14173 {
14174   unformat_input_t *i = vam->input;
14175   vl_api_policer_classify_dump_t *mp;
14176   f64 timeout = ~0;
14177   u8 type = POLICER_CLASSIFY_N_TABLES;
14178
14179   if (unformat (i, "type %U", unformat_classify_table_type, &type))
14180     ;
14181   else
14182     {
14183       errmsg ("classify table type must be specified\n");
14184       return -99;
14185     }
14186
14187   if (!vam->json_output)
14188     {
14189       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14190     }
14191
14192   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14193   mp->type = type;
14194   /* send it... */
14195   S;
14196
14197   /* Use a control ping for synchronization */
14198   {
14199     vl_api_control_ping_t *mp;
14200     M (CONTROL_PING, control_ping);
14201     S;
14202   }
14203   /* Wait for a reply... */
14204   W;
14205
14206   /* NOTREACHED */
14207   return 0;
14208 }
14209
14210 static int
14211 api_netmap_create (vat_main_t * vam)
14212 {
14213   unformat_input_t *i = vam->input;
14214   vl_api_netmap_create_t *mp;
14215   f64 timeout;
14216   u8 *if_name = 0;
14217   u8 hw_addr[6];
14218   u8 random_hw_addr = 1;
14219   u8 is_pipe = 0;
14220   u8 is_master = 0;
14221
14222   memset (hw_addr, 0, sizeof (hw_addr));
14223
14224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14225     {
14226       if (unformat (i, "name %s", &if_name))
14227         vec_add1 (if_name, 0);
14228       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14229         random_hw_addr = 0;
14230       else if (unformat (i, "pipe"))
14231         is_pipe = 1;
14232       else if (unformat (i, "master"))
14233         is_master = 1;
14234       else if (unformat (i, "slave"))
14235         is_master = 0;
14236       else
14237         break;
14238     }
14239
14240   if (!vec_len (if_name))
14241     {
14242       errmsg ("interface name must be specified");
14243       return -99;
14244     }
14245
14246   if (vec_len (if_name) > 64)
14247     {
14248       errmsg ("interface name too long");
14249       return -99;
14250     }
14251
14252   M (NETMAP_CREATE, netmap_create);
14253
14254   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14255   clib_memcpy (mp->hw_addr, hw_addr, 6);
14256   mp->use_random_hw_addr = random_hw_addr;
14257   mp->is_pipe = is_pipe;
14258   mp->is_master = is_master;
14259   vec_free (if_name);
14260
14261   S;
14262   W;
14263   /* NOTREACHED */
14264   return 0;
14265 }
14266
14267 static int
14268 api_netmap_delete (vat_main_t * vam)
14269 {
14270   unformat_input_t *i = vam->input;
14271   vl_api_netmap_delete_t *mp;
14272   f64 timeout;
14273   u8 *if_name = 0;
14274
14275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14276     {
14277       if (unformat (i, "name %s", &if_name))
14278         vec_add1 (if_name, 0);
14279       else
14280         break;
14281     }
14282
14283   if (!vec_len (if_name))
14284     {
14285       errmsg ("interface name must be specified");
14286       return -99;
14287     }
14288
14289   if (vec_len (if_name) > 64)
14290     {
14291       errmsg ("interface name too long");
14292       return -99;
14293     }
14294
14295   M (NETMAP_DELETE, netmap_delete);
14296
14297   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14298   vec_free (if_name);
14299
14300   S;
14301   W;
14302   /* NOTREACHED */
14303   return 0;
14304 }
14305
14306 static void vl_api_mpls_gre_tunnel_details_t_handler
14307   (vl_api_mpls_gre_tunnel_details_t * mp)
14308 {
14309   vat_main_t *vam = &vat_main;
14310   i32 i;
14311   i32 len = ntohl (mp->nlabels);
14312
14313   if (mp->l2_only == 0)
14314     {
14315       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14316                ntohl (mp->tunnel_index),
14317                format_ip4_address, &mp->tunnel_src,
14318                format_ip4_address, &mp->tunnel_dst,
14319                format_ip4_address, &mp->intfc_address,
14320                ntohl (mp->mask_width));
14321       for (i = 0; i < len; i++)
14322         {
14323           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14324         }
14325       fformat (vam->ofp, "\n");
14326       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14327                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14328     }
14329   else
14330     {
14331       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14332                ntohl (mp->tunnel_index),
14333                format_ip4_address, &mp->tunnel_src,
14334                format_ip4_address, &mp->tunnel_dst,
14335                format_ip4_address, &mp->intfc_address);
14336       for (i = 0; i < len; i++)
14337         {
14338           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14339         }
14340       fformat (vam->ofp, "\n");
14341       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14342                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14343     }
14344 }
14345
14346 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14347   (vl_api_mpls_gre_tunnel_details_t * mp)
14348 {
14349   vat_main_t *vam = &vat_main;
14350   vat_json_node_t *node = NULL;
14351   struct in_addr ip4;
14352   i32 i;
14353   i32 len = ntohl (mp->nlabels);
14354
14355   if (VAT_JSON_ARRAY != vam->json_tree.type)
14356     {
14357       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14358       vat_json_init_array (&vam->json_tree);
14359     }
14360   node = vat_json_array_add (&vam->json_tree);
14361
14362   vat_json_init_object (node);
14363   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14364   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14365   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14366   vat_json_object_add_uint (node, "inner_fib_index",
14367                             ntohl (mp->inner_fib_index));
14368   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14369   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14370   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14371   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14372   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14373   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14374   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14375   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14376   vat_json_object_add_uint (node, "outer_fib_index",
14377                             ntohl (mp->outer_fib_index));
14378   vat_json_object_add_uint (node, "label_count", len);
14379   for (i = 0; i < len; i++)
14380     {
14381       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14382     }
14383 }
14384
14385 static int
14386 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14387 {
14388   vl_api_mpls_gre_tunnel_dump_t *mp;
14389   f64 timeout;
14390   i32 index = -1;
14391
14392   /* Parse args required to build the message */
14393   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14394     {
14395       if (!unformat (vam->input, "tunnel_index %d", &index))
14396         {
14397           index = -1;
14398           break;
14399         }
14400     }
14401
14402   fformat (vam->ofp, "  tunnel_index %d\n", index);
14403
14404   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14405   mp->tunnel_index = htonl (index);
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   W;
14415 }
14416
14417 static void vl_api_mpls_eth_tunnel_details_t_handler
14418   (vl_api_mpls_eth_tunnel_details_t * mp)
14419 {
14420   vat_main_t *vam = &vat_main;
14421   i32 i;
14422   i32 len = ntohl (mp->nlabels);
14423
14424   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14425            ntohl (mp->tunnel_index),
14426            format_ethernet_address, &mp->tunnel_dst_mac,
14427            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14428   for (i = 0; i < len; i++)
14429     {
14430       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14431     }
14432   fformat (vam->ofp, "\n");
14433   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14434            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14435 }
14436
14437 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14438   (vl_api_mpls_eth_tunnel_details_t * mp)
14439 {
14440   vat_main_t *vam = &vat_main;
14441   vat_json_node_t *node = NULL;
14442   struct in_addr ip4;
14443   i32 i;
14444   i32 len = ntohl (mp->nlabels);
14445
14446   if (VAT_JSON_ARRAY != vam->json_tree.type)
14447     {
14448       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14449       vat_json_init_array (&vam->json_tree);
14450     }
14451   node = vat_json_array_add (&vam->json_tree);
14452
14453   vat_json_init_object (node);
14454   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14455   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14456   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14457   vat_json_object_add_uint (node, "inner_fib_index",
14458                             ntohl (mp->inner_fib_index));
14459   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14460   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14461   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14462   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14463   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14464                                    format (0, "%U", format_ethernet_address,
14465                                            &mp->tunnel_dst_mac));
14466   vat_json_object_add_uint (node, "tx_sw_if_index",
14467                             ntohl (mp->tx_sw_if_index));
14468   vat_json_object_add_uint (node, "label_count", len);
14469   for (i = 0; i < len; i++)
14470     {
14471       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14472     }
14473 }
14474
14475 static int
14476 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14477 {
14478   vl_api_mpls_eth_tunnel_dump_t *mp;
14479   f64 timeout;
14480   i32 index = -1;
14481
14482   /* Parse args required to build the message */
14483   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14484     {
14485       if (!unformat (vam->input, "tunnel_index %d", &index))
14486         {
14487           index = -1;
14488           break;
14489         }
14490     }
14491
14492   fformat (vam->ofp, "  tunnel_index %d\n", index);
14493
14494   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14495   mp->tunnel_index = htonl (index);
14496   S;
14497
14498   /* Use a control ping for synchronization */
14499   {
14500     vl_api_control_ping_t *mp;
14501     M (CONTROL_PING, control_ping);
14502     S;
14503   }
14504   W;
14505 }
14506
14507 static void vl_api_mpls_fib_encap_details_t_handler
14508   (vl_api_mpls_fib_encap_details_t * mp)
14509 {
14510   vat_main_t *vam = &vat_main;
14511   i32 i;
14512   i32 len = ntohl (mp->nlabels);
14513
14514   fformat (vam->ofp, "table %d, dest %U, label ",
14515            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14516   for (i = 0; i < len; i++)
14517     {
14518       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14519     }
14520   fformat (vam->ofp, "\n");
14521 }
14522
14523 static void vl_api_mpls_fib_encap_details_t_handler_json
14524   (vl_api_mpls_fib_encap_details_t * mp)
14525 {
14526   vat_main_t *vam = &vat_main;
14527   vat_json_node_t *node = NULL;
14528   i32 i;
14529   i32 len = ntohl (mp->nlabels);
14530   struct in_addr ip4;
14531
14532   if (VAT_JSON_ARRAY != vam->json_tree.type)
14533     {
14534       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14535       vat_json_init_array (&vam->json_tree);
14536     }
14537   node = vat_json_array_add (&vam->json_tree);
14538
14539   vat_json_init_object (node);
14540   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14541   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14542   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14543   vat_json_object_add_ip4 (node, "dest", ip4);
14544   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14545   vat_json_object_add_uint (node, "label_count", len);
14546   for (i = 0; i < len; i++)
14547     {
14548       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14549     }
14550 }
14551
14552 static int
14553 api_mpls_fib_encap_dump (vat_main_t * vam)
14554 {
14555   vl_api_mpls_fib_encap_dump_t *mp;
14556   f64 timeout;
14557
14558   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14559   S;
14560
14561   /* Use a control ping for synchronization */
14562   {
14563     vl_api_control_ping_t *mp;
14564     M (CONTROL_PING, control_ping);
14565     S;
14566   }
14567   W;
14568 }
14569
14570 static void vl_api_mpls_fib_decap_details_t_handler
14571   (vl_api_mpls_fib_decap_details_t * mp)
14572 {
14573   vat_main_t *vam = &vat_main;
14574
14575   fformat (vam->ofp,
14576            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14577            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14578            ntohl (mp->label), ntohl (mp->s_bit));
14579 }
14580
14581 static void vl_api_mpls_fib_decap_details_t_handler_json
14582   (vl_api_mpls_fib_decap_details_t * mp)
14583 {
14584   vat_main_t *vam = &vat_main;
14585   vat_json_node_t *node = NULL;
14586   struct in_addr ip4;
14587
14588   if (VAT_JSON_ARRAY != vam->json_tree.type)
14589     {
14590       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14591       vat_json_init_array (&vam->json_tree);
14592     }
14593   node = vat_json_array_add (&vam->json_tree);
14594
14595   vat_json_init_object (node);
14596   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14597   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14598   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14599   vat_json_object_add_ip4 (node, "dest", ip4);
14600   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14601   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14602   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14603   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14604   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14605 }
14606
14607 static int
14608 api_mpls_fib_decap_dump (vat_main_t * vam)
14609 {
14610   vl_api_mpls_fib_decap_dump_t *mp;
14611   f64 timeout;
14612
14613   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14614   S;
14615
14616   /* Use a control ping for synchronization */
14617   {
14618     vl_api_control_ping_t *mp;
14619     M (CONTROL_PING, control_ping);
14620     S;
14621   }
14622   W;
14623 }
14624
14625 int
14626 api_classify_table_ids (vat_main_t * vam)
14627 {
14628   vl_api_classify_table_ids_t *mp;
14629   f64 timeout;
14630
14631   /* Construct the API message */
14632   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14633   mp->context = 0;
14634
14635   S;
14636   W;
14637   /* NOTREACHED */
14638   return 0;
14639 }
14640
14641 int
14642 api_classify_table_by_interface (vat_main_t * vam)
14643 {
14644   unformat_input_t *input = vam->input;
14645   vl_api_classify_table_by_interface_t *mp;
14646   f64 timeout;
14647
14648   u32 sw_if_index = ~0;
14649   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14650     {
14651       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14652         ;
14653       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14654         ;
14655       else
14656         break;
14657     }
14658   if (sw_if_index == ~0)
14659     {
14660       errmsg ("missing interface name or sw_if_index\n");
14661       return -99;
14662     }
14663
14664   /* Construct the API message */
14665   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14666   mp->context = 0;
14667   mp->sw_if_index = ntohl (sw_if_index);
14668
14669   S;
14670   W;
14671   /* NOTREACHED */
14672   return 0;
14673 }
14674
14675 int
14676 api_classify_table_info (vat_main_t * vam)
14677 {
14678   unformat_input_t *input = vam->input;
14679   vl_api_classify_table_info_t *mp;
14680   f64 timeout;
14681
14682   u32 table_id = ~0;
14683   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14684     {
14685       if (unformat (input, "table_id %d", &table_id))
14686         ;
14687       else
14688         break;
14689     }
14690   if (table_id == ~0)
14691     {
14692       errmsg ("missing table id\n");
14693       return -99;
14694     }
14695
14696   /* Construct the API message */
14697   M (CLASSIFY_TABLE_INFO, classify_table_info);
14698   mp->context = 0;
14699   mp->table_id = ntohl (table_id);
14700
14701   S;
14702   W;
14703   /* NOTREACHED */
14704   return 0;
14705 }
14706
14707 int
14708 api_classify_session_dump (vat_main_t * vam)
14709 {
14710   unformat_input_t *input = vam->input;
14711   vl_api_classify_session_dump_t *mp;
14712   f64 timeout;
14713
14714   u32 table_id = ~0;
14715   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14716     {
14717       if (unformat (input, "table_id %d", &table_id))
14718         ;
14719       else
14720         break;
14721     }
14722   if (table_id == ~0)
14723     {
14724       errmsg ("missing table id\n");
14725       return -99;
14726     }
14727
14728   /* Construct the API message */
14729   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14730   mp->context = 0;
14731   mp->table_id = ntohl (table_id);
14732   S;
14733
14734   /* Use a control ping for synchronization */
14735   {
14736     vl_api_control_ping_t *mp;
14737     M (CONTROL_PING, control_ping);
14738     S;
14739   }
14740   W;
14741   /* NOTREACHED */
14742   return 0;
14743 }
14744
14745 static void
14746 vl_api_ipfix_details_t_handler (vl_api_ipfix_details_t * mp)
14747 {
14748   vat_main_t *vam = &vat_main;
14749
14750   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14751            "src_address %U, fib_index %u, path_mtu %u, "
14752            "template_interval %u\n",
14753            format_ip4_address, mp->collector_address,
14754            ntohs (mp->collector_port),
14755            format_ip4_address, mp->src_address,
14756            ntohl (mp->fib_index),
14757            ntohl (mp->path_mtu), ntohl (mp->template_interval));
14758
14759   vam->retval = 0;
14760   vam->result_ready = 1;
14761 }
14762
14763 static void
14764 vl_api_ipfix_details_t_handler_json (vl_api_ipfix_details_t * mp)
14765 {
14766   vat_main_t *vam = &vat_main;
14767   vat_json_node_t node;
14768   struct in_addr collector_address;
14769   struct in_addr src_address;
14770
14771   vat_json_init_object (&node);
14772   clib_memcpy (&collector_address, &mp->collector_address,
14773                sizeof (collector_address));
14774   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14775   vat_json_object_add_uint (&node, "collector_port",
14776                             ntohs (mp->collector_port));
14777   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14778   vat_json_object_add_ip4 (&node, "src_address", src_address);
14779   vat_json_object_add_uint (&node, "fib_index", ntohl (mp->fib_index));
14780   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14781   vat_json_object_add_uint (&node, "template_interval",
14782                             ntohl (mp->template_interval));
14783
14784   vat_json_print (vam->ofp, &node);
14785   vat_json_free (&node);
14786   vam->retval = 0;
14787   vam->result_ready = 1;
14788 }
14789
14790 int
14791 api_ipfix_dump (vat_main_t * vam)
14792 {
14793   vl_api_ipfix_dump_t *mp;
14794   f64 timeout;
14795
14796   /* Construct the API message */
14797   M (IPFIX_DUMP, ipfix_dump);
14798   mp->context = 0;
14799
14800   S;
14801   W;
14802   /* NOTREACHED */
14803   return 0;
14804 }
14805
14806 int
14807 api_pg_create_interface (vat_main_t * vam)
14808 {
14809   unformat_input_t *input = vam->input;
14810   vl_api_pg_create_interface_t *mp;
14811   f64 timeout;
14812
14813   u32 if_id = ~0;
14814   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14815     {
14816       if (unformat (input, "if_id %d", &if_id))
14817         ;
14818       else
14819         break;
14820     }
14821   if (if_id == ~0)
14822     {
14823       errmsg ("missing pg interface index\n");
14824       return -99;
14825     }
14826
14827   /* Construct the API message */
14828   M (PG_CREATE_INTERFACE, pg_create_interface);
14829   mp->context = 0;
14830   mp->interface_id = ntohl (if_id);
14831
14832   S;
14833   W;
14834   /* NOTREACHED */
14835   return 0;
14836 }
14837
14838 int
14839 api_pg_capture (vat_main_t * vam)
14840 {
14841   unformat_input_t *input = vam->input;
14842   vl_api_pg_capture_t *mp;
14843   f64 timeout;
14844
14845   u32 if_id = ~0;
14846   u8 enable = 1;
14847   u32 count = 1;
14848   u8 pcap_file_set = 0;
14849   u8 *pcap_file = 0;
14850   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14851     {
14852       if (unformat (input, "if_id %d", &if_id))
14853         ;
14854       else if (unformat (input, "pcap %s", &pcap_file))
14855         pcap_file_set = 1;
14856       else if (unformat (input, "count %d", &count))
14857         ;
14858       else if (unformat (input, "disable"))
14859         enable = 0;
14860       else
14861         break;
14862     }
14863   if (if_id == ~0)
14864     {
14865       errmsg ("missing pg interface index\n");
14866       return -99;
14867     }
14868   if (pcap_file_set > 0)
14869     {
14870       if (vec_len (pcap_file) > 255)
14871         {
14872           errmsg ("pcap file name is too long\n");
14873           return -99;
14874         }
14875     }
14876
14877   u32 name_len = vec_len (pcap_file);
14878   /* Construct the API message */
14879   M (PG_CAPTURE, pg_capture);
14880   mp->context = 0;
14881   mp->interface_id = ntohl (if_id);
14882   mp->is_enabled = enable;
14883   mp->count = ntohl (count);
14884   mp->pcap_name_length = ntohl (name_len);
14885   if (pcap_file_set != 0)
14886     {
14887       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
14888     }
14889   vec_free (pcap_file);
14890
14891   S;
14892   W;
14893   /* NOTREACHED */
14894   return 0;
14895 }
14896
14897 int
14898 api_pg_enable_disable (vat_main_t * vam)
14899 {
14900   unformat_input_t *input = vam->input;
14901   vl_api_pg_enable_disable_t *mp;
14902   f64 timeout;
14903
14904   u8 enable = 1;
14905   u8 stream_name_set = 0;
14906   u8 *stream_name = 0;
14907   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14908     {
14909       if (unformat (input, "stream %s", &stream_name))
14910         stream_name_set = 1;
14911       else if (unformat (input, "disable"))
14912         enable = 0;
14913       else
14914         break;
14915     }
14916
14917   if (stream_name_set > 0)
14918     {
14919       if (vec_len (stream_name) > 255)
14920         {
14921           errmsg ("stream name too long\n");
14922           return -99;
14923         }
14924     }
14925
14926   u32 name_len = vec_len (stream_name);
14927   /* Construct the API message */
14928   M (PG_ENABLE_DISABLE, pg_enable_disable);
14929   mp->context = 0;
14930   mp->is_enabled = enable;
14931   if (stream_name_set != 0)
14932     {
14933       mp->stream_name_length = ntohl (name_len);
14934       clib_memcpy (mp->stream_name, stream_name, name_len);
14935     }
14936   vec_free (stream_name);
14937
14938   S;
14939   W;
14940   /* NOTREACHED */
14941   return 0;
14942 }
14943
14944 int
14945 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
14946 {
14947   unformat_input_t *input = vam->input;
14948   vl_api_ip_source_and_port_range_check_add_del_t *mp;
14949   f64 timeout;
14950
14951   u16 *low_ports = 0;
14952   u16 *high_ports = 0;
14953   u16 this_low;
14954   u16 this_hi;
14955   ip4_address_t ip4_addr;
14956   ip6_address_t ip6_addr;
14957   u32 length;
14958   u32 tmp, tmp2;
14959   u8 prefix_set = 0;
14960   u32 vrf_id = ~0;
14961   u8 is_add = 1;
14962   u8 is_ipv6 = 0;
14963
14964   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14965     {
14966       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
14967         {
14968           prefix_set = 1;
14969         }
14970       else
14971         if (unformat
14972             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
14973         {
14974           prefix_set = 1;
14975           is_ipv6 = 1;
14976         }
14977       else if (unformat (input, "vrf %d", &vrf_id))
14978         ;
14979       else if (unformat (input, "del"))
14980         is_add = 0;
14981       else if (unformat (input, "port %d", &tmp))
14982         {
14983           if (tmp == 0 || tmp > 65535)
14984             {
14985               errmsg ("port %d out of range", tmp);
14986               return -99;
14987             }
14988           this_low = tmp;
14989           this_hi = this_low + 1;
14990           vec_add1 (low_ports, this_low);
14991           vec_add1 (high_ports, this_hi);
14992         }
14993       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
14994         {
14995           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
14996             {
14997               errmsg ("incorrect range parameters\n");
14998               return -99;
14999             }
15000           this_low = tmp;
15001           /* Note: in debug CLI +1 is added to high before
15002              passing to real fn that does "the work"
15003              (ip_source_and_port_range_check_add_del).
15004              This fn is a wrapper around the binary API fn a
15005              control plane will call, which expects this increment
15006              to have occurred. Hence letting the binary API control
15007              plane fn do the increment for consistency between VAT
15008              and other control planes.
15009            */
15010           this_hi = tmp2;
15011           vec_add1 (low_ports, this_low);
15012           vec_add1 (high_ports, this_hi);
15013         }
15014       else
15015         break;
15016     }
15017
15018   if (prefix_set == 0)
15019     {
15020       errmsg ("<address>/<mask> not specified\n");
15021       return -99;
15022     }
15023
15024   if (vrf_id == ~0)
15025     {
15026       errmsg ("VRF ID required, not specified\n");
15027       return -99;
15028     }
15029
15030   if (vrf_id == 0)
15031     {
15032       errmsg
15033         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15034       return -99;
15035     }
15036
15037   if (vec_len (low_ports) == 0)
15038     {
15039       errmsg ("At least one port or port range required\n");
15040       return -99;
15041     }
15042
15043   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15044      ip_source_and_port_range_check_add_del);
15045
15046   mp->is_add = is_add;
15047
15048   if (is_ipv6)
15049     {
15050       mp->is_ipv6 = 1;
15051       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15052     }
15053   else
15054     {
15055       mp->is_ipv6 = 0;
15056       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15057     }
15058
15059   mp->mask_length = length;
15060   mp->number_of_ranges = vec_len (low_ports);
15061
15062   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15063   vec_free (low_ports);
15064
15065   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15066   vec_free (high_ports);
15067
15068   mp->vrf_id = ntohl (vrf_id);
15069
15070   S;
15071   W;
15072   /* NOTREACHED */
15073   return 0;
15074 }
15075
15076 int
15077 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15078 {
15079   unformat_input_t *input = vam->input;
15080   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15081   f64 timeout;
15082   u32 sw_if_index = ~0;
15083   int vrf_set = 0;
15084   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15085   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15086   u8 is_add = 1;
15087
15088   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15089     {
15090       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15091         ;
15092       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15093         ;
15094       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15095         vrf_set = 1;
15096       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15097         vrf_set = 1;
15098       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15099         vrf_set = 1;
15100       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15101         vrf_set = 1;
15102       else if (unformat (input, "del"))
15103         is_add = 0;
15104       else
15105         break;
15106     }
15107
15108   if (sw_if_index == ~0)
15109     {
15110       errmsg ("Interface required but not specified\n");
15111       return -99;
15112     }
15113
15114   if (vrf_set == 0)
15115     {
15116       errmsg ("VRF ID required but not specified\n");
15117       return -99;
15118     }
15119
15120   if (tcp_out_vrf_id == 0
15121       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15122     {
15123       errmsg
15124         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15125       return -99;
15126     }
15127
15128   /* Construct the API message */
15129   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15130      ip_source_and_port_range_check_interface_add_del);
15131
15132   mp->sw_if_index = ntohl (sw_if_index);
15133   mp->is_add = is_add;
15134   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15135   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15136   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15137   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15138
15139   /* send it... */
15140   S;
15141
15142   /* Wait for a reply... */
15143   W;
15144 }
15145
15146 static int
15147 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15148 {
15149   unformat_input_t *i = vam->input;
15150   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15151   f64 timeout;
15152   u32 local_sa_id = 0;
15153   u32 remote_sa_id = 0;
15154   ip4_address_t src_address;
15155   ip4_address_t dst_address;
15156   u8 is_add = 1;
15157
15158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15159     {
15160       if (unformat (i, "local_sa %d", &local_sa_id))
15161         ;
15162       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15163         ;
15164       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15165         ;
15166       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15167         ;
15168       else if (unformat (i, "del"))
15169         is_add = 0;
15170       else
15171         {
15172           clib_warning ("parse error '%U'", format_unformat_error, i);
15173           return -99;
15174         }
15175     }
15176
15177   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15178
15179   mp->local_sa_id = ntohl (local_sa_id);
15180   mp->remote_sa_id = ntohl (remote_sa_id);
15181   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15182   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15183   mp->is_add = is_add;
15184
15185   S;
15186   W;
15187   /* NOTREACHED */
15188   return 0;
15189 }
15190
15191 static void vl_api_ipsec_gre_tunnel_details_t_handler
15192   (vl_api_ipsec_gre_tunnel_details_t * mp)
15193 {
15194   vat_main_t *vam = &vat_main;
15195
15196   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15197            ntohl (mp->sw_if_index),
15198            format_ip4_address, &mp->src_address,
15199            format_ip4_address, &mp->dst_address,
15200            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15201 }
15202
15203 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15204   (vl_api_ipsec_gre_tunnel_details_t * mp)
15205 {
15206   vat_main_t *vam = &vat_main;
15207   vat_json_node_t *node = NULL;
15208   struct in_addr ip4;
15209
15210   if (VAT_JSON_ARRAY != vam->json_tree.type)
15211     {
15212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15213       vat_json_init_array (&vam->json_tree);
15214     }
15215   node = vat_json_array_add (&vam->json_tree);
15216
15217   vat_json_init_object (node);
15218   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15219   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15220   vat_json_object_add_ip4 (node, "src_address", ip4);
15221   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15222   vat_json_object_add_ip4 (node, "dst_address", ip4);
15223   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15224   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15225 }
15226
15227 static int
15228 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15229 {
15230   unformat_input_t *i = vam->input;
15231   vl_api_ipsec_gre_tunnel_dump_t *mp;
15232   f64 timeout;
15233   u32 sw_if_index;
15234   u8 sw_if_index_set = 0;
15235
15236   /* Parse args required to build the message */
15237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15238     {
15239       if (unformat (i, "sw_if_index %d", &sw_if_index))
15240         sw_if_index_set = 1;
15241       else
15242         break;
15243     }
15244
15245   if (sw_if_index_set == 0)
15246     {
15247       sw_if_index = ~0;
15248     }
15249
15250   if (!vam->json_output)
15251     {
15252       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15253                "sw_if_index", "src_address", "dst_address",
15254                "local_sa_id", "remote_sa_id");
15255     }
15256
15257   /* Get list of gre-tunnel interfaces */
15258   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15259
15260   mp->sw_if_index = htonl (sw_if_index);
15261
15262   S;
15263
15264   /* Use a control ping for synchronization */
15265   {
15266     vl_api_control_ping_t *mp;
15267     M (CONTROL_PING, control_ping);
15268     S;
15269   }
15270   W;
15271 }
15272
15273 static int
15274 api_delete_subif (vat_main_t * vam)
15275 {
15276   unformat_input_t *i = vam->input;
15277   vl_api_delete_subif_t *mp;
15278   f64 timeout;
15279   u32 sw_if_index = ~0;
15280
15281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15282     {
15283       if (unformat (i, "sw_if_index %d", &sw_if_index))
15284         ;
15285       else
15286         break;
15287     }
15288
15289   if (sw_if_index == ~0)
15290     {
15291       errmsg ("missing sw_if_index\n");
15292       return -99;
15293     }
15294
15295   /* Construct the API message */
15296   M (DELETE_SUBIF, delete_subif);
15297   mp->sw_if_index = ntohl (sw_if_index);
15298
15299   S;
15300   W;
15301 }
15302
15303 static int
15304 q_or_quit (vat_main_t * vam)
15305 {
15306   longjmp (vam->jump_buf, 1);
15307   return 0;                     /* not so much */
15308 }
15309
15310 static int
15311 q (vat_main_t * vam)
15312 {
15313   return q_or_quit (vam);
15314 }
15315
15316 static int
15317 quit (vat_main_t * vam)
15318 {
15319   return q_or_quit (vam);
15320 }
15321
15322 static int
15323 comment (vat_main_t * vam)
15324 {
15325   return 0;
15326 }
15327
15328 static int
15329 cmd_cmp (void *a1, void *a2)
15330 {
15331   u8 **c1 = a1;
15332   u8 **c2 = a2;
15333
15334   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15335 }
15336
15337 static int
15338 help (vat_main_t * vam)
15339 {
15340   u8 **cmds = 0;
15341   u8 *name = 0;
15342   hash_pair_t *p;
15343   unformat_input_t *i = vam->input;
15344   int j;
15345
15346   if (unformat (i, "%s", &name))
15347     {
15348       uword *hs;
15349
15350       vec_add1 (name, 0);
15351
15352       hs = hash_get_mem (vam->help_by_name, name);
15353       if (hs)
15354         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15355       else
15356         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15357       vec_free (name);
15358       return 0;
15359     }
15360
15361   fformat (vam->ofp, "Help is available for the following:\n");
15362
15363     /* *INDENT-OFF* */
15364     hash_foreach_pair (p, vam->function_by_name,
15365     ({
15366       vec_add1 (cmds, (u8 *)(p->key));
15367     }));
15368     /* *INDENT-ON* */
15369
15370   vec_sort_with_function (cmds, cmd_cmp);
15371
15372   for (j = 0; j < vec_len (cmds); j++)
15373     fformat (vam->ofp, "%s\n", cmds[j]);
15374
15375   vec_free (cmds);
15376   return 0;
15377 }
15378
15379 static int
15380 set (vat_main_t * vam)
15381 {
15382   u8 *name = 0, *value = 0;
15383   unformat_input_t *i = vam->input;
15384
15385   if (unformat (i, "%s", &name))
15386     {
15387       /* The input buffer is a vector, not a string. */
15388       value = vec_dup (i->buffer);
15389       vec_delete (value, i->index, 0);
15390       /* Almost certainly has a trailing newline */
15391       if (value[vec_len (value) - 1] == '\n')
15392         value[vec_len (value) - 1] = 0;
15393       /* Make sure it's a proper string, one way or the other */
15394       vec_add1 (value, 0);
15395       (void) clib_macro_set_value (&vam->macro_main,
15396                                    (char *) name, (char *) value);
15397     }
15398   else
15399     errmsg ("usage: set <name> <value>\n");
15400
15401   vec_free (name);
15402   vec_free (value);
15403   return 0;
15404 }
15405
15406 static int
15407 unset (vat_main_t * vam)
15408 {
15409   u8 *name = 0;
15410
15411   if (unformat (vam->input, "%s", &name))
15412     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15413       errmsg ("unset: %s wasn't set\n", name);
15414   vec_free (name);
15415   return 0;
15416 }
15417
15418 typedef struct
15419 {
15420   u8 *name;
15421   u8 *value;
15422 } macro_sort_t;
15423
15424
15425 static int
15426 macro_sort_cmp (void *a1, void *a2)
15427 {
15428   macro_sort_t *s1 = a1;
15429   macro_sort_t *s2 = a2;
15430
15431   return strcmp ((char *) (s1->name), (char *) (s2->name));
15432 }
15433
15434 static int
15435 dump_macro_table (vat_main_t * vam)
15436 {
15437   macro_sort_t *sort_me = 0, *sm;
15438   int i;
15439   hash_pair_t *p;
15440
15441     /* *INDENT-OFF* */
15442     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15443     ({
15444       vec_add2 (sort_me, sm, 1);
15445       sm->name = (u8 *)(p->key);
15446       sm->value = (u8 *) (p->value[0]);
15447     }));
15448     /* *INDENT-ON* */
15449
15450   vec_sort_with_function (sort_me, macro_sort_cmp);
15451
15452   if (vec_len (sort_me))
15453     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15454   else
15455     fformat (vam->ofp, "The macro table is empty...\n");
15456
15457   for (i = 0; i < vec_len (sort_me); i++)
15458     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15459   return 0;
15460 }
15461
15462 static int
15463 dump_node_table (vat_main_t * vam)
15464 {
15465   int i, j;
15466   vlib_node_t *node, *next_node;
15467
15468   if (vec_len (vam->graph_nodes) == 0)
15469     {
15470       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15471       return 0;
15472     }
15473
15474   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15475     {
15476       node = vam->graph_nodes[i];
15477       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15478       for (j = 0; j < vec_len (node->next_nodes); j++)
15479         {
15480           if (node->next_nodes[j] != ~0)
15481             {
15482               next_node = vam->graph_nodes[node->next_nodes[j]];
15483               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15484             }
15485         }
15486     }
15487   return 0;
15488 }
15489
15490 static int
15491 search_node_table (vat_main_t * vam)
15492 {
15493   unformat_input_t *line_input = vam->input;
15494   u8 *node_to_find;
15495   int j;
15496   vlib_node_t *node, *next_node;
15497   uword *p;
15498
15499   if (vam->graph_node_index_by_name == 0)
15500     {
15501       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15502       return 0;
15503     }
15504
15505   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15506     {
15507       if (unformat (line_input, "%s", &node_to_find))
15508         {
15509           vec_add1 (node_to_find, 0);
15510           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15511           if (p == 0)
15512             {
15513               fformat (vam->ofp, "%s not found...\n", node_to_find);
15514               goto out;
15515             }
15516           node = vam->graph_nodes[p[0]];
15517           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15518           for (j = 0; j < vec_len (node->next_nodes); j++)
15519             {
15520               if (node->next_nodes[j] != ~0)
15521                 {
15522                   next_node = vam->graph_nodes[node->next_nodes[j]];
15523                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15524                 }
15525             }
15526         }
15527
15528       else
15529         {
15530           clib_warning ("parse error '%U'", format_unformat_error,
15531                         line_input);
15532           return -99;
15533         }
15534
15535     out:
15536       vec_free (node_to_find);
15537
15538     }
15539
15540   return 0;
15541 }
15542
15543
15544 static int
15545 script (vat_main_t * vam)
15546 {
15547   u8 *s = 0;
15548   char *save_current_file;
15549   unformat_input_t save_input;
15550   jmp_buf save_jump_buf;
15551   u32 save_line_number;
15552
15553   FILE *new_fp, *save_ifp;
15554
15555   if (unformat (vam->input, "%s", &s))
15556     {
15557       new_fp = fopen ((char *) s, "r");
15558       if (new_fp == 0)
15559         {
15560           errmsg ("Couldn't open script file %s\n", s);
15561           vec_free (s);
15562           return -99;
15563         }
15564     }
15565   else
15566     {
15567       errmsg ("Missing script name\n");
15568       return -99;
15569     }
15570
15571   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15572   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15573   save_ifp = vam->ifp;
15574   save_line_number = vam->input_line_number;
15575   save_current_file = (char *) vam->current_file;
15576
15577   vam->input_line_number = 0;
15578   vam->ifp = new_fp;
15579   vam->current_file = s;
15580   do_one_file (vam);
15581
15582   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15583   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15584   vam->ifp = save_ifp;
15585   vam->input_line_number = save_line_number;
15586   vam->current_file = (u8 *) save_current_file;
15587   vec_free (s);
15588
15589   return 0;
15590 }
15591
15592 static int
15593 echo (vat_main_t * vam)
15594 {
15595   fformat (vam->ofp, "%v", vam->input->buffer);
15596   return 0;
15597 }
15598
15599 /* List of API message constructors, CLI names map to api_xxx */
15600 #define foreach_vpe_api_msg                                             \
15601 _(create_loopback,"[mac <mac-addr>]")                                   \
15602 _(sw_interface_dump,"")                                                 \
15603 _(sw_interface_set_flags,                                               \
15604   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15605 _(sw_interface_add_del_address,                                         \
15606   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15607 _(sw_interface_set_table,                                               \
15608   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15609 _(sw_interface_set_vpath,                                               \
15610   "<intfc> | sw_if_index <id> enable | disable")                        \
15611 _(sw_interface_set_l2_xconnect,                                         \
15612   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15613   "enable | disable")                                                   \
15614 _(sw_interface_set_l2_bridge,                                           \
15615   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15616   "[shg <split-horizon-group>] [bvi]\n"                                 \
15617   "enable | disable")                                                   \
15618 _(bridge_domain_add_del,                                                \
15619   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15620 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15621 _(l2fib_add_del,                                                        \
15622   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15623 _(l2_flags,                                                             \
15624   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15625 _(bridge_flags,                                                         \
15626   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15627 _(tap_connect,                                                          \
15628   "tapname <name> mac <mac-addr> | random-mac")                         \
15629 _(tap_modify,                                                           \
15630   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15631 _(tap_delete,                                                           \
15632   "<vpp-if-name> | sw_if_index <id>")                                   \
15633 _(sw_interface_tap_dump, "")                                            \
15634 _(ip_add_del_route,                                                     \
15635   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15636   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15637   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15638   "[multipath] [count <n>]")                                            \
15639 _(proxy_arp_add_del,                                                    \
15640   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15641 _(proxy_arp_intfc_enable_disable,                                       \
15642   "<intfc> | sw_if_index <id> enable | disable")                        \
15643 _(mpls_add_del_encap,                                                   \
15644   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15645 _(mpls_add_del_decap,                                                   \
15646   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15647 _(mpls_gre_add_del_tunnel,                                              \
15648   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15649   "adj <ip4-address>/<mask-width> [del]")                               \
15650 _(sw_interface_set_unnumbered,                                          \
15651   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15652 _(ip_neighbor_add_del,                                                  \
15653   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15654   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15655 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15656 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15657 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15658   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15659   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15660   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15661 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15662 _(reset_fib, "vrf <n> [ipv6]")                                          \
15663 _(dhcp_proxy_config,                                                    \
15664   "svr <v46-address> src <v46-address>\n"                               \
15665    "insert-cid <n> [del]")                                              \
15666 _(dhcp_proxy_config_2,                                                  \
15667   "svr <v46-address> src <v46-address>\n"                               \
15668    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15669 _(dhcp_proxy_set_vss,                                                   \
15670   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15671 _(dhcp_client_config,                                                   \
15672   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15673 _(set_ip_flow_hash,                                                     \
15674   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15675 _(sw_interface_ip6_enable_disable,                                      \
15676   "<intfc> | sw_if_index <id> enable | disable")                        \
15677 _(sw_interface_ip6_set_link_local_address,                              \
15678   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15679 _(sw_interface_ip6nd_ra_prefix,                                         \
15680   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15681   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15682   "[nolink] [isno]")                                                    \
15683 _(sw_interface_ip6nd_ra_config,                                         \
15684   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15685   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15686   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15687 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15688 _(l2_patch_add_del,                                                     \
15689   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15690   "enable | disable")                                                   \
15691 _(mpls_ethernet_add_del_tunnel,                                         \
15692   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15693   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15694 _(mpls_ethernet_add_del_tunnel_2,                                       \
15695   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15696   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15697 _(sr_tunnel_add_del,                                                    \
15698   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15699   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15700   "[policy <policy_name>]")                                             \
15701 _(sr_policy_add_del,                                                    \
15702   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15703 _(sr_multicast_map_add_del,                                             \
15704   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15705 _(classify_add_del_table,                                               \
15706   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15707   "[del] mask <mask-value>\n"                                           \
15708   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15709 _(classify_add_del_session,                                             \
15710   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15711   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15712   "  [l3 [ip4|ip6]]")                                                   \
15713 _(classify_set_interface_ip_table,                                      \
15714   "<intfc> | sw_if_index <nn> table <nn>")                              \
15715 _(classify_set_interface_l2_tables,                                     \
15716   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15717   "  [other-table <nn>]")                                               \
15718 _(get_node_index, "node <node-name")                                    \
15719 _(add_node_next, "node <node-name> next <next-node-name>")              \
15720 _(l2tpv3_create_tunnel,                                                 \
15721   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15722   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15723   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15724 _(l2tpv3_set_tunnel_cookies,                                            \
15725   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15726   "[new_remote_cookie <nn>]\n")                                         \
15727 _(l2tpv3_interface_enable_disable,                                      \
15728   "<intfc> | sw_if_index <nn> enable | disable")                        \
15729 _(l2tpv3_set_lookup_key,                                                \
15730   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15731 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15732 _(vxlan_add_del_tunnel,                                                 \
15733   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15734   " [decap-next l2|ip4|ip6] [del]")                                     \
15735 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15736 _(gre_add_del_tunnel,                                                   \
15737   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n")          \
15738 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15739 _(l2_fib_clear_table, "")                                               \
15740 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15741 _(l2_interface_vlan_tag_rewrite,                                        \
15742   "<intfc> | sw_if_index <nn> \n"                                       \
15743   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15744   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15745 _(create_vhost_user_if,                                                 \
15746         "socket <filename> [server] [renumber <dev_instance>] "         \
15747         "[mac <mac_address>]")                                          \
15748 _(modify_vhost_user_if,                                                 \
15749         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15750         "[server] [renumber <dev_instance>]")                           \
15751 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15752 _(sw_interface_vhost_user_dump, "")                                     \
15753 _(show_version, "")                                                     \
15754 _(vxlan_gpe_add_del_tunnel,                                             \
15755   "local <addr> remote <addr> vni <nn>\n"                               \
15756     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15757   "[next-ethernet] [next-nsh]\n")                                       \
15758 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15759 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15760 _(interface_name_renumber,                                              \
15761   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15762 _(input_acl_set_interface,                                              \
15763   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15764   "  [l2-table <nn>] [del]")                                            \
15765 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15766 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
15767 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15768 _(ip_dump, "ipv4 | ipv6")                                               \
15769 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15770 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15771   "  spid_id <n> ")                                                     \
15772 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15773   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15774   "  integ_alg <alg> integ_key <hex>")                                  \
15775 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15776   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15777   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15778   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15779 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15780 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15781 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15782   "(auth_data 0x<data> | auth_data <data>)")                            \
15783 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15784   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15785 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15786   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15787   "(local|remote)")                                                     \
15788 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15789 _(delete_loopback,"sw_if_index <nn>")                                   \
15790 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15791 _(map_add_domain,                                                       \
15792   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
15793   "ip6-src <ip6addr> "                                                  \
15794   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
15795 _(map_del_domain, "index <n>")                                          \
15796 _(map_add_del_rule,                                                     \
15797   "index <n> psid <n> dst <ip6addr> [del]")                             \
15798 _(map_domain_dump, "")                                                  \
15799 _(map_rule_dump, "index <map-domain>")                                  \
15800 _(want_interface_events,  "enable|disable")                             \
15801 _(want_stats,"enable|disable")                                          \
15802 _(get_first_msg_id, "client <name>")                                    \
15803 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15804 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15805   "fib-id <nn> [ip4][ip6][default]")                                    \
15806 _(get_node_graph, " ")                                                  \
15807 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15808 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
15809 _(ioam_disable, "")                                                \
15810 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
15811                             " sw_if_index <sw_if_index> p <priority> "  \
15812                             "w <weight>] [del]")                        \
15813 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
15814                         "iface <intf> | sw_if_index <sw_if_index> "     \
15815                         "p <priority> w <weight> [del]")                \
15816 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
15817                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
15818                           "locator-set <locator_name> [del]")           \
15819 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
15820   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
15821 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
15822 _(lisp_gpe_enable_disable, "enable|disable")                            \
15823 _(lisp_enable_disable, "enable|disable")                                \
15824 _(lisp_gpe_add_del_iface, "up|down")                                    \
15825 _(lisp_add_del_remote_mapping, "add|del vni <vni> deid <dest-eid> "     \
15826                                "rloc <locator> p <prio> "               \
15827                                "w <weight> [rloc <loc> ... ] "          \
15828                                "action <action> [del-all]")             \
15829 _(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid "     \
15830                           "<src-eid> rloc <locator> p <prio> w <weight>"\
15831                           "[rloc <loc> ... ] action <action>")          \
15832 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
15833 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
15834 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
15835 _(lisp_locator_set_dump, "[locator-set-index <ls-index> | "             \
15836                          "locator-set <loc-set-name>] [local | remote]")\
15837 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
15838                        "[local] | [remote]")                            \
15839 _(lisp_eid_table_vni_dump, "")                                          \
15840 _(lisp_eid_table_map_dump, "l2|l3")                                     \
15841 _(lisp_gpe_tunnel_dump, "")                                             \
15842 _(lisp_map_resolver_dump, "")                                           \
15843 _(show_lisp_status, "")                                                 \
15844 _(lisp_get_map_request_itr_rlocs, "")                                   \
15845 _(show_lisp_pitr, "")                                                   \
15846 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15847 _(af_packet_delete, "name <host interface name>")                       \
15848 _(policer_add_del, "name <policer name> <params> [del]")                \
15849 _(policer_dump, "[name <policer name>]")                                \
15850 _(policer_classify_set_interface,                                       \
15851   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15852   "  [l2-table <nn>] [del]")                                            \
15853 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15854 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
15855     "[master|slave]")                                                   \
15856 _(netmap_delete, "name <interface name>")                               \
15857 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15858 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15859 _(mpls_fib_encap_dump, "")                                              \
15860 _(mpls_fib_decap_dump, "")                                              \
15861 _(classify_table_ids, "")                                               \
15862 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15863 _(classify_table_info, "table_id <nn>")                                 \
15864 _(classify_session_dump, "table_id <nn>")                               \
15865 _(ipfix_enable, "collector_address <ip4> [collector_port <nn>] "        \
15866                 "src_address <ip4> [fib_id <nn>] [path_mtu <nn>] "      \
15867                 "[template_interval <nn>]")                             \
15868 _(ipfix_dump, "")                                                       \
15869 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15870 _(pg_create_interface, "if_id <nn>")                                    \
15871 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15872 _(pg_enable_disable, "[stream <id>] disable")                           \
15873 _(ip_source_and_port_range_check_add_del,                               \
15874   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15875 _(ip_source_and_port_range_check_interface_add_del,                     \
15876   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15877   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
15878 _(ipsec_gre_add_del_tunnel,                                             \
15879   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
15880 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
15881 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")
15882
15883 /* List of command functions, CLI names map directly to functions */
15884 #define foreach_cli_function                                    \
15885 _(comment, "usage: comment <ignore-rest-of-line>")              \
15886 _(dump_interface_table, "usage: dump_interface_table")          \
15887 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15888 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15889 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15890 _(dump_stats_table, "usage: dump_stats_table")                  \
15891 _(dump_macro_table, "usage: dump_macro_table ")                 \
15892 _(dump_node_table, "usage: dump_node_table")                    \
15893 _(echo, "usage: echo <message>")                                \
15894 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15895 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
15896 _(help, "usage: help")                                          \
15897 _(q, "usage: quit")                                             \
15898 _(quit, "usage: quit")                                          \
15899 _(search_node_table, "usage: search_node_table <name>...")      \
15900 _(set, "usage: set <variable-name> <value>")                    \
15901 _(script, "usage: script <file-name>")                          \
15902 _(unset, "usage: unset <variable-name>")
15903
15904 #define _(N,n)                                  \
15905     static void vl_api_##n##_t_handler_uni      \
15906     (vl_api_##n##_t * mp)                       \
15907     {                                           \
15908         vat_main_t * vam = &vat_main;           \
15909         if (vam->json_output) {                 \
15910             vl_api_##n##_t_handler_json(mp);    \
15911         } else {                                \
15912             vl_api_##n##_t_handler(mp);         \
15913         }                                       \
15914     }
15915 foreach_vpe_api_reply_msg;
15916 #undef _
15917
15918 void
15919 vat_api_hookup (vat_main_t * vam)
15920 {
15921 #define _(N,n)                                                  \
15922     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15923                            vl_api_##n##_t_handler_uni,          \
15924                            vl_noop_handler,                     \
15925                            vl_api_##n##_t_endian,               \
15926                            vl_api_##n##_t_print,                \
15927                            sizeof(vl_api_##n##_t), 1);
15928   foreach_vpe_api_reply_msg;
15929 #undef _
15930
15931   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
15932
15933   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15934
15935   vam->function_by_name = hash_create_string (0, sizeof (uword));
15936
15937   vam->help_by_name = hash_create_string (0, sizeof (uword));
15938
15939   /* API messages we can send */
15940 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15941   foreach_vpe_api_msg;
15942 #undef _
15943
15944   /* Help strings */
15945 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15946   foreach_vpe_api_msg;
15947 #undef _
15948
15949   /* CLI functions */
15950 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15951   foreach_cli_function;
15952 #undef _
15953
15954   /* Help strings */
15955 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15956   foreach_cli_function;
15957 #undef _
15958 }
15959
15960 #undef vl_api_version
15961 #define vl_api_version(n,v) static u32 vpe_api_version = v;
15962 #include <vpp-api/vpe.api.h>
15963 #undef vl_api_version
15964
15965 void
15966 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
15967 {
15968   /*
15969    * Send the main API signature in slot 0. This bit of code must
15970    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
15971    */
15972   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
15973 }
15974
15975 /*
15976  * fd.io coding-style-patch-verification: ON
15977  *
15978  * Local Variables:
15979  * eval: (c-set-style "gnu")
15980  * End:
15981  */