VPP-376: Refactor LISP dump API + VAT
[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
1319 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_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_l2_flags_reply_t_handler_json
1335   (vl_api_l2_flags_reply_t * mp)
1336 {
1337   vat_main_t *vam = &vat_main;
1338   vat_json_node_t node;
1339
1340   vat_json_init_object (&node);
1341   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1342   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1343                             ntohl (mp->resulting_feature_bitmap));
1344
1345   vat_json_print (vam->ofp, &node);
1346   vat_json_free (&node);
1347
1348   vam->retval = ntohl (mp->retval);
1349   vam->result_ready = 1;
1350 }
1351
1352 static void vl_api_bridge_flags_reply_t_handler
1353   (vl_api_bridge_flags_reply_t * mp)
1354 {
1355   vat_main_t *vam = &vat_main;
1356   i32 retval = ntohl (mp->retval);
1357   if (vam->async_mode)
1358     {
1359       vam->async_errors += (retval < 0);
1360     }
1361   else
1362     {
1363       vam->retval = retval;
1364       vam->result_ready = 1;
1365     }
1366 }
1367
1368 static void vl_api_bridge_flags_reply_t_handler_json
1369   (vl_api_bridge_flags_reply_t * mp)
1370 {
1371   vat_main_t *vam = &vat_main;
1372   vat_json_node_t node;
1373
1374   vat_json_init_object (&node);
1375   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1376   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1377                             ntohl (mp->resulting_feature_bitmap));
1378
1379   vat_json_print (vam->ofp, &node);
1380   vat_json_free (&node);
1381
1382   vam->retval = ntohl (mp->retval);
1383   vam->result_ready = 1;
1384 }
1385
1386 static void vl_api_tap_connect_reply_t_handler
1387   (vl_api_tap_connect_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   i32 retval = ntohl (mp->retval);
1391   if (vam->async_mode)
1392     {
1393       vam->async_errors += (retval < 0);
1394     }
1395   else
1396     {
1397       vam->retval = retval;
1398       vam->sw_if_index = ntohl (mp->sw_if_index);
1399       vam->result_ready = 1;
1400     }
1401
1402 }
1403
1404 static void vl_api_tap_connect_reply_t_handler_json
1405   (vl_api_tap_connect_reply_t * mp)
1406 {
1407   vat_main_t *vam = &vat_main;
1408   vat_json_node_t node;
1409
1410   vat_json_init_object (&node);
1411   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1412   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1413
1414   vat_json_print (vam->ofp, &node);
1415   vat_json_free (&node);
1416
1417   vam->retval = ntohl (mp->retval);
1418   vam->result_ready = 1;
1419
1420 }
1421
1422 static void
1423 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1424 {
1425   vat_main_t *vam = &vat_main;
1426   i32 retval = ntohl (mp->retval);
1427   if (vam->async_mode)
1428     {
1429       vam->async_errors += (retval < 0);
1430     }
1431   else
1432     {
1433       vam->retval = retval;
1434       vam->sw_if_index = ntohl (mp->sw_if_index);
1435       vam->result_ready = 1;
1436     }
1437 }
1438
1439 static void vl_api_tap_modify_reply_t_handler_json
1440   (vl_api_tap_modify_reply_t * mp)
1441 {
1442   vat_main_t *vam = &vat_main;
1443   vat_json_node_t node;
1444
1445   vat_json_init_object (&node);
1446   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1447   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1448
1449   vat_json_print (vam->ofp, &node);
1450   vat_json_free (&node);
1451
1452   vam->retval = ntohl (mp->retval);
1453   vam->result_ready = 1;
1454 }
1455
1456 static void
1457 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1458 {
1459   vat_main_t *vam = &vat_main;
1460   i32 retval = ntohl (mp->retval);
1461   if (vam->async_mode)
1462     {
1463       vam->async_errors += (retval < 0);
1464     }
1465   else
1466     {
1467       vam->retval = retval;
1468       vam->result_ready = 1;
1469     }
1470 }
1471
1472 static void vl_api_tap_delete_reply_t_handler_json
1473   (vl_api_tap_delete_reply_t * mp)
1474 {
1475   vat_main_t *vam = &vat_main;
1476   vat_json_node_t node;
1477
1478   vat_json_init_object (&node);
1479   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1480
1481   vat_json_print (vam->ofp, &node);
1482   vat_json_free (&node);
1483
1484   vam->retval = ntohl (mp->retval);
1485   vam->result_ready = 1;
1486 }
1487
1488 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1489   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1490 {
1491   vat_main_t *vam = &vat_main;
1492   i32 retval = ntohl (mp->retval);
1493   if (vam->async_mode)
1494     {
1495       vam->async_errors += (retval < 0);
1496     }
1497   else
1498     {
1499       vam->retval = retval;
1500       vam->result_ready = 1;
1501     }
1502 }
1503
1504 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1505   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1506 {
1507   vat_main_t *vam = &vat_main;
1508   vat_json_node_t node;
1509
1510   vat_json_init_object (&node);
1511   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1512   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1513                             ntohl (mp->tunnel_sw_if_index));
1514
1515   vat_json_print (vam->ofp, &node);
1516   vat_json_free (&node);
1517
1518   vam->retval = ntohl (mp->retval);
1519   vam->result_ready = 1;
1520 }
1521
1522 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1523   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1524 {
1525   vat_main_t *vam = &vat_main;
1526   i32 retval = ntohl (mp->retval);
1527   if (vam->async_mode)
1528     {
1529       vam->async_errors += (retval < 0);
1530     }
1531   else
1532     {
1533       vam->retval = retval;
1534       vam->sw_if_index = ntohl (mp->sw_if_index);
1535       vam->result_ready = 1;
1536     }
1537 }
1538
1539 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1540   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1541 {
1542   vat_main_t *vam = &vat_main;
1543   vat_json_node_t node;
1544
1545   vat_json_init_object (&node);
1546   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1547   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1548
1549   vat_json_print (vam->ofp, &node);
1550   vat_json_free (&node);
1551
1552   vam->retval = ntohl (mp->retval);
1553   vam->result_ready = 1;
1554 }
1555
1556
1557 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1558   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1559 {
1560   vat_main_t *vam = &vat_main;
1561   i32 retval = ntohl (mp->retval);
1562   if (vam->async_mode)
1563     {
1564       vam->async_errors += (retval < 0);
1565     }
1566   else
1567     {
1568       vam->retval = retval;
1569       vam->result_ready = 1;
1570     }
1571 }
1572
1573 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1574   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1575 {
1576   vat_main_t *vam = &vat_main;
1577   vat_json_node_t node;
1578
1579   vat_json_init_object (&node);
1580   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1581   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1582
1583   vat_json_print (vam->ofp, &node);
1584   vat_json_free (&node);
1585
1586   vam->retval = ntohl (mp->retval);
1587   vam->result_ready = 1;
1588 }
1589
1590 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1591   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1592 {
1593   vat_main_t *vam = &vat_main;
1594   i32 retval = ntohl (mp->retval);
1595   if (vam->async_mode)
1596     {
1597       vam->async_errors += (retval < 0);
1598     }
1599   else
1600     {
1601       vam->retval = retval;
1602       vam->sw_if_index = ntohl (mp->sw_if_index);
1603       vam->result_ready = 1;
1604     }
1605 }
1606
1607 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1608   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1609 {
1610   vat_main_t *vam = &vat_main;
1611   vat_json_node_t node;
1612
1613   vat_json_init_object (&node);
1614   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1615   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1616
1617   vat_json_print (vam->ofp, &node);
1618   vat_json_free (&node);
1619
1620   vam->retval = ntohl (mp->retval);
1621   vam->result_ready = 1;
1622 }
1623
1624 static void vl_api_gre_add_del_tunnel_reply_t_handler
1625   (vl_api_gre_add_del_tunnel_reply_t * mp)
1626 {
1627   vat_main_t *vam = &vat_main;
1628   i32 retval = ntohl (mp->retval);
1629   if (vam->async_mode)
1630     {
1631       vam->async_errors += (retval < 0);
1632     }
1633   else
1634     {
1635       vam->retval = retval;
1636       vam->sw_if_index = ntohl (mp->sw_if_index);
1637       vam->result_ready = 1;
1638     }
1639 }
1640
1641 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1642   (vl_api_gre_add_del_tunnel_reply_t * mp)
1643 {
1644   vat_main_t *vam = &vat_main;
1645   vat_json_node_t node;
1646
1647   vat_json_init_object (&node);
1648   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1649   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1650
1651   vat_json_print (vam->ofp, &node);
1652   vat_json_free (&node);
1653
1654   vam->retval = ntohl (mp->retval);
1655   vam->result_ready = 1;
1656 }
1657
1658 static void vl_api_create_vhost_user_if_reply_t_handler
1659   (vl_api_create_vhost_user_if_reply_t * mp)
1660 {
1661   vat_main_t *vam = &vat_main;
1662   i32 retval = ntohl (mp->retval);
1663   if (vam->async_mode)
1664     {
1665       vam->async_errors += (retval < 0);
1666     }
1667   else
1668     {
1669       vam->retval = retval;
1670       vam->sw_if_index = ntohl (mp->sw_if_index);
1671       vam->result_ready = 1;
1672     }
1673 }
1674
1675 static void vl_api_create_vhost_user_if_reply_t_handler_json
1676   (vl_api_create_vhost_user_if_reply_t * mp)
1677 {
1678   vat_main_t *vam = &vat_main;
1679   vat_json_node_t node;
1680
1681   vat_json_init_object (&node);
1682   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1683   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1684
1685   vat_json_print (vam->ofp, &node);
1686   vat_json_free (&node);
1687
1688   vam->retval = ntohl (mp->retval);
1689   vam->result_ready = 1;
1690 }
1691
1692 static void vl_api_ip_address_details_t_handler
1693   (vl_api_ip_address_details_t * mp)
1694 {
1695   vat_main_t *vam = &vat_main;
1696   static ip_address_details_t empty_ip_address_details = { {0} };
1697   ip_address_details_t *address = NULL;
1698   ip_details_t *current_ip_details = NULL;
1699   ip_details_t *details = NULL;
1700
1701   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1702
1703   if (!details || vam->current_sw_if_index >= vec_len (details)
1704       || !details[vam->current_sw_if_index].present)
1705     {
1706       errmsg ("ip address details arrived but not stored\n");
1707       errmsg ("ip_dump should be called first\n");
1708       return;
1709     }
1710
1711   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1712
1713 #define addresses (current_ip_details->addr)
1714
1715   vec_validate_init_empty (addresses, vec_len (addresses),
1716                            empty_ip_address_details);
1717
1718   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1719
1720   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1721   address->prefix_length = mp->prefix_length;
1722 #undef addresses
1723 }
1724
1725 static void vl_api_ip_address_details_t_handler_json
1726   (vl_api_ip_address_details_t * mp)
1727 {
1728   vat_main_t *vam = &vat_main;
1729   vat_json_node_t *node = NULL;
1730   struct in6_addr ip6;
1731   struct in_addr ip4;
1732
1733   if (VAT_JSON_ARRAY != vam->json_tree.type)
1734     {
1735       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1736       vat_json_init_array (&vam->json_tree);
1737     }
1738   node = vat_json_array_add (&vam->json_tree);
1739
1740   vat_json_init_object (node);
1741   if (vam->is_ipv6)
1742     {
1743       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1744       vat_json_object_add_ip6 (node, "ip", ip6);
1745     }
1746   else
1747     {
1748       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1749       vat_json_object_add_ip4 (node, "ip", ip4);
1750     }
1751   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1752 }
1753
1754 static void
1755 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1756 {
1757   vat_main_t *vam = &vat_main;
1758   static ip_details_t empty_ip_details = { 0 };
1759   ip_details_t *ip = NULL;
1760   u32 sw_if_index = ~0;
1761
1762   sw_if_index = ntohl (mp->sw_if_index);
1763
1764   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1765                            sw_if_index, empty_ip_details);
1766
1767   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1768                          sw_if_index);
1769
1770   ip->present = 1;
1771 }
1772
1773 static void
1774 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1775 {
1776   vat_main_t *vam = &vat_main;
1777
1778   if (VAT_JSON_ARRAY != vam->json_tree.type)
1779     {
1780       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1781       vat_json_init_array (&vam->json_tree);
1782     }
1783   vat_json_array_add_uint (&vam->json_tree,
1784                            clib_net_to_host_u32 (mp->sw_if_index));
1785 }
1786
1787 static void vl_api_map_domain_details_t_handler_json
1788   (vl_api_map_domain_details_t * mp)
1789 {
1790   vat_json_node_t *node = NULL;
1791   vat_main_t *vam = &vat_main;
1792   struct in6_addr ip6;
1793   struct in_addr ip4;
1794
1795   if (VAT_JSON_ARRAY != vam->json_tree.type)
1796     {
1797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1798       vat_json_init_array (&vam->json_tree);
1799     }
1800
1801   node = vat_json_array_add (&vam->json_tree);
1802   vat_json_init_object (node);
1803
1804   vat_json_object_add_uint (node, "domain_index",
1805                             clib_net_to_host_u32 (mp->domain_index));
1806   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1807   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1808   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1809   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1810   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1811   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1812   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1813   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1814   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1815   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1816   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1817   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1818   vat_json_object_add_uint (node, "flags", mp->flags);
1819   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1820   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1821 }
1822
1823 static void vl_api_map_domain_details_t_handler
1824   (vl_api_map_domain_details_t * mp)
1825 {
1826   vat_main_t *vam = &vat_main;
1827
1828   if (mp->is_translation)
1829     {
1830       fformat (vam->ofp,
1831                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1832                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1833                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1834                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1835                clib_net_to_host_u32 (mp->domain_index));
1836     }
1837   else
1838     {
1839       fformat (vam->ofp,
1840                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1841                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1842                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1843                format_ip6_address, mp->ip6_src,
1844                clib_net_to_host_u32 (mp->domain_index));
1845     }
1846   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1847            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1848            mp->is_translation ? "map-t" : "");
1849 }
1850
1851 static void vl_api_map_rule_details_t_handler_json
1852   (vl_api_map_rule_details_t * mp)
1853 {
1854   struct in6_addr ip6;
1855   vat_json_node_t *node = NULL;
1856   vat_main_t *vam = &vat_main;
1857
1858   if (VAT_JSON_ARRAY != vam->json_tree.type)
1859     {
1860       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1861       vat_json_init_array (&vam->json_tree);
1862     }
1863
1864   node = vat_json_array_add (&vam->json_tree);
1865   vat_json_init_object (node);
1866
1867   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1868   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1869   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1870 }
1871
1872 static void
1873 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1874 {
1875   vat_main_t *vam = &vat_main;
1876   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1877            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1878 }
1879
1880 static void
1881 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1882 {
1883   vat_main_t *vam = &vat_main;
1884   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1885           "router_addr %U host_mac %U\n",
1886           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1887           format_ip4_address, &mp->host_address,
1888           format_ip4_address, &mp->router_address,
1889           format_ethernet_address, mp->host_mac);
1890 }
1891
1892 static void vl_api_dhcp_compl_event_t_handler_json
1893   (vl_api_dhcp_compl_event_t * mp)
1894 {
1895   /* JSON output not supported */
1896 }
1897
1898 static void
1899 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1900                               u32 counter)
1901 {
1902   vat_main_t *vam = &vat_main;
1903   static u64 default_counter = 0;
1904
1905   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1906                            NULL);
1907   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1908                            sw_if_index, default_counter);
1909   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1910 }
1911
1912 static void
1913 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1914                                 interface_counter_t counter)
1915 {
1916   vat_main_t *vam = &vat_main;
1917   static interface_counter_t default_counter = { 0, };
1918
1919   vec_validate_init_empty (vam->combined_interface_counters,
1920                            vnet_counter_type, NULL);
1921   vec_validate_init_empty (vam->combined_interface_counters
1922                            [vnet_counter_type], sw_if_index, default_counter);
1923   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1924 }
1925
1926 static void vl_api_vnet_interface_counters_t_handler
1927   (vl_api_vnet_interface_counters_t * mp)
1928 {
1929   /* not supported */
1930 }
1931
1932 static void vl_api_vnet_interface_counters_t_handler_json
1933   (vl_api_vnet_interface_counters_t * mp)
1934 {
1935   interface_counter_t counter;
1936   vlib_counter_t *v;
1937   u64 *v_packets;
1938   u64 packets;
1939   u32 count;
1940   u32 first_sw_if_index;
1941   int i;
1942
1943   count = ntohl (mp->count);
1944   first_sw_if_index = ntohl (mp->first_sw_if_index);
1945
1946   if (!mp->is_combined)
1947     {
1948       v_packets = (u64 *) & mp->data;
1949       for (i = 0; i < count; i++)
1950         {
1951           packets =
1952             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1953           set_simple_interface_counter (mp->vnet_counter_type,
1954                                         first_sw_if_index + i, packets);
1955           v_packets++;
1956         }
1957     }
1958   else
1959     {
1960       v = (vlib_counter_t *) & mp->data;
1961       for (i = 0; i < count; i++)
1962         {
1963           counter.packets =
1964             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1965           counter.bytes =
1966             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1967           set_combined_interface_counter (mp->vnet_counter_type,
1968                                           first_sw_if_index + i, counter);
1969           v++;
1970         }
1971     }
1972 }
1973
1974 static u32
1975 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1976 {
1977   vat_main_t *vam = &vat_main;
1978   u32 i;
1979
1980   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1981     {
1982       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1983         {
1984           return i;
1985         }
1986     }
1987   return ~0;
1988 }
1989
1990 static u32
1991 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1992 {
1993   vat_main_t *vam = &vat_main;
1994   u32 i;
1995
1996   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1997     {
1998       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1999         {
2000           return i;
2001         }
2002     }
2003   return ~0;
2004 }
2005
2006 static void vl_api_vnet_ip4_fib_counters_t_handler
2007   (vl_api_vnet_ip4_fib_counters_t * mp)
2008 {
2009   /* not supported */
2010 }
2011
2012 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2013   (vl_api_vnet_ip4_fib_counters_t * mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016   vl_api_ip4_fib_counter_t *v;
2017   ip4_fib_counter_t *counter;
2018   struct in_addr ip4;
2019   u32 vrf_id;
2020   u32 vrf_index;
2021   u32 count;
2022   int i;
2023
2024   vrf_id = ntohl (mp->vrf_id);
2025   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2026   if (~0 == vrf_index)
2027     {
2028       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2029       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2030       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2031       vec_validate (vam->ip4_fib_counters, vrf_index);
2032       vam->ip4_fib_counters[vrf_index] = NULL;
2033     }
2034
2035   vec_free (vam->ip4_fib_counters[vrf_index]);
2036   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2037   count = ntohl (mp->count);
2038   for (i = 0; i < count; i++)
2039     {
2040       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2041       counter = &vam->ip4_fib_counters[vrf_index][i];
2042       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2043       counter->address = ip4;
2044       counter->address_length = v->address_length;
2045       counter->packets = clib_net_to_host_u64 (v->packets);
2046       counter->bytes = clib_net_to_host_u64 (v->bytes);
2047       v++;
2048     }
2049 }
2050
2051 static void vl_api_vnet_ip6_fib_counters_t_handler
2052   (vl_api_vnet_ip6_fib_counters_t * mp)
2053 {
2054   /* not supported */
2055 }
2056
2057 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2058   (vl_api_vnet_ip6_fib_counters_t * mp)
2059 {
2060   vat_main_t *vam = &vat_main;
2061   vl_api_ip6_fib_counter_t *v;
2062   ip6_fib_counter_t *counter;
2063   struct in6_addr ip6;
2064   u32 vrf_id;
2065   u32 vrf_index;
2066   u32 count;
2067   int i;
2068
2069   vrf_id = ntohl (mp->vrf_id);
2070   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2071   if (~0 == vrf_index)
2072     {
2073       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2074       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2075       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2076       vec_validate (vam->ip6_fib_counters, vrf_index);
2077       vam->ip6_fib_counters[vrf_index] = NULL;
2078     }
2079
2080   vec_free (vam->ip6_fib_counters[vrf_index]);
2081   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2082   count = ntohl (mp->count);
2083   for (i = 0; i < count; i++)
2084     {
2085       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2086       counter = &vam->ip6_fib_counters[vrf_index][i];
2087       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2088       counter->address = ip6;
2089       counter->address_length = v->address_length;
2090       counter->packets = clib_net_to_host_u64 (v->packets);
2091       counter->bytes = clib_net_to_host_u64 (v->bytes);
2092       v++;
2093     }
2094 }
2095
2096 static void vl_api_get_first_msg_id_reply_t_handler
2097   (vl_api_get_first_msg_id_reply_t * mp)
2098 {
2099   vat_main_t *vam = &vat_main;
2100   i32 retval = ntohl (mp->retval);
2101
2102   if (vam->async_mode)
2103     {
2104       vam->async_errors += (retval < 0);
2105     }
2106   else
2107     {
2108       vam->retval = retval;
2109       vam->result_ready = 1;
2110     }
2111   if (retval >= 0)
2112     {
2113       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2114     }
2115 }
2116
2117 static void vl_api_get_first_msg_id_reply_t_handler_json
2118   (vl_api_get_first_msg_id_reply_t * mp)
2119 {
2120   vat_main_t *vam = &vat_main;
2121   vat_json_node_t node;
2122
2123   vat_json_init_object (&node);
2124   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2125   vat_json_object_add_uint (&node, "first_msg_id",
2126                             (uint) ntohs (mp->first_msg_id));
2127
2128   vat_json_print (vam->ofp, &node);
2129   vat_json_free (&node);
2130
2131   vam->retval = ntohl (mp->retval);
2132   vam->result_ready = 1;
2133 }
2134
2135 static void vl_api_get_node_graph_reply_t_handler
2136   (vl_api_get_node_graph_reply_t * mp)
2137 {
2138   vat_main_t *vam = &vat_main;
2139   api_main_t *am = &api_main;
2140   i32 retval = ntohl (mp->retval);
2141   u8 *pvt_copy, *reply;
2142   void *oldheap;
2143   vlib_node_t *node;
2144   int i;
2145
2146   if (vam->async_mode)
2147     {
2148       vam->async_errors += (retval < 0);
2149     }
2150   else
2151     {
2152       vam->retval = retval;
2153       vam->result_ready = 1;
2154     }
2155
2156   /* "Should never happen..." */
2157   if (retval != 0)
2158     return;
2159
2160   reply = (u8 *) (mp->reply_in_shmem);
2161   pvt_copy = vec_dup (reply);
2162
2163   /* Toss the shared-memory original... */
2164   pthread_mutex_lock (&am->vlib_rp->mutex);
2165   oldheap = svm_push_data_heap (am->vlib_rp);
2166
2167   vec_free (reply);
2168
2169   svm_pop_heap (oldheap);
2170   pthread_mutex_unlock (&am->vlib_rp->mutex);
2171
2172   if (vam->graph_nodes)
2173     {
2174       hash_free (vam->graph_node_index_by_name);
2175
2176       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2177         {
2178           node = vam->graph_nodes[i];
2179           vec_free (node->name);
2180           vec_free (node->next_nodes);
2181           vec_free (node);
2182         }
2183       vec_free (vam->graph_nodes);
2184     }
2185
2186   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2187   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2188   vec_free (pvt_copy);
2189
2190   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2191     {
2192       node = vam->graph_nodes[i];
2193       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2194     }
2195 }
2196
2197 static void vl_api_get_node_graph_reply_t_handler_json
2198   (vl_api_get_node_graph_reply_t * mp)
2199 {
2200   vat_main_t *vam = &vat_main;
2201   api_main_t *am = &api_main;
2202   void *oldheap;
2203   vat_json_node_t node;
2204   u8 *reply;
2205
2206   /* $$$$ make this real? */
2207   vat_json_init_object (&node);
2208   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2209   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2210
2211   reply = (u8 *) (mp->reply_in_shmem);
2212
2213   /* Toss the shared-memory original... */
2214   pthread_mutex_lock (&am->vlib_rp->mutex);
2215   oldheap = svm_push_data_heap (am->vlib_rp);
2216
2217   vec_free (reply);
2218
2219   svm_pop_heap (oldheap);
2220   pthread_mutex_unlock (&am->vlib_rp->mutex);
2221
2222   vat_json_print (vam->ofp, &node);
2223   vat_json_free (&node);
2224
2225   vam->retval = ntohl (mp->retval);
2226   vam->result_ready = 1;
2227 }
2228
2229 static void
2230 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2231 {
2232   vat_main_t *vam = &vat_main;
2233   u8 *s = 0;
2234
2235   if (mp->local)
2236     {
2237       s = format (s, "%=16d%=16d%=16d\n",
2238                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2239     }
2240   else
2241     {
2242       s = format (s, "%=16U%=16d%=16d\n",
2243                   mp->is_ipv6 ? format_ip6_address :
2244                   format_ip4_address,
2245                   mp->ip_address, mp->priority, mp->weight);
2246     }
2247
2248   fformat (vam->ofp, "%v", s);
2249   vec_free (s);
2250 }
2251
2252 static void
2253 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2254                                             mp)
2255 {
2256   vat_main_t *vam = &vat_main;
2257   vat_json_node_t *node = NULL;
2258   struct in6_addr ip6;
2259   struct in_addr ip4;
2260
2261   if (VAT_JSON_ARRAY != vam->json_tree.type)
2262     {
2263       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2264       vat_json_init_array (&vam->json_tree);
2265     }
2266   node = vat_json_array_add (&vam->json_tree);
2267   vat_json_init_object (node);
2268
2269   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2270   vat_json_object_add_uint (node, "priority", mp->priority);
2271   vat_json_object_add_uint (node, "weight", mp->weight);
2272
2273   if (mp->local)
2274     vat_json_object_add_uint (node, "sw_if_index",
2275                               clib_net_to_host_u32 (mp->sw_if_index));
2276   else
2277     {
2278       if (mp->is_ipv6)
2279         {
2280           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2281           vat_json_object_add_ip6 (node, "address", ip6);
2282         }
2283       else
2284         {
2285           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2286           vat_json_object_add_ip4 (node, "address", ip4);
2287         }
2288     }
2289 }
2290
2291 static void
2292 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2293                                            mp)
2294 {
2295   vat_main_t *vam = &vat_main;
2296   u8 *ls_name = 0;
2297
2298   ls_name = format (0, "%s", mp->ls_name);
2299
2300   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2301            ls_name);
2302   vec_free (ls_name);
2303 }
2304
2305 static void
2306   vl_api_lisp_locator_set_details_t_handler_json
2307   (vl_api_lisp_locator_set_details_t * mp)
2308 {
2309   vat_main_t *vam = &vat_main;
2310   vat_json_node_t *node = 0;
2311   u8 *ls_name = 0;
2312
2313   ls_name = format (0, "%s", mp->ls_name);
2314   vec_add1 (ls_name, 0);
2315
2316   if (VAT_JSON_ARRAY != vam->json_tree.type)
2317     {
2318       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2319       vat_json_init_array (&vam->json_tree);
2320     }
2321   node = vat_json_array_add (&vam->json_tree);
2322
2323   vat_json_init_object (node);
2324   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2325   vat_json_object_add_uint (node, "ls_index",
2326                             clib_net_to_host_u32 (mp->ls_index));
2327   vec_free (ls_name);
2328 }
2329
2330 static u8 *
2331 format_lisp_flat_eid (u8 * s, va_list * args)
2332 {
2333   u32 type = va_arg (*args, u32);
2334   u8 *eid = va_arg (*args, u8 *);
2335   u32 eid_len = va_arg (*args, u32);
2336
2337   switch (type)
2338     {
2339     case 0:
2340       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2341     case 1:
2342       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2343     case 2:
2344       return format (s, "%U", format_ethernet_address, eid);
2345     }
2346   return 0;
2347 }
2348
2349 static u8 *
2350 format_lisp_eid_vat (u8 * s, va_list * args)
2351 {
2352   u32 type = va_arg (*args, u32);
2353   u8 *eid = va_arg (*args, u8 *);
2354   u32 eid_len = va_arg (*args, u32);
2355   u8 *seid = va_arg (*args, u8 *);
2356   u32 seid_len = va_arg (*args, u32);
2357   u32 is_src_dst = va_arg (*args, u32);
2358
2359   if (is_src_dst)
2360     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2361
2362   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2363
2364   return s;
2365 }
2366
2367 static void
2368 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2369 {
2370   vat_main_t *vam = &vat_main;
2371   u8 *s = 0, *eid = 0;
2372
2373   if (~0 == mp->locator_set_index)
2374     s = format (0, "action: %d", mp->action);
2375   else
2376     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2377
2378   eid = format (0, "%U", format_lisp_eid_vat,
2379                 mp->eid_type,
2380                 mp->eid,
2381                 mp->eid_prefix_len,
2382                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2383   vec_add1 (eid, 0);
2384
2385   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2386            clib_net_to_host_u32 (mp->vni),
2387            eid,
2388            mp->is_local ? "local" : "remote",
2389            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2390   vec_free (s);
2391   vec_free (eid);
2392 }
2393
2394 static void
2395 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2396                                               * mp)
2397 {
2398   vat_main_t *vam = &vat_main;
2399   vat_json_node_t *node = 0;
2400   u8 *eid = 0;
2401
2402   if (VAT_JSON_ARRAY != vam->json_tree.type)
2403     {
2404       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2405       vat_json_init_array (&vam->json_tree);
2406     }
2407   node = vat_json_array_add (&vam->json_tree);
2408
2409   vat_json_init_object (node);
2410   if (~0 == mp->locator_set_index)
2411     vat_json_object_add_uint (node, "action", mp->action);
2412   else
2413     vat_json_object_add_uint (node, "locator_set_index",
2414                               clib_net_to_host_u32 (mp->locator_set_index));
2415
2416   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2417   eid = format (0, "%U", format_lisp_eid_vat,
2418                 mp->eid_type,
2419                 mp->eid,
2420                 mp->eid_prefix_len,
2421                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2422   vec_add1 (eid, 0);
2423   vat_json_object_add_string_copy (node, "eid", eid);
2424   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2425   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2426   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2427   vec_free (eid);
2428 }
2429
2430 static void
2431   vl_api_lisp_eid_table_map_details_t_handler
2432   (vl_api_lisp_eid_table_map_details_t * mp)
2433 {
2434   vat_main_t *vam = &vat_main;
2435
2436   u8 *line = format (0, "%=10d%=10d",
2437                      clib_net_to_host_u32 (mp->vni),
2438                      clib_net_to_host_u32 (mp->dp_table));
2439   fformat (vam->ofp, "%v\n", line);
2440   vec_free (line);
2441 }
2442
2443 static void
2444   vl_api_lisp_eid_table_map_details_t_handler_json
2445   (vl_api_lisp_eid_table_map_details_t * mp)
2446 {
2447   vat_main_t *vam = &vat_main;
2448   vat_json_node_t *node = NULL;
2449
2450   if (VAT_JSON_ARRAY != vam->json_tree.type)
2451     {
2452       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2453       vat_json_init_array (&vam->json_tree);
2454     }
2455   node = vat_json_array_add (&vam->json_tree);
2456   vat_json_init_object (node);
2457   vat_json_object_add_uint (node, "dp_table",
2458                             clib_net_to_host_u32 (mp->dp_table));
2459   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2460 }
2461
2462 static void
2463   vl_api_lisp_eid_table_vni_details_t_handler
2464   (vl_api_lisp_eid_table_vni_details_t * mp)
2465 {
2466   vat_main_t *vam = &vat_main;
2467
2468   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2469   fformat (vam->ofp, "%v\n", line);
2470   vec_free (line);
2471 }
2472
2473 static void
2474   vl_api_lisp_eid_table_vni_details_t_handler_json
2475   (vl_api_lisp_eid_table_vni_details_t * mp)
2476 {
2477   vat_main_t *vam = &vat_main;
2478   vat_json_node_t *node = NULL;
2479
2480   if (VAT_JSON_ARRAY != vam->json_tree.type)
2481     {
2482       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2483       vat_json_init_array (&vam->json_tree);
2484     }
2485   node = vat_json_array_add (&vam->json_tree);
2486   vat_json_init_object (node);
2487   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2488 }
2489
2490 static u8 *
2491 format_decap_next (u8 * s, va_list * args)
2492 {
2493   u32 next_index = va_arg (*args, u32);
2494
2495   switch (next_index)
2496     {
2497     case LISP_GPE_INPUT_NEXT_DROP:
2498       return format (s, "drop");
2499     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2500       return format (s, "ip4");
2501     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2502       return format (s, "ip6");
2503     default:
2504       return format (s, "unknown %d", next_index);
2505     }
2506   return s;
2507 }
2508
2509 static void
2510 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2511                                           mp)
2512 {
2513   vat_main_t *vam = &vat_main;
2514   u8 *iid_str;
2515   u8 *flag_str = NULL;
2516
2517   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2518
2519 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2520   foreach_lisp_gpe_flag_bit;
2521 #undef _
2522
2523   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2524            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2525            mp->tunnels,
2526            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2527            mp->source_ip,
2528            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2529            mp->destination_ip,
2530            ntohl (mp->encap_fib_id),
2531            ntohl (mp->decap_fib_id),
2532            format_decap_next, ntohl (mp->dcap_next),
2533            mp->ver_res >> 6,
2534            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2535
2536   vec_free (iid_str);
2537 }
2538
2539 static void
2540   vl_api_lisp_gpe_tunnel_details_t_handler_json
2541   (vl_api_lisp_gpe_tunnel_details_t * mp)
2542 {
2543   vat_main_t *vam = &vat_main;
2544   vat_json_node_t *node = NULL;
2545   struct in6_addr ip6;
2546   struct in_addr ip4;
2547   u8 *next_decap_str;
2548
2549   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2550
2551   if (VAT_JSON_ARRAY != vam->json_tree.type)
2552     {
2553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2554       vat_json_init_array (&vam->json_tree);
2555     }
2556   node = vat_json_array_add (&vam->json_tree);
2557
2558   vat_json_init_object (node);
2559   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2560   if (mp->is_ipv6)
2561     {
2562       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2563       vat_json_object_add_ip6 (node, "source address", ip6);
2564       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2565       vat_json_object_add_ip6 (node, "destination address", ip6);
2566     }
2567   else
2568     {
2569       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2570       vat_json_object_add_ip4 (node, "source address", ip4);
2571       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2572       vat_json_object_add_ip4 (node, "destination address", ip4);
2573     }
2574   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2575   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2576   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2577   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2578   vat_json_object_add_uint (node, "flags", mp->flags);
2579   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2580   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2581   vat_json_object_add_uint (node, "res", mp->res);
2582   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2583
2584   vec_free (next_decap_str);
2585 }
2586
2587 static void
2588 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2589                                             * mp)
2590 {
2591   vat_main_t *vam = &vat_main;
2592
2593   fformat (vam->ofp, "%=20U\n",
2594            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2595            mp->ip_address);
2596 }
2597
2598 static void
2599   vl_api_lisp_map_resolver_details_t_handler_json
2600   (vl_api_lisp_map_resolver_details_t * mp)
2601 {
2602   vat_main_t *vam = &vat_main;
2603   vat_json_node_t *node = NULL;
2604   struct in6_addr ip6;
2605   struct in_addr ip4;
2606
2607   if (VAT_JSON_ARRAY != vam->json_tree.type)
2608     {
2609       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2610       vat_json_init_array (&vam->json_tree);
2611     }
2612   node = vat_json_array_add (&vam->json_tree);
2613
2614   vat_json_init_object (node);
2615   if (mp->is_ipv6)
2616     {
2617       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2618       vat_json_object_add_ip6 (node, "map resolver", ip6);
2619     }
2620   else
2621     {
2622       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2623       vat_json_object_add_ip4 (node, "map resolver", ip4);
2624     }
2625 }
2626
2627 static void
2628   vl_api_show_lisp_status_reply_t_handler
2629   (vl_api_show_lisp_status_reply_t * mp)
2630 {
2631   vat_main_t *vam = &vat_main;
2632   i32 retval = ntohl (mp->retval);
2633
2634   if (0 <= retval)
2635     {
2636       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2637                mp->feature_status ? "enabled" : "disabled",
2638                mp->gpe_status ? "enabled" : "disabled");
2639     }
2640
2641   vam->retval = retval;
2642   vam->result_ready = 1;
2643 }
2644
2645 static void
2646   vl_api_show_lisp_status_reply_t_handler_json
2647   (vl_api_show_lisp_status_reply_t * mp)
2648 {
2649   vat_main_t *vam = &vat_main;
2650   vat_json_node_t node;
2651   u8 *gpe_status = NULL;
2652   u8 *feature_status = NULL;
2653
2654   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2655   feature_status = format (0, "%s",
2656                            mp->feature_status ? "enabled" : "disabled");
2657   vec_add1 (gpe_status, 0);
2658   vec_add1 (feature_status, 0);
2659
2660   vat_json_init_object (&node);
2661   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2662   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2663
2664   vec_free (gpe_status);
2665   vec_free (feature_status);
2666
2667   vat_json_print (vam->ofp, &node);
2668   vat_json_free (&node);
2669
2670   vam->retval = ntohl (mp->retval);
2671   vam->result_ready = 1;
2672 }
2673
2674 static void
2675   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2676   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2677 {
2678   vat_main_t *vam = &vat_main;
2679   i32 retval = ntohl (mp->retval);
2680
2681   if (retval >= 0)
2682     {
2683       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2684     }
2685
2686   vam->retval = retval;
2687   vam->result_ready = 1;
2688 }
2689
2690 static void
2691   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2692   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2693 {
2694   vat_main_t *vam = &vat_main;
2695   vat_json_node_t *node = NULL;
2696
2697   if (VAT_JSON_ARRAY != vam->json_tree.type)
2698     {
2699       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2700       vat_json_init_array (&vam->json_tree);
2701     }
2702   node = vat_json_array_add (&vam->json_tree);
2703
2704   vat_json_init_object (node);
2705   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2706
2707   vat_json_print (vam->ofp, node);
2708   vat_json_free (node);
2709
2710   vam->retval = ntohl (mp->retval);
2711   vam->result_ready = 1;
2712 }
2713
2714 static void
2715 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2716 {
2717   vat_main_t *vam = &vat_main;
2718   i32 retval = ntohl (mp->retval);
2719
2720   if (0 <= retval)
2721     {
2722       fformat (vam->ofp, "%-20s%-16s\n",
2723                mp->status ? "enabled" : "disabled",
2724                mp->status ? (char *) mp->locator_set_name : "");
2725     }
2726
2727   vam->retval = retval;
2728   vam->result_ready = 1;
2729 }
2730
2731 static void
2732 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2733                                             mp)
2734 {
2735   vat_main_t *vam = &vat_main;
2736   vat_json_node_t node;
2737   u8 *status = 0;
2738
2739   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2740   vec_add1 (status, 0);
2741
2742   vat_json_init_object (&node);
2743   vat_json_object_add_string_copy (&node, "status", status);
2744   if (mp->status)
2745     {
2746       vat_json_object_add_string_copy (&node, "locator_set",
2747                                        mp->locator_set_name);
2748     }
2749
2750   vec_free (status);
2751
2752   vat_json_print (vam->ofp, &node);
2753   vat_json_free (&node);
2754
2755   vam->retval = ntohl (mp->retval);
2756   vam->result_ready = 1;
2757 }
2758
2759 static u8 *
2760 format_policer_type (u8 * s, va_list * va)
2761 {
2762   u32 i = va_arg (*va, u32);
2763
2764   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2765     s = format (s, "1r2c");
2766   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2767     s = format (s, "1r3c");
2768   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2769     s = format (s, "2r3c-2698");
2770   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2771     s = format (s, "2r3c-4115");
2772   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2773     s = format (s, "2r3c-mef5cf1");
2774   else
2775     s = format (s, "ILLEGAL");
2776   return s;
2777 }
2778
2779 static u8 *
2780 format_policer_rate_type (u8 * s, va_list * va)
2781 {
2782   u32 i = va_arg (*va, u32);
2783
2784   if (i == SSE2_QOS_RATE_KBPS)
2785     s = format (s, "kbps");
2786   else if (i == SSE2_QOS_RATE_PPS)
2787     s = format (s, "pps");
2788   else
2789     s = format (s, "ILLEGAL");
2790   return s;
2791 }
2792
2793 static u8 *
2794 format_policer_round_type (u8 * s, va_list * va)
2795 {
2796   u32 i = va_arg (*va, u32);
2797
2798   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2799     s = format (s, "closest");
2800   else if (i == SSE2_QOS_ROUND_TO_UP)
2801     s = format (s, "up");
2802   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2803     s = format (s, "down");
2804   else
2805     s = format (s, "ILLEGAL");
2806   return s;
2807 }
2808
2809 static u8 *
2810 format_policer_action_type (u8 * s, va_list * va)
2811 {
2812   u32 i = va_arg (*va, u32);
2813
2814   if (i == SSE2_QOS_ACTION_DROP)
2815     s = format (s, "drop");
2816   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2817     s = format (s, "transmit");
2818   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2819     s = format (s, "mark-and-transmit");
2820   else
2821     s = format (s, "ILLEGAL");
2822   return s;
2823 }
2824
2825 static u8 *
2826 format_dscp (u8 * s, va_list * va)
2827 {
2828   u32 i = va_arg (*va, u32);
2829   char *t = 0;
2830
2831   switch (i)
2832     {
2833 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2834       foreach_vnet_dscp
2835 #undef _
2836     default:
2837       return format (s, "ILLEGAL");
2838     }
2839   s = format (s, "%s", t);
2840   return s;
2841 }
2842
2843 static void
2844 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2845 {
2846   vat_main_t *vam = &vat_main;
2847   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2848
2849   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2850     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2851   else
2852     conform_dscp_str = format (0, "");
2853
2854   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2855     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2856   else
2857     exceed_dscp_str = format (0, "");
2858
2859   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2860     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2861   else
2862     violate_dscp_str = format (0, "");
2863
2864   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2865            "rate type %U, round type %U, %s rate, %s color-aware, "
2866            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2867            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2868            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2869            mp->name,
2870            format_policer_type, mp->type,
2871            ntohl (mp->cir),
2872            ntohl (mp->eir),
2873            clib_net_to_host_u64 (mp->cb),
2874            clib_net_to_host_u64 (mp->eb),
2875            format_policer_rate_type, mp->rate_type,
2876            format_policer_round_type, mp->round_type,
2877            mp->single_rate ? "single" : "dual",
2878            mp->color_aware ? "is" : "not",
2879            ntohl (mp->cir_tokens_per_period),
2880            ntohl (mp->pir_tokens_per_period),
2881            ntohl (mp->scale),
2882            ntohl (mp->current_limit),
2883            ntohl (mp->current_bucket),
2884            ntohl (mp->extended_limit),
2885            ntohl (mp->extended_bucket),
2886            clib_net_to_host_u64 (mp->last_update_time),
2887            format_policer_action_type, mp->conform_action_type,
2888            conform_dscp_str,
2889            format_policer_action_type, mp->exceed_action_type,
2890            exceed_dscp_str,
2891            format_policer_action_type, mp->violate_action_type,
2892            violate_dscp_str);
2893
2894   vec_free (conform_dscp_str);
2895   vec_free (exceed_dscp_str);
2896   vec_free (violate_dscp_str);
2897 }
2898
2899 static void vl_api_policer_details_t_handler_json
2900   (vl_api_policer_details_t * mp)
2901 {
2902   vat_main_t *vam = &vat_main;
2903   vat_json_node_t *node;
2904   u8 *rate_type_str, *round_type_str, *type_str;
2905   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2906
2907   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2908   round_type_str =
2909     format (0, "%U", format_policer_round_type, mp->round_type);
2910   type_str = format (0, "%U", format_policer_type, mp->type);
2911   conform_action_str = format (0, "%U", format_policer_action_type,
2912                                mp->conform_action_type);
2913   exceed_action_str = format (0, "%U", format_policer_action_type,
2914                               mp->exceed_action_type);
2915   violate_action_str = format (0, "%U", format_policer_action_type,
2916                                mp->violate_action_type);
2917
2918   if (VAT_JSON_ARRAY != vam->json_tree.type)
2919     {
2920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2921       vat_json_init_array (&vam->json_tree);
2922     }
2923   node = vat_json_array_add (&vam->json_tree);
2924
2925   vat_json_init_object (node);
2926   vat_json_object_add_string_copy (node, "name", mp->name);
2927   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2928   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2929   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
2930   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
2931   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2932   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2933   vat_json_object_add_string_copy (node, "type", type_str);
2934   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2935   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2936   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2937   vat_json_object_add_uint (node, "cir_tokens_per_period",
2938                             ntohl (mp->cir_tokens_per_period));
2939   vat_json_object_add_uint (node, "eir_tokens_per_period",
2940                             ntohl (mp->pir_tokens_per_period));
2941   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2942   vat_json_object_add_uint (node, "current_bucket",
2943                             ntohl (mp->current_bucket));
2944   vat_json_object_add_uint (node, "extended_limit",
2945                             ntohl (mp->extended_limit));
2946   vat_json_object_add_uint (node, "extended_bucket",
2947                             ntohl (mp->extended_bucket));
2948   vat_json_object_add_uint (node, "last_update_time",
2949                             ntohl (mp->last_update_time));
2950   vat_json_object_add_string_copy (node, "conform_action",
2951                                    conform_action_str);
2952   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2953     {
2954       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2955       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2956       vec_free (dscp_str);
2957     }
2958   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
2959   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2960     {
2961       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2962       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2963       vec_free (dscp_str);
2964     }
2965   vat_json_object_add_string_copy (node, "violate_action",
2966                                    violate_action_str);
2967   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2968     {
2969       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2970       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2971       vec_free (dscp_str);
2972     }
2973
2974   vec_free (rate_type_str);
2975   vec_free (round_type_str);
2976   vec_free (type_str);
2977   vec_free (conform_action_str);
2978   vec_free (exceed_action_str);
2979   vec_free (violate_action_str);
2980 }
2981
2982 static void
2983 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2984                                            mp)
2985 {
2986   vat_main_t *vam = &vat_main;
2987   int i, count = ntohl (mp->count);
2988
2989   if (count > 0)
2990     fformat (vam->ofp, "classify table ids (%d) : ", count);
2991   for (i = 0; i < count; i++)
2992     {
2993       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
2994       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
2995     }
2996   vam->retval = ntohl (mp->retval);
2997   vam->result_ready = 1;
2998 }
2999
3000 static void
3001   vl_api_classify_table_ids_reply_t_handler_json
3002   (vl_api_classify_table_ids_reply_t * mp)
3003 {
3004   vat_main_t *vam = &vat_main;
3005   int i, count = ntohl (mp->count);
3006
3007   if (count > 0)
3008     {
3009       vat_json_node_t node;
3010
3011       vat_json_init_object (&node);
3012       for (i = 0; i < count; i++)
3013         {
3014           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3015         }
3016       vat_json_print (vam->ofp, &node);
3017       vat_json_free (&node);
3018     }
3019   vam->retval = ntohl (mp->retval);
3020   vam->result_ready = 1;
3021 }
3022
3023 static void
3024   vl_api_classify_table_by_interface_reply_t_handler
3025   (vl_api_classify_table_by_interface_reply_t * mp)
3026 {
3027   vat_main_t *vam = &vat_main;
3028   u32 table_id;
3029
3030   table_id = ntohl (mp->l2_table_id);
3031   if (table_id != ~0)
3032     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3033   else
3034     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3035   table_id = ntohl (mp->ip4_table_id);
3036   if (table_id != ~0)
3037     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3038   else
3039     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3040   table_id = ntohl (mp->ip6_table_id);
3041   if (table_id != ~0)
3042     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3043   else
3044     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3045   vam->retval = ntohl (mp->retval);
3046   vam->result_ready = 1;
3047 }
3048
3049 static void
3050   vl_api_classify_table_by_interface_reply_t_handler_json
3051   (vl_api_classify_table_by_interface_reply_t * mp)
3052 {
3053   vat_main_t *vam = &vat_main;
3054   vat_json_node_t node;
3055
3056   vat_json_init_object (&node);
3057
3058   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3059   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3060   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3061
3062   vat_json_print (vam->ofp, &node);
3063   vat_json_free (&node);
3064
3065   vam->retval = ntohl (mp->retval);
3066   vam->result_ready = 1;
3067 }
3068
3069 static void vl_api_policer_add_del_reply_t_handler
3070   (vl_api_policer_add_del_reply_t * mp)
3071 {
3072   vat_main_t *vam = &vat_main;
3073   i32 retval = ntohl (mp->retval);
3074   if (vam->async_mode)
3075     {
3076       vam->async_errors += (retval < 0);
3077     }
3078   else
3079     {
3080       vam->retval = retval;
3081       vam->result_ready = 1;
3082       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3083         /*
3084          * Note: this is just barely thread-safe, depends on
3085          * the main thread spinning waiting for an answer...
3086          */
3087         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3088     }
3089 }
3090
3091 static void vl_api_policer_add_del_reply_t_handler_json
3092   (vl_api_policer_add_del_reply_t * mp)
3093 {
3094   vat_main_t *vam = &vat_main;
3095   vat_json_node_t node;
3096
3097   vat_json_init_object (&node);
3098   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3099   vat_json_object_add_uint (&node, "policer_index",
3100                             ntohl (mp->policer_index));
3101
3102   vat_json_print (vam->ofp, &node);
3103   vat_json_free (&node);
3104
3105   vam->retval = ntohl (mp->retval);
3106   vam->result_ready = 1;
3107 }
3108
3109 /* Format hex dump. */
3110 u8 *
3111 format_hex_bytes (u8 * s, va_list * va)
3112 {
3113   u8 *bytes = va_arg (*va, u8 *);
3114   int n_bytes = va_arg (*va, int);
3115   uword i;
3116
3117   /* Print short or long form depending on byte count. */
3118   uword short_form = n_bytes <= 32;
3119   uword indent = format_get_indent (s);
3120
3121   if (n_bytes == 0)
3122     return s;
3123
3124   for (i = 0; i < n_bytes; i++)
3125     {
3126       if (!short_form && (i % 32) == 0)
3127         s = format (s, "%08x: ", i);
3128       s = format (s, "%02x", bytes[i]);
3129       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3130         s = format (s, "\n%U", format_white_space, indent);
3131     }
3132
3133   return s;
3134 }
3135
3136 static void
3137 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3138                                             * mp)
3139 {
3140   vat_main_t *vam = &vat_main;
3141   i32 retval = ntohl (mp->retval);
3142   if (retval == 0)
3143     {
3144       fformat (vam->ofp, "classify table info :\n");
3145       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3146                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3147                ntohl (mp->miss_next_index));
3148       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3149                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3150                ntohl (mp->match_n_vectors));
3151       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3152                ntohl (mp->mask_length));
3153     }
3154   vam->retval = retval;
3155   vam->result_ready = 1;
3156 }
3157
3158 static void
3159   vl_api_classify_table_info_reply_t_handler_json
3160   (vl_api_classify_table_info_reply_t * mp)
3161 {
3162   vat_main_t *vam = &vat_main;
3163   vat_json_node_t node;
3164
3165   i32 retval = ntohl (mp->retval);
3166   if (retval == 0)
3167     {
3168       vat_json_init_object (&node);
3169
3170       vat_json_object_add_int (&node, "sessions",
3171                                ntohl (mp->active_sessions));
3172       vat_json_object_add_int (&node, "nexttbl",
3173                                ntohl (mp->next_table_index));
3174       vat_json_object_add_int (&node, "nextnode",
3175                                ntohl (mp->miss_next_index));
3176       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3177       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3178       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3179       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3180                       ntohl (mp->mask_length), 0);
3181       vat_json_object_add_string_copy (&node, "mask", s);
3182
3183       vat_json_print (vam->ofp, &node);
3184       vat_json_free (&node);
3185     }
3186   vam->retval = ntohl (mp->retval);
3187   vam->result_ready = 1;
3188 }
3189
3190 static void
3191 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3192                                            mp)
3193 {
3194   vat_main_t *vam = &vat_main;
3195
3196   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3197            ntohl (mp->hit_next_index), ntohl (mp->advance),
3198            ntohl (mp->opaque_index));
3199   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3200            ntohl (mp->match_length));
3201 }
3202
3203 static void
3204   vl_api_classify_session_details_t_handler_json
3205   (vl_api_classify_session_details_t * mp)
3206 {
3207   vat_main_t *vam = &vat_main;
3208   vat_json_node_t *node = NULL;
3209
3210   if (VAT_JSON_ARRAY != vam->json_tree.type)
3211     {
3212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3213       vat_json_init_array (&vam->json_tree);
3214     }
3215   node = vat_json_array_add (&vam->json_tree);
3216
3217   vat_json_init_object (node);
3218   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3219   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3220   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3221   u8 *s =
3222     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3223             0);
3224   vat_json_object_add_string_copy (node, "match", s);
3225 }
3226
3227 static void vl_api_pg_create_interface_reply_t_handler
3228   (vl_api_pg_create_interface_reply_t * mp)
3229 {
3230   vat_main_t *vam = &vat_main;
3231
3232   vam->retval = ntohl (mp->retval);
3233   vam->result_ready = 1;
3234 }
3235
3236 static void vl_api_pg_create_interface_reply_t_handler_json
3237   (vl_api_pg_create_interface_reply_t * mp)
3238 {
3239   vat_main_t *vam = &vat_main;
3240   vat_json_node_t node;
3241
3242   i32 retval = ntohl (mp->retval);
3243   if (retval == 0)
3244     {
3245       vat_json_init_object (&node);
3246
3247       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3248
3249       vat_json_print (vam->ofp, &node);
3250       vat_json_free (&node);
3251     }
3252   vam->retval = ntohl (mp->retval);
3253   vam->result_ready = 1;
3254 }
3255
3256 static void vl_api_policer_classify_details_t_handler
3257   (vl_api_policer_classify_details_t * mp)
3258 {
3259   vat_main_t *vam = &vat_main;
3260
3261   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3262            ntohl (mp->table_index));
3263 }
3264
3265 static void vl_api_policer_classify_details_t_handler_json
3266   (vl_api_policer_classify_details_t * mp)
3267 {
3268   vat_main_t *vam = &vat_main;
3269   vat_json_node_t *node;
3270
3271   if (VAT_JSON_ARRAY != vam->json_tree.type)
3272     {
3273       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3274       vat_json_init_array (&vam->json_tree);
3275     }
3276   node = vat_json_array_add (&vam->json_tree);
3277
3278   vat_json_init_object (node);
3279   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3280   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3281 }
3282
3283 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3284   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3285 {
3286   vat_main_t *vam = &vat_main;
3287   i32 retval = ntohl (mp->retval);
3288   if (vam->async_mode)
3289     {
3290       vam->async_errors += (retval < 0);
3291     }
3292   else
3293     {
3294       vam->retval = retval;
3295       vam->sw_if_index = ntohl (mp->sw_if_index);
3296       vam->result_ready = 1;
3297     }
3298 }
3299
3300 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3301   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3302 {
3303   vat_main_t *vam = &vat_main;
3304   vat_json_node_t node;
3305
3306   vat_json_init_object (&node);
3307   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3308   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3309
3310   vat_json_print (vam->ofp, &node);
3311   vat_json_free (&node);
3312
3313   vam->retval = ntohl (mp->retval);
3314   vam->result_ready = 1;
3315 }
3316
3317 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3318 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3319 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3320 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3321
3322 /*
3323  * Generate boilerplate reply handlers, which
3324  * dig the return value out of the xxx_reply_t API message,
3325  * stick it into vam->retval, and set vam->result_ready
3326  *
3327  * Could also do this by pointing N message decode slots at
3328  * a single function, but that could break in subtle ways.
3329  */
3330
3331 #define foreach_standard_reply_retval_handler           \
3332 _(sw_interface_set_flags_reply)                         \
3333 _(sw_interface_add_del_address_reply)                   \
3334 _(sw_interface_set_table_reply)                         \
3335 _(sw_interface_set_vpath_reply)                         \
3336 _(sw_interface_set_l2_bridge_reply)                     \
3337 _(bridge_domain_add_del_reply)                          \
3338 _(sw_interface_set_l2_xconnect_reply)                   \
3339 _(l2fib_add_del_reply)                                  \
3340 _(ip_add_del_route_reply)                               \
3341 _(proxy_arp_add_del_reply)                              \
3342 _(proxy_arp_intfc_enable_disable_reply)                 \
3343 _(mpls_add_del_encap_reply)                             \
3344 _(mpls_add_del_decap_reply)                             \
3345 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3346 _(sw_interface_set_unnumbered_reply)                    \
3347 _(ip_neighbor_add_del_reply)                            \
3348 _(reset_vrf_reply)                                      \
3349 _(oam_add_del_reply)                                    \
3350 _(reset_fib_reply)                                      \
3351 _(dhcp_proxy_config_reply)                              \
3352 _(dhcp_proxy_config_2_reply)                            \
3353 _(dhcp_proxy_set_vss_reply)                             \
3354 _(dhcp_client_config_reply)                             \
3355 _(set_ip_flow_hash_reply)                               \
3356 _(sw_interface_ip6_enable_disable_reply)                \
3357 _(sw_interface_ip6_set_link_local_address_reply)        \
3358 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3359 _(sw_interface_ip6nd_ra_config_reply)                   \
3360 _(set_arp_neighbor_limit_reply)                         \
3361 _(l2_patch_add_del_reply)                               \
3362 _(sr_tunnel_add_del_reply)                              \
3363 _(sr_policy_add_del_reply)                              \
3364 _(sr_multicast_map_add_del_reply)                       \
3365 _(classify_add_del_session_reply)                       \
3366 _(classify_set_interface_ip_table_reply)                \
3367 _(classify_set_interface_l2_tables_reply)               \
3368 _(l2tpv3_set_tunnel_cookies_reply)                      \
3369 _(l2tpv3_interface_enable_disable_reply)                \
3370 _(l2tpv3_set_lookup_key_reply)                          \
3371 _(l2_fib_clear_table_reply)                             \
3372 _(l2_interface_efp_filter_reply)                        \
3373 _(l2_interface_vlan_tag_rewrite_reply)                  \
3374 _(modify_vhost_user_if_reply)                           \
3375 _(delete_vhost_user_if_reply)                           \
3376 _(want_ip4_arp_events_reply)                            \
3377 _(want_ip6_nd_events_reply)                             \
3378 _(input_acl_set_interface_reply)                        \
3379 _(ipsec_spd_add_del_reply)                              \
3380 _(ipsec_interface_add_del_spd_reply)                    \
3381 _(ipsec_spd_add_del_entry_reply)                        \
3382 _(ipsec_sad_add_del_entry_reply)                        \
3383 _(ipsec_sa_set_key_reply)                               \
3384 _(ikev2_profile_add_del_reply)                          \
3385 _(ikev2_profile_set_auth_reply)                         \
3386 _(ikev2_profile_set_id_reply)                           \
3387 _(ikev2_profile_set_ts_reply)                           \
3388 _(ikev2_set_local_key_reply)                            \
3389 _(delete_loopback_reply)                                \
3390 _(bd_ip_mac_add_del_reply)                              \
3391 _(map_del_domain_reply)                                 \
3392 _(map_add_del_rule_reply)                               \
3393 _(want_interface_events_reply)                          \
3394 _(want_stats_reply)                                     \
3395 _(cop_interface_enable_disable_reply)                   \
3396 _(cop_whitelist_enable_disable_reply)                   \
3397 _(sw_interface_clear_stats_reply)                       \
3398 _(ioam_enable_reply)                              \
3399 _(ioam_disable_reply)                              \
3400 _(lisp_add_del_locator_reply)                           \
3401 _(lisp_add_del_local_eid_reply)                         \
3402 _(lisp_add_del_remote_mapping_reply)                    \
3403 _(lisp_add_del_adjacency_reply)                         \
3404 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3405 _(lisp_add_del_map_resolver_reply)                      \
3406 _(lisp_gpe_enable_disable_reply)                        \
3407 _(lisp_gpe_add_del_iface_reply)                         \
3408 _(lisp_enable_disable_reply)                            \
3409 _(lisp_pitr_set_locator_set_reply)                      \
3410 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3411 _(lisp_eid_table_add_del_map_reply)                     \
3412 _(vxlan_gpe_add_del_tunnel_reply)                       \
3413 _(af_packet_delete_reply)                               \
3414 _(policer_classify_set_interface_reply)                 \
3415 _(netmap_create_reply)                                  \
3416 _(netmap_delete_reply)                                  \
3417 _(set_ipfix_exporter_reply)                             \
3418 _(set_ipfix_classify_stream_reply)                      \
3419 _(ipfix_classify_table_add_del_reply)                   \
3420 _(pg_capture_reply)                                     \
3421 _(pg_enable_disable_reply)                              \
3422 _(ip_source_and_port_range_check_add_del_reply)         \
3423 _(ip_source_and_port_range_check_interface_add_del_reply)\
3424 _(delete_subif_reply)
3425
3426 #define _(n)                                    \
3427     static void vl_api_##n##_t_handler          \
3428     (vl_api_##n##_t * mp)                       \
3429     {                                           \
3430         vat_main_t * vam = &vat_main;           \
3431         i32 retval = ntohl(mp->retval);         \
3432         if (vam->async_mode) {                  \
3433             vam->async_errors += (retval < 0);  \
3434         } else {                                \
3435             vam->retval = retval;               \
3436             vam->result_ready = 1;              \
3437         }                                       \
3438     }
3439 foreach_standard_reply_retval_handler;
3440 #undef _
3441
3442 #define _(n)                                    \
3443     static void vl_api_##n##_t_handler_json     \
3444     (vl_api_##n##_t * mp)                       \
3445     {                                           \
3446         vat_main_t * vam = &vat_main;           \
3447         vat_json_node_t node;                   \
3448         vat_json_init_object(&node);            \
3449         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3450         vat_json_print(vam->ofp, &node);        \
3451         vam->retval = ntohl(mp->retval);        \
3452         vam->result_ready = 1;                  \
3453     }
3454 foreach_standard_reply_retval_handler;
3455 #undef _
3456
3457 /*
3458  * Table of message reply handlers, must include boilerplate handlers
3459  * we just generated
3460  */
3461
3462 #define foreach_vpe_api_reply_msg                                       \
3463 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3464 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3465 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3466 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3467 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3468 _(CLI_REPLY, cli_reply)                                                 \
3469 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3470 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3471   sw_interface_add_del_address_reply)                                   \
3472 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3473 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3474 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3475   sw_interface_set_l2_xconnect_reply)                                   \
3476 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3477   sw_interface_set_l2_bridge_reply)                                     \
3478 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3479 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3480 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3481 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3482 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3483 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3484 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3485 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3486 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3487 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3488 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3489 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3490 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3491   proxy_arp_intfc_enable_disable_reply)                                 \
3492 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3493 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3494 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3495 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3496   mpls_ethernet_add_del_tunnel_reply)                                   \
3497 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3498   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3499 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3500   sw_interface_set_unnumbered_reply)                                    \
3501 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3502 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3503 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3504 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3505 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3506 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3507 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3508 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3509 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3510 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3511 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3512 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3513   sw_interface_ip6_enable_disable_reply)                                \
3514 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3515   sw_interface_ip6_set_link_local_address_reply)                        \
3516 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3517   sw_interface_ip6nd_ra_prefix_reply)                                   \
3518 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3519   sw_interface_ip6nd_ra_config_reply)                                   \
3520 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3521 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3522 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3523 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3524 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3525 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3526 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3527 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3528 classify_set_interface_ip_table_reply)                                  \
3529 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3530   classify_set_interface_l2_tables_reply)                               \
3531 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3532 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3533 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3534 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3535 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3536   l2tpv3_interface_enable_disable_reply)                                \
3537 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3538 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3539 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3540 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3541 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3542 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3543 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3544 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3545 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3546 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3547 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3548 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3549 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3550 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3551 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3552 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3553 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3554 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3555 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3556 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3557 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3558 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3559 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3560 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3561 _(IP_DETAILS, ip_details)                                               \
3562 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3563 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3564 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3565 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3566 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3567 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3568 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3569 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3570 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3571 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3572 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3573 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3574 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3575 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3576 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3577 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3578 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3579 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3580 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3581 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3582 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3583 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3584 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3585 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3586 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3587 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3588 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3589 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3590 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3591 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3592 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3593 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3594 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3595 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3596 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3597 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3598 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3599 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3600 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3601 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3602 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3603 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3604 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3605 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3606 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3607 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3608 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3609 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3610 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3611 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3612 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3613   lisp_add_del_map_request_itr_rlocs_reply)                             \
3614 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3615   lisp_get_map_request_itr_rlocs_reply)                                 \
3616 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3617 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3618 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3619 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3620 _(POLICER_DETAILS, policer_details)                                     \
3621 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3622 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3623 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3624 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3625 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3626 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3627 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3628 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3629 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3630 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3631 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3632 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3633 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3634 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3635 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3636 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3637 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3638 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3639 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3640 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3641 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3642 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3643 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3644  ip_source_and_port_range_check_add_del_reply)                          \
3645 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3646  ip_source_and_port_range_check_interface_add_del_reply)                \
3647 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3648 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3649 _(DELETE_SUBIF_REPLY, delete_subif_reply)
3650
3651 /* M: construct, but don't yet send a message */
3652
3653 #define M(T,t)                                  \
3654 do {                                            \
3655     vam->result_ready = 0;                      \
3656     mp = vl_msg_api_alloc(sizeof(*mp));         \
3657     memset (mp, 0, sizeof (*mp));               \
3658     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3659     mp->client_index = vam->my_client_index;    \
3660 } while(0);
3661
3662 #define M2(T,t,n)                               \
3663 do {                                            \
3664     vam->result_ready = 0;                      \
3665     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3666     memset (mp, 0, sizeof (*mp));               \
3667     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3668     mp->client_index = vam->my_client_index;    \
3669 } while(0);
3670
3671
3672 /* S: send a message */
3673 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3674
3675 /* W: wait for results, with timeout */
3676 #define W                                       \
3677 do {                                            \
3678     timeout = vat_time_now (vam) + 1.0;         \
3679                                                 \
3680     while (vat_time_now (vam) < timeout) {      \
3681         if (vam->result_ready == 1) {           \
3682             return (vam->retval);               \
3683         }                                       \
3684     }                                           \
3685     return -99;                                 \
3686 } while(0);
3687
3688 /* W2: wait for results, with timeout */
3689 #define W2(body)                                \
3690 do {                                            \
3691     timeout = vat_time_now (vam) + 1.0;         \
3692                                                 \
3693     while (vat_time_now (vam) < timeout) {      \
3694         if (vam->result_ready == 1) {           \
3695           (body);                               \
3696           return (vam->retval);                 \
3697         }                                       \
3698     }                                           \
3699     return -99;                                 \
3700 } while(0);
3701
3702 typedef struct
3703 {
3704   u8 *name;
3705   u32 value;
3706 } name_sort_t;
3707
3708
3709 #define STR_VTR_OP_CASE(op)     \
3710     case L2_VTR_ ## op:         \
3711         return "" # op;
3712
3713 static const char *
3714 str_vtr_op (u32 vtr_op)
3715 {
3716   switch (vtr_op)
3717     {
3718       STR_VTR_OP_CASE (DISABLED);
3719       STR_VTR_OP_CASE (PUSH_1);
3720       STR_VTR_OP_CASE (PUSH_2);
3721       STR_VTR_OP_CASE (POP_1);
3722       STR_VTR_OP_CASE (POP_2);
3723       STR_VTR_OP_CASE (TRANSLATE_1_1);
3724       STR_VTR_OP_CASE (TRANSLATE_1_2);
3725       STR_VTR_OP_CASE (TRANSLATE_2_1);
3726       STR_VTR_OP_CASE (TRANSLATE_2_2);
3727     }
3728
3729   return "UNKNOWN";
3730 }
3731
3732 static int
3733 dump_sub_interface_table (vat_main_t * vam)
3734 {
3735   const sw_interface_subif_t *sub = NULL;
3736
3737   if (vam->json_output)
3738     {
3739       clib_warning
3740         ("JSON output supported only for VPE API calls and dump_stats_table");
3741       return -99;
3742     }
3743
3744   fformat (vam->ofp,
3745            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3746            "Interface", "sw_if_index",
3747            "sub id", "dot1ad", "tags", "outer id",
3748            "inner id", "exact", "default", "outer any", "inner any");
3749
3750   vec_foreach (sub, vam->sw_if_subif_table)
3751   {
3752     fformat (vam->ofp,
3753              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3754              sub->interface_name,
3755              sub->sw_if_index,
3756              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3757              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3758              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3759              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3760     if (sub->vtr_op != L2_VTR_DISABLED)
3761       {
3762         fformat (vam->ofp,
3763                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3764                  "tag1: %d tag2: %d ]\n",
3765                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3766                  sub->vtr_tag1, sub->vtr_tag2);
3767       }
3768   }
3769
3770   return 0;
3771 }
3772
3773 static int
3774 name_sort_cmp (void *a1, void *a2)
3775 {
3776   name_sort_t *n1 = a1;
3777   name_sort_t *n2 = a2;
3778
3779   return strcmp ((char *) n1->name, (char *) n2->name);
3780 }
3781
3782 static int
3783 dump_interface_table (vat_main_t * vam)
3784 {
3785   hash_pair_t *p;
3786   name_sort_t *nses = 0, *ns;
3787
3788   if (vam->json_output)
3789     {
3790       clib_warning
3791         ("JSON output supported only for VPE API calls and dump_stats_table");
3792       return -99;
3793     }
3794
3795   /* *INDENT-OFF* */
3796   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3797   ({
3798     vec_add2 (nses, ns, 1);
3799     ns->name = (u8 *)(p->key);
3800     ns->value = (u32) p->value[0];
3801   }));
3802   /* *INDENT-ON* */
3803
3804   vec_sort_with_function (nses, name_sort_cmp);
3805
3806   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3807   vec_foreach (ns, nses)
3808   {
3809     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3810   }
3811   vec_free (nses);
3812   return 0;
3813 }
3814
3815 static int
3816 dump_ip_table (vat_main_t * vam, int is_ipv6)
3817 {
3818   const ip_details_t *det = NULL;
3819   const ip_address_details_t *address = NULL;
3820   u32 i = ~0;
3821
3822   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3823
3824   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3825   {
3826     i++;
3827     if (!det->present)
3828       {
3829         continue;
3830       }
3831     fformat (vam->ofp, "%-12d\n", i);
3832     fformat (vam->ofp,
3833              "            %-30s%-13s\n", "Address", "Prefix length");
3834     if (!det->addr)
3835       {
3836         continue;
3837       }
3838     vec_foreach (address, det->addr)
3839     {
3840       fformat (vam->ofp,
3841                "            %-30U%-13d\n",
3842                is_ipv6 ? format_ip6_address : format_ip4_address,
3843                address->ip, address->prefix_length);
3844     }
3845   }
3846
3847   return 0;
3848 }
3849
3850 static int
3851 dump_ipv4_table (vat_main_t * vam)
3852 {
3853   if (vam->json_output)
3854     {
3855       clib_warning
3856         ("JSON output supported only for VPE API calls and dump_stats_table");
3857       return -99;
3858     }
3859
3860   return dump_ip_table (vam, 0);
3861 }
3862
3863 static int
3864 dump_ipv6_table (vat_main_t * vam)
3865 {
3866   if (vam->json_output)
3867     {
3868       clib_warning
3869         ("JSON output supported only for VPE API calls and dump_stats_table");
3870       return -99;
3871     }
3872
3873   return dump_ip_table (vam, 1);
3874 }
3875
3876 static char *
3877 counter_type_to_str (u8 counter_type, u8 is_combined)
3878 {
3879   if (!is_combined)
3880     {
3881       switch (counter_type)
3882         {
3883         case VNET_INTERFACE_COUNTER_DROP:
3884           return "drop";
3885         case VNET_INTERFACE_COUNTER_PUNT:
3886           return "punt";
3887         case VNET_INTERFACE_COUNTER_IP4:
3888           return "ip4";
3889         case VNET_INTERFACE_COUNTER_IP6:
3890           return "ip6";
3891         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3892           return "rx-no-buf";
3893         case VNET_INTERFACE_COUNTER_RX_MISS:
3894           return "rx-miss";
3895         case VNET_INTERFACE_COUNTER_RX_ERROR:
3896           return "rx-error";
3897         case VNET_INTERFACE_COUNTER_TX_ERROR:
3898           return "tx-error";
3899         default:
3900           return "INVALID-COUNTER-TYPE";
3901         }
3902     }
3903   else
3904     {
3905       switch (counter_type)
3906         {
3907         case VNET_INTERFACE_COUNTER_RX:
3908           return "rx";
3909         case VNET_INTERFACE_COUNTER_TX:
3910           return "tx";
3911         default:
3912           return "INVALID-COUNTER-TYPE";
3913         }
3914     }
3915 }
3916
3917 static int
3918 dump_stats_table (vat_main_t * vam)
3919 {
3920   vat_json_node_t node;
3921   vat_json_node_t *msg_array;
3922   vat_json_node_t *msg;
3923   vat_json_node_t *counter_array;
3924   vat_json_node_t *counter;
3925   interface_counter_t c;
3926   u64 packets;
3927   ip4_fib_counter_t *c4;
3928   ip6_fib_counter_t *c6;
3929   int i, j;
3930
3931   if (!vam->json_output)
3932     {
3933       clib_warning ("dump_stats_table supported only in JSON format");
3934       return -99;
3935     }
3936
3937   vat_json_init_object (&node);
3938
3939   /* interface counters */
3940   msg_array = vat_json_object_add (&node, "interface_counters");
3941   vat_json_init_array (msg_array);
3942   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
3943     {
3944       msg = vat_json_array_add (msg_array);
3945       vat_json_init_object (msg);
3946       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3947                                        (u8 *) counter_type_to_str (i, 0));
3948       vat_json_object_add_int (msg, "is_combined", 0);
3949       counter_array = vat_json_object_add (msg, "data");
3950       vat_json_init_array (counter_array);
3951       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
3952         {
3953           packets = vam->simple_interface_counters[i][j];
3954           vat_json_array_add_uint (counter_array, packets);
3955         }
3956     }
3957   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
3958     {
3959       msg = vat_json_array_add (msg_array);
3960       vat_json_init_object (msg);
3961       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3962                                        (u8 *) counter_type_to_str (i, 1));
3963       vat_json_object_add_int (msg, "is_combined", 1);
3964       counter_array = vat_json_object_add (msg, "data");
3965       vat_json_init_array (counter_array);
3966       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
3967         {
3968           c = vam->combined_interface_counters[i][j];
3969           counter = vat_json_array_add (counter_array);
3970           vat_json_init_object (counter);
3971           vat_json_object_add_uint (counter, "packets", c.packets);
3972           vat_json_object_add_uint (counter, "bytes", c.bytes);
3973         }
3974     }
3975
3976   /* ip4 fib counters */
3977   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
3978   vat_json_init_array (msg_array);
3979   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
3980     {
3981       msg = vat_json_array_add (msg_array);
3982       vat_json_init_object (msg);
3983       vat_json_object_add_uint (msg, "vrf_id",
3984                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
3985       counter_array = vat_json_object_add (msg, "c");
3986       vat_json_init_array (counter_array);
3987       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
3988         {
3989           counter = vat_json_array_add (counter_array);
3990           vat_json_init_object (counter);
3991           c4 = &vam->ip4_fib_counters[i][j];
3992           vat_json_object_add_ip4 (counter, "address", c4->address);
3993           vat_json_object_add_uint (counter, "address_length",
3994                                     c4->address_length);
3995           vat_json_object_add_uint (counter, "packets", c4->packets);
3996           vat_json_object_add_uint (counter, "bytes", c4->bytes);
3997         }
3998     }
3999
4000   /* ip6 fib counters */
4001   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4002   vat_json_init_array (msg_array);
4003   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4004     {
4005       msg = vat_json_array_add (msg_array);
4006       vat_json_init_object (msg);
4007       vat_json_object_add_uint (msg, "vrf_id",
4008                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4009       counter_array = vat_json_object_add (msg, "c");
4010       vat_json_init_array (counter_array);
4011       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4012         {
4013           counter = vat_json_array_add (counter_array);
4014           vat_json_init_object (counter);
4015           c6 = &vam->ip6_fib_counters[i][j];
4016           vat_json_object_add_ip6 (counter, "address", c6->address);
4017           vat_json_object_add_uint (counter, "address_length",
4018                                     c6->address_length);
4019           vat_json_object_add_uint (counter, "packets", c6->packets);
4020           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4021         }
4022     }
4023
4024   vat_json_print (vam->ofp, &node);
4025   vat_json_free (&node);
4026
4027   return 0;
4028 }
4029
4030 int
4031 exec (vat_main_t * vam)
4032 {
4033   api_main_t *am = &api_main;
4034   vl_api_cli_request_t *mp;
4035   f64 timeout;
4036   void *oldheap;
4037   u8 *cmd = 0;
4038   unformat_input_t *i = vam->input;
4039
4040   if (vec_len (i->buffer) == 0)
4041     return -1;
4042
4043   if (vam->exec_mode == 0 && unformat (i, "mode"))
4044     {
4045       vam->exec_mode = 1;
4046       return 0;
4047     }
4048   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4049     {
4050       vam->exec_mode = 0;
4051       return 0;
4052     }
4053
4054
4055   M (CLI_REQUEST, cli_request);
4056
4057   /*
4058    * Copy cmd into shared memory.
4059    * In order for the CLI command to work, it
4060    * must be a vector ending in \n, not a C-string ending
4061    * in \n\0.
4062    */
4063   pthread_mutex_lock (&am->vlib_rp->mutex);
4064   oldheap = svm_push_data_heap (am->vlib_rp);
4065
4066   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4067   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4068
4069   svm_pop_heap (oldheap);
4070   pthread_mutex_unlock (&am->vlib_rp->mutex);
4071
4072   mp->cmd_in_shmem = (u64) cmd;
4073   S;
4074   timeout = vat_time_now (vam) + 10.0;
4075
4076   while (vat_time_now (vam) < timeout)
4077     {
4078       if (vam->result_ready == 1)
4079         {
4080           u8 *free_me;
4081           if (vam->shmem_result != NULL)
4082             fformat (vam->ofp, "%s", vam->shmem_result);
4083           pthread_mutex_lock (&am->vlib_rp->mutex);
4084           oldheap = svm_push_data_heap (am->vlib_rp);
4085
4086           free_me = (u8 *) vam->shmem_result;
4087           vec_free (free_me);
4088
4089           svm_pop_heap (oldheap);
4090           pthread_mutex_unlock (&am->vlib_rp->mutex);
4091           return 0;
4092         }
4093     }
4094   return -99;
4095 }
4096
4097 /*
4098  * Future replacement of exec() that passes CLI buffers directly in
4099  * the API messages instead of an additional shared memory area.
4100  */
4101 static int
4102 exec_inband (vat_main_t * vam)
4103 {
4104   vl_api_cli_inband_t *mp;
4105   f64 timeout;
4106   unformat_input_t *i = vam->input;
4107
4108   if (vec_len (i->buffer) == 0)
4109     return -1;
4110
4111   if (vam->exec_mode == 0 && unformat (i, "mode"))
4112     {
4113       vam->exec_mode = 1;
4114       return 0;
4115     }
4116   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4117     {
4118       vam->exec_mode = 0;
4119       return 0;
4120     }
4121
4122   /*
4123    * In order for the CLI command to work, it
4124    * must be a vector ending in \n, not a C-string ending
4125    * in \n\0.
4126    */
4127   u32 len = vec_len (vam->input->buffer);
4128   M2 (CLI_INBAND, cli_inband, len);
4129   clib_memcpy (mp->cmd, vam->input->buffer, len);
4130   mp->length = htonl (len);
4131
4132   S;
4133   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4134 }
4135
4136 static int
4137 api_create_loopback (vat_main_t * vam)
4138 {
4139   unformat_input_t *i = vam->input;
4140   vl_api_create_loopback_t *mp;
4141   f64 timeout;
4142   u8 mac_address[6];
4143   u8 mac_set = 0;
4144
4145   memset (mac_address, 0, sizeof (mac_address));
4146
4147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4148     {
4149       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4150         mac_set = 1;
4151       else
4152         break;
4153     }
4154
4155   /* Construct the API message */
4156   M (CREATE_LOOPBACK, create_loopback);
4157   if (mac_set)
4158     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4159
4160   S;
4161   W;
4162 }
4163
4164 static int
4165 api_delete_loopback (vat_main_t * vam)
4166 {
4167   unformat_input_t *i = vam->input;
4168   vl_api_delete_loopback_t *mp;
4169   f64 timeout;
4170   u32 sw_if_index = ~0;
4171
4172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4173     {
4174       if (unformat (i, "sw_if_index %d", &sw_if_index))
4175         ;
4176       else
4177         break;
4178     }
4179
4180   if (sw_if_index == ~0)
4181     {
4182       errmsg ("missing sw_if_index\n");
4183       return -99;
4184     }
4185
4186   /* Construct the API message */
4187   M (DELETE_LOOPBACK, delete_loopback);
4188   mp->sw_if_index = ntohl (sw_if_index);
4189
4190   S;
4191   W;
4192 }
4193
4194 static int
4195 api_want_stats (vat_main_t * vam)
4196 {
4197   unformat_input_t *i = vam->input;
4198   vl_api_want_stats_t *mp;
4199   f64 timeout;
4200   int enable = -1;
4201
4202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4203     {
4204       if (unformat (i, "enable"))
4205         enable = 1;
4206       else if (unformat (i, "disable"))
4207         enable = 0;
4208       else
4209         break;
4210     }
4211
4212   if (enable == -1)
4213     {
4214       errmsg ("missing enable|disable\n");
4215       return -99;
4216     }
4217
4218   M (WANT_STATS, want_stats);
4219   mp->enable_disable = enable;
4220
4221   S;
4222   W;
4223 }
4224
4225 static int
4226 api_want_interface_events (vat_main_t * vam)
4227 {
4228   unformat_input_t *i = vam->input;
4229   vl_api_want_interface_events_t *mp;
4230   f64 timeout;
4231   int enable = -1;
4232
4233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4234     {
4235       if (unformat (i, "enable"))
4236         enable = 1;
4237       else if (unformat (i, "disable"))
4238         enable = 0;
4239       else
4240         break;
4241     }
4242
4243   if (enable == -1)
4244     {
4245       errmsg ("missing enable|disable\n");
4246       return -99;
4247     }
4248
4249   M (WANT_INTERFACE_EVENTS, want_interface_events);
4250   mp->enable_disable = enable;
4251
4252   vam->interface_event_display = enable;
4253
4254   S;
4255   W;
4256 }
4257
4258
4259 /* Note: non-static, called once to set up the initial intfc table */
4260 int
4261 api_sw_interface_dump (vat_main_t * vam)
4262 {
4263   vl_api_sw_interface_dump_t *mp;
4264   f64 timeout;
4265   hash_pair_t *p;
4266   name_sort_t *nses = 0, *ns;
4267   sw_interface_subif_t *sub = NULL;
4268
4269   /* Toss the old name table */
4270   /* *INDENT-OFF* */
4271   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4272   ({
4273     vec_add2 (nses, ns, 1);
4274     ns->name = (u8 *)(p->key);
4275     ns->value = (u32) p->value[0];
4276   }));
4277   /* *INDENT-ON* */
4278
4279   hash_free (vam->sw_if_index_by_interface_name);
4280
4281   vec_foreach (ns, nses) vec_free (ns->name);
4282
4283   vec_free (nses);
4284
4285   vec_foreach (sub, vam->sw_if_subif_table)
4286   {
4287     vec_free (sub->interface_name);
4288   }
4289   vec_free (vam->sw_if_subif_table);
4290
4291   /* recreate the interface name hash table */
4292   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4293
4294   /* Get list of ethernets */
4295   M (SW_INTERFACE_DUMP, sw_interface_dump);
4296   mp->name_filter_valid = 1;
4297   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4298   S;
4299
4300   /* and local / loopback interfaces */
4301   M (SW_INTERFACE_DUMP, sw_interface_dump);
4302   mp->name_filter_valid = 1;
4303   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4304   S;
4305
4306
4307   /* and vxlan-gpe tunnel interfaces */
4308   M (SW_INTERFACE_DUMP, sw_interface_dump);
4309   mp->name_filter_valid = 1;
4310   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4311            sizeof (mp->name_filter) - 1);
4312   S;
4313
4314   /* and vxlan tunnel interfaces */
4315   M (SW_INTERFACE_DUMP, sw_interface_dump);
4316   mp->name_filter_valid = 1;
4317   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4318   S;
4319
4320   /* and host (af_packet) interfaces */
4321   M (SW_INTERFACE_DUMP, sw_interface_dump);
4322   mp->name_filter_valid = 1;
4323   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4324   S;
4325
4326   /* and l2tpv3 tunnel interfaces */
4327   M (SW_INTERFACE_DUMP, sw_interface_dump);
4328   mp->name_filter_valid = 1;
4329   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4330            sizeof (mp->name_filter) - 1);
4331   S;
4332
4333   /* and GRE tunnel interfaces */
4334   M (SW_INTERFACE_DUMP, sw_interface_dump);
4335   mp->name_filter_valid = 1;
4336   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4337   S;
4338
4339   /* and LISP-GPE interfaces */
4340   M (SW_INTERFACE_DUMP, sw_interface_dump);
4341   mp->name_filter_valid = 1;
4342   strncpy ((char *) mp->name_filter, "lisp_gpe",
4343            sizeof (mp->name_filter) - 1);
4344   S;
4345
4346   /* and IPSEC tunnel interfaces */
4347   M (SW_INTERFACE_DUMP, sw_interface_dump);
4348   mp->name_filter_valid = 1;
4349   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4350   S;
4351
4352   /* Use a control ping for synchronization */
4353   {
4354     vl_api_control_ping_t *mp;
4355     M (CONTROL_PING, control_ping);
4356     S;
4357   }
4358   W;
4359 }
4360
4361 static int
4362 api_sw_interface_set_flags (vat_main_t * vam)
4363 {
4364   unformat_input_t *i = vam->input;
4365   vl_api_sw_interface_set_flags_t *mp;
4366   f64 timeout;
4367   u32 sw_if_index;
4368   u8 sw_if_index_set = 0;
4369   u8 admin_up = 0, link_up = 0;
4370
4371   /* Parse args required to build the message */
4372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4373     {
4374       if (unformat (i, "admin-up"))
4375         admin_up = 1;
4376       else if (unformat (i, "admin-down"))
4377         admin_up = 0;
4378       else if (unformat (i, "link-up"))
4379         link_up = 1;
4380       else if (unformat (i, "link-down"))
4381         link_up = 0;
4382       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4383         sw_if_index_set = 1;
4384       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4385         sw_if_index_set = 1;
4386       else
4387         break;
4388     }
4389
4390   if (sw_if_index_set == 0)
4391     {
4392       errmsg ("missing interface name or sw_if_index\n");
4393       return -99;
4394     }
4395
4396   /* Construct the API message */
4397   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4398   mp->sw_if_index = ntohl (sw_if_index);
4399   mp->admin_up_down = admin_up;
4400   mp->link_up_down = link_up;
4401
4402   /* send it... */
4403   S;
4404
4405   /* Wait for a reply, return the good/bad news... */
4406   W;
4407 }
4408
4409 static int
4410 api_sw_interface_clear_stats (vat_main_t * vam)
4411 {
4412   unformat_input_t *i = vam->input;
4413   vl_api_sw_interface_clear_stats_t *mp;
4414   f64 timeout;
4415   u32 sw_if_index;
4416   u8 sw_if_index_set = 0;
4417
4418   /* Parse args required to build the message */
4419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4420     {
4421       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4422         sw_if_index_set = 1;
4423       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4424         sw_if_index_set = 1;
4425       else
4426         break;
4427     }
4428
4429   /* Construct the API message */
4430   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4431
4432   if (sw_if_index_set == 1)
4433     mp->sw_if_index = ntohl (sw_if_index);
4434   else
4435     mp->sw_if_index = ~0;
4436
4437   /* send it... */
4438   S;
4439
4440   /* Wait for a reply, return the good/bad news... */
4441   W;
4442 }
4443
4444 static int
4445 api_sw_interface_add_del_address (vat_main_t * vam)
4446 {
4447   unformat_input_t *i = vam->input;
4448   vl_api_sw_interface_add_del_address_t *mp;
4449   f64 timeout;
4450   u32 sw_if_index;
4451   u8 sw_if_index_set = 0;
4452   u8 is_add = 1, del_all = 0;
4453   u32 address_length = 0;
4454   u8 v4_address_set = 0;
4455   u8 v6_address_set = 0;
4456   ip4_address_t v4address;
4457   ip6_address_t v6address;
4458
4459   /* Parse args required to build the message */
4460   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4461     {
4462       if (unformat (i, "del-all"))
4463         del_all = 1;
4464       else if (unformat (i, "del"))
4465         is_add = 0;
4466       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4467         sw_if_index_set = 1;
4468       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4469         sw_if_index_set = 1;
4470       else if (unformat (i, "%U/%d",
4471                          unformat_ip4_address, &v4address, &address_length))
4472         v4_address_set = 1;
4473       else if (unformat (i, "%U/%d",
4474                          unformat_ip6_address, &v6address, &address_length))
4475         v6_address_set = 1;
4476       else
4477         break;
4478     }
4479
4480   if (sw_if_index_set == 0)
4481     {
4482       errmsg ("missing interface name or sw_if_index\n");
4483       return -99;
4484     }
4485   if (v4_address_set && v6_address_set)
4486     {
4487       errmsg ("both v4 and v6 addresses set\n");
4488       return -99;
4489     }
4490   if (!v4_address_set && !v6_address_set && !del_all)
4491     {
4492       errmsg ("no addresses set\n");
4493       return -99;
4494     }
4495
4496   /* Construct the API message */
4497   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4498
4499   mp->sw_if_index = ntohl (sw_if_index);
4500   mp->is_add = is_add;
4501   mp->del_all = del_all;
4502   if (v6_address_set)
4503     {
4504       mp->is_ipv6 = 1;
4505       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4506     }
4507   else
4508     {
4509       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4510     }
4511   mp->address_length = address_length;
4512
4513   /* send it... */
4514   S;
4515
4516   /* Wait for a reply, return good/bad news  */
4517   W;
4518 }
4519
4520 static int
4521 api_sw_interface_set_table (vat_main_t * vam)
4522 {
4523   unformat_input_t *i = vam->input;
4524   vl_api_sw_interface_set_table_t *mp;
4525   f64 timeout;
4526   u32 sw_if_index, vrf_id = 0;
4527   u8 sw_if_index_set = 0;
4528   u8 is_ipv6 = 0;
4529
4530   /* Parse args required to build the message */
4531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4532     {
4533       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4534         sw_if_index_set = 1;
4535       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4536         sw_if_index_set = 1;
4537       else if (unformat (i, "vrf %d", &vrf_id))
4538         ;
4539       else if (unformat (i, "ipv6"))
4540         is_ipv6 = 1;
4541       else
4542         break;
4543     }
4544
4545   if (sw_if_index_set == 0)
4546     {
4547       errmsg ("missing interface name or sw_if_index\n");
4548       return -99;
4549     }
4550
4551   /* Construct the API message */
4552   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4553
4554   mp->sw_if_index = ntohl (sw_if_index);
4555   mp->is_ipv6 = is_ipv6;
4556   mp->vrf_id = ntohl (vrf_id);
4557
4558   /* send it... */
4559   S;
4560
4561   /* Wait for a reply... */
4562   W;
4563 }
4564
4565 static int
4566 api_sw_interface_set_vpath (vat_main_t * vam)
4567 {
4568   unformat_input_t *i = vam->input;
4569   vl_api_sw_interface_set_vpath_t *mp;
4570   f64 timeout;
4571   u32 sw_if_index = 0;
4572   u8 sw_if_index_set = 0;
4573   u8 is_enable = 0;
4574
4575   /* Parse args required to build the message */
4576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4577     {
4578       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4579         sw_if_index_set = 1;
4580       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4581         sw_if_index_set = 1;
4582       else if (unformat (i, "enable"))
4583         is_enable = 1;
4584       else if (unformat (i, "disable"))
4585         is_enable = 0;
4586       else
4587         break;
4588     }
4589
4590   if (sw_if_index_set == 0)
4591     {
4592       errmsg ("missing interface name or sw_if_index\n");
4593       return -99;
4594     }
4595
4596   /* Construct the API message */
4597   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4598
4599   mp->sw_if_index = ntohl (sw_if_index);
4600   mp->enable = is_enable;
4601
4602   /* send it... */
4603   S;
4604
4605   /* Wait for a reply... */
4606   W;
4607 }
4608
4609 static int
4610 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4611 {
4612   unformat_input_t *i = vam->input;
4613   vl_api_sw_interface_set_l2_xconnect_t *mp;
4614   f64 timeout;
4615   u32 rx_sw_if_index;
4616   u8 rx_sw_if_index_set = 0;
4617   u32 tx_sw_if_index;
4618   u8 tx_sw_if_index_set = 0;
4619   u8 enable = 1;
4620
4621   /* Parse args required to build the message */
4622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4623     {
4624       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4625         rx_sw_if_index_set = 1;
4626       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4627         tx_sw_if_index_set = 1;
4628       else if (unformat (i, "rx"))
4629         {
4630           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4631             {
4632               if (unformat (i, "%U", unformat_sw_if_index, vam,
4633                             &rx_sw_if_index))
4634                 rx_sw_if_index_set = 1;
4635             }
4636           else
4637             break;
4638         }
4639       else if (unformat (i, "tx"))
4640         {
4641           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4642             {
4643               if (unformat (i, "%U", unformat_sw_if_index, vam,
4644                             &tx_sw_if_index))
4645                 tx_sw_if_index_set = 1;
4646             }
4647           else
4648             break;
4649         }
4650       else if (unformat (i, "enable"))
4651         enable = 1;
4652       else if (unformat (i, "disable"))
4653         enable = 0;
4654       else
4655         break;
4656     }
4657
4658   if (rx_sw_if_index_set == 0)
4659     {
4660       errmsg ("missing rx interface name or rx_sw_if_index\n");
4661       return -99;
4662     }
4663
4664   if (enable && (tx_sw_if_index_set == 0))
4665     {
4666       errmsg ("missing tx interface name or tx_sw_if_index\n");
4667       return -99;
4668     }
4669
4670   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4671
4672   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4673   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4674   mp->enable = enable;
4675
4676   S;
4677   W;
4678   /* NOTREACHED */
4679   return 0;
4680 }
4681
4682 static int
4683 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4684 {
4685   unformat_input_t *i = vam->input;
4686   vl_api_sw_interface_set_l2_bridge_t *mp;
4687   f64 timeout;
4688   u32 rx_sw_if_index;
4689   u8 rx_sw_if_index_set = 0;
4690   u32 bd_id;
4691   u8 bd_id_set = 0;
4692   u8 bvi = 0;
4693   u32 shg = 0;
4694   u8 enable = 1;
4695
4696   /* Parse args required to build the message */
4697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4698     {
4699       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4700         rx_sw_if_index_set = 1;
4701       else if (unformat (i, "bd_id %d", &bd_id))
4702         bd_id_set = 1;
4703       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
4704         rx_sw_if_index_set = 1;
4705       else if (unformat (i, "shg %d", &shg))
4706         ;
4707       else if (unformat (i, "bvi"))
4708         bvi = 1;
4709       else if (unformat (i, "enable"))
4710         enable = 1;
4711       else if (unformat (i, "disable"))
4712         enable = 0;
4713       else
4714         break;
4715     }
4716
4717   if (rx_sw_if_index_set == 0)
4718     {
4719       errmsg ("missing rx interface name or sw_if_index\n");
4720       return -99;
4721     }
4722
4723   if (enable && (bd_id_set == 0))
4724     {
4725       errmsg ("missing bridge domain\n");
4726       return -99;
4727     }
4728
4729   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
4730
4731   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4732   mp->bd_id = ntohl (bd_id);
4733   mp->shg = (u8) shg;
4734   mp->bvi = bvi;
4735   mp->enable = enable;
4736
4737   S;
4738   W;
4739   /* NOTREACHED */
4740   return 0;
4741 }
4742
4743 static int
4744 api_bridge_domain_dump (vat_main_t * vam)
4745 {
4746   unformat_input_t *i = vam->input;
4747   vl_api_bridge_domain_dump_t *mp;
4748   f64 timeout;
4749   u32 bd_id = ~0;
4750
4751   /* Parse args required to build the message */
4752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4753     {
4754       if (unformat (i, "bd_id %d", &bd_id))
4755         ;
4756       else
4757         break;
4758     }
4759
4760   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
4761   mp->bd_id = ntohl (bd_id);
4762   S;
4763
4764   /* Use a control ping for synchronization */
4765   {
4766     vl_api_control_ping_t *mp;
4767     M (CONTROL_PING, control_ping);
4768     S;
4769   }
4770
4771   W;
4772   /* NOTREACHED */
4773   return 0;
4774 }
4775
4776 static int
4777 api_bridge_domain_add_del (vat_main_t * vam)
4778 {
4779   unformat_input_t *i = vam->input;
4780   vl_api_bridge_domain_add_del_t *mp;
4781   f64 timeout;
4782   u32 bd_id = ~0;
4783   u8 is_add = 1;
4784   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4785
4786   /* Parse args required to build the message */
4787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4788     {
4789       if (unformat (i, "bd_id %d", &bd_id))
4790         ;
4791       else if (unformat (i, "flood %d", &flood))
4792         ;
4793       else if (unformat (i, "uu-flood %d", &uu_flood))
4794         ;
4795       else if (unformat (i, "forward %d", &forward))
4796         ;
4797       else if (unformat (i, "learn %d", &learn))
4798         ;
4799       else if (unformat (i, "arp-term %d", &arp_term))
4800         ;
4801       else if (unformat (i, "del"))
4802         {
4803           is_add = 0;
4804           flood = uu_flood = forward = learn = 0;
4805         }
4806       else
4807         break;
4808     }
4809
4810   if (bd_id == ~0)
4811     {
4812       errmsg ("missing bridge domain\n");
4813       return -99;
4814     }
4815
4816   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
4817
4818   mp->bd_id = ntohl (bd_id);
4819   mp->flood = flood;
4820   mp->uu_flood = uu_flood;
4821   mp->forward = forward;
4822   mp->learn = learn;
4823   mp->arp_term = arp_term;
4824   mp->is_add = is_add;
4825
4826   S;
4827   W;
4828   /* NOTREACHED */
4829   return 0;
4830 }
4831
4832 static int
4833 api_l2fib_add_del (vat_main_t * vam)
4834 {
4835   unformat_input_t *i = vam->input;
4836   vl_api_l2fib_add_del_t *mp;
4837   f64 timeout;
4838   u64 mac = 0;
4839   u8 mac_set = 0;
4840   u32 bd_id;
4841   u8 bd_id_set = 0;
4842   u32 sw_if_index;
4843   u8 sw_if_index_set = 0;
4844   u8 is_add = 1;
4845   u8 static_mac = 0;
4846   u8 filter_mac = 0;
4847   u8 bvi_mac = 0;
4848   int count = 1;
4849   f64 before = 0;
4850   int j;
4851
4852   /* Parse args required to build the message */
4853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4854     {
4855       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
4856         mac_set = 1;
4857       else if (unformat (i, "bd_id %d", &bd_id))
4858         bd_id_set = 1;
4859       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4860         sw_if_index_set = 1;
4861       else if (unformat (i, "sw_if"))
4862         {
4863           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4864             {
4865               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4866                 sw_if_index_set = 1;
4867             }
4868           else
4869             break;
4870         }
4871       else if (unformat (i, "static"))
4872         static_mac = 1;
4873       else if (unformat (i, "filter"))
4874         {
4875           filter_mac = 1;
4876           static_mac = 1;
4877         }
4878       else if (unformat (i, "bvi"))
4879         {
4880           bvi_mac = 1;
4881           static_mac = 1;
4882         }
4883       else if (unformat (i, "del"))
4884         is_add = 0;
4885       else if (unformat (i, "count %d", &count))
4886         ;
4887       else
4888         break;
4889     }
4890
4891   if (mac_set == 0)
4892     {
4893       errmsg ("missing mac address\n");
4894       return -99;
4895     }
4896
4897   if (bd_id_set == 0)
4898     {
4899       errmsg ("missing bridge domain\n");
4900       return -99;
4901     }
4902
4903   if (is_add && (sw_if_index_set == 0))
4904     {
4905       errmsg ("missing interface name or sw_if_index\n");
4906       return -99;
4907     }
4908
4909   if (count > 1)
4910     {
4911       /* Turn on async mode */
4912       vam->async_mode = 1;
4913       vam->async_errors = 0;
4914       before = vat_time_now (vam);
4915     }
4916
4917   for (j = 0; j < count; j++)
4918     {
4919       M (L2FIB_ADD_DEL, l2fib_add_del);
4920
4921       mp->mac = mac;
4922       mp->bd_id = ntohl (bd_id);
4923       mp->is_add = is_add;
4924
4925       if (is_add)
4926         {
4927           mp->sw_if_index = ntohl (sw_if_index);
4928           mp->static_mac = static_mac;
4929           mp->filter_mac = filter_mac;
4930           mp->bvi_mac = bvi_mac;
4931         }
4932       increment_mac_address (&mac);
4933       /* send it... */
4934       S;
4935     }
4936
4937   if (count > 1)
4938     {
4939       vl_api_control_ping_t *mp;
4940       f64 after;
4941
4942       /* Shut off async mode */
4943       vam->async_mode = 0;
4944
4945       M (CONTROL_PING, control_ping);
4946       S;
4947
4948       timeout = vat_time_now (vam) + 1.0;
4949       while (vat_time_now (vam) < timeout)
4950         if (vam->result_ready == 1)
4951           goto out;
4952       vam->retval = -99;
4953
4954     out:
4955       if (vam->retval == -99)
4956         errmsg ("timeout\n");
4957
4958       if (vam->async_errors > 0)
4959         {
4960           errmsg ("%d asynchronous errors\n", vam->async_errors);
4961           vam->retval = -98;
4962         }
4963       vam->async_errors = 0;
4964       after = vat_time_now (vam);
4965
4966       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4967                count, after - before, count / (after - before));
4968     }
4969   else
4970     {
4971       /* Wait for a reply... */
4972       W;
4973     }
4974   /* Return the good/bad news */
4975   return (vam->retval);
4976 }
4977
4978 static int
4979 api_l2_flags (vat_main_t * vam)
4980 {
4981   unformat_input_t *i = vam->input;
4982   vl_api_l2_flags_t *mp;
4983   f64 timeout;
4984   u32 sw_if_index;
4985   u32 feature_bitmap = 0;
4986   u8 sw_if_index_set = 0;
4987
4988   /* Parse args required to build the message */
4989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4990     {
4991       if (unformat (i, "sw_if_index %d", &sw_if_index))
4992         sw_if_index_set = 1;
4993       else if (unformat (i, "sw_if"))
4994         {
4995           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4996             {
4997               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4998                 sw_if_index_set = 1;
4999             }
5000           else
5001             break;
5002         }
5003       else if (unformat (i, "learn"))
5004         feature_bitmap |= L2INPUT_FEAT_LEARN;
5005       else if (unformat (i, "forward"))
5006         feature_bitmap |= L2INPUT_FEAT_FWD;
5007       else if (unformat (i, "flood"))
5008         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5009       else if (unformat (i, "uu-flood"))
5010         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5011       else
5012         break;
5013     }
5014
5015   if (sw_if_index_set == 0)
5016     {
5017       errmsg ("missing interface name or sw_if_index\n");
5018       return -99;
5019     }
5020
5021   M (L2_FLAGS, l2_flags);
5022
5023   mp->sw_if_index = ntohl (sw_if_index);
5024   mp->feature_bitmap = ntohl (feature_bitmap);
5025
5026   S;
5027   W;
5028   /* NOTREACHED */
5029   return 0;
5030 }
5031
5032 static int
5033 api_bridge_flags (vat_main_t * vam)
5034 {
5035   unformat_input_t *i = vam->input;
5036   vl_api_bridge_flags_t *mp;
5037   f64 timeout;
5038   u32 bd_id;
5039   u8 bd_id_set = 0;
5040   u8 is_set = 1;
5041   u32 flags = 0;
5042
5043   /* Parse args required to build the message */
5044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5045     {
5046       if (unformat (i, "bd_id %d", &bd_id))
5047         bd_id_set = 1;
5048       else if (unformat (i, "learn"))
5049         flags |= L2_LEARN;
5050       else if (unformat (i, "forward"))
5051         flags |= L2_FWD;
5052       else if (unformat (i, "flood"))
5053         flags |= L2_FLOOD;
5054       else if (unformat (i, "uu-flood"))
5055         flags |= L2_UU_FLOOD;
5056       else if (unformat (i, "arp-term"))
5057         flags |= L2_ARP_TERM;
5058       else if (unformat (i, "off"))
5059         is_set = 0;
5060       else if (unformat (i, "disable"))
5061         is_set = 0;
5062       else
5063         break;
5064     }
5065
5066   if (bd_id_set == 0)
5067     {
5068       errmsg ("missing bridge domain\n");
5069       return -99;
5070     }
5071
5072   M (BRIDGE_FLAGS, bridge_flags);
5073
5074   mp->bd_id = ntohl (bd_id);
5075   mp->feature_bitmap = ntohl (flags);
5076   mp->is_set = is_set;
5077
5078   S;
5079   W;
5080   /* NOTREACHED */
5081   return 0;
5082 }
5083
5084 static int
5085 api_bd_ip_mac_add_del (vat_main_t * vam)
5086 {
5087   unformat_input_t *i = vam->input;
5088   vl_api_bd_ip_mac_add_del_t *mp;
5089   f64 timeout;
5090   u32 bd_id;
5091   u8 is_ipv6 = 0;
5092   u8 is_add = 1;
5093   u8 bd_id_set = 0;
5094   u8 ip_set = 0;
5095   u8 mac_set = 0;
5096   ip4_address_t v4addr;
5097   ip6_address_t v6addr;
5098   u8 macaddr[6];
5099
5100
5101   /* Parse args required to build the message */
5102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5103     {
5104       if (unformat (i, "bd_id %d", &bd_id))
5105         {
5106           bd_id_set++;
5107         }
5108       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5109         {
5110           ip_set++;
5111         }
5112       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5113         {
5114           ip_set++;
5115           is_ipv6++;
5116         }
5117       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5118         {
5119           mac_set++;
5120         }
5121       else if (unformat (i, "del"))
5122         is_add = 0;
5123       else
5124         break;
5125     }
5126
5127   if (bd_id_set == 0)
5128     {
5129       errmsg ("missing bridge domain\n");
5130       return -99;
5131     }
5132   else if (ip_set == 0)
5133     {
5134       errmsg ("missing IP address\n");
5135       return -99;
5136     }
5137   else if (mac_set == 0)
5138     {
5139       errmsg ("missing MAC address\n");
5140       return -99;
5141     }
5142
5143   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5144
5145   mp->bd_id = ntohl (bd_id);
5146   mp->is_ipv6 = is_ipv6;
5147   mp->is_add = is_add;
5148   if (is_ipv6)
5149     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5150   else
5151     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5152   clib_memcpy (mp->mac_address, macaddr, 6);
5153   S;
5154   W;
5155   /* NOTREACHED */
5156   return 0;
5157 }
5158
5159 static int
5160 api_tap_connect (vat_main_t * vam)
5161 {
5162   unformat_input_t *i = vam->input;
5163   vl_api_tap_connect_t *mp;
5164   f64 timeout;
5165   u8 mac_address[6];
5166   u8 random_mac = 1;
5167   u8 name_set = 0;
5168   u8 *tap_name;
5169
5170   memset (mac_address, 0, sizeof (mac_address));
5171
5172   /* Parse args required to build the message */
5173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5174     {
5175       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5176         {
5177           random_mac = 0;
5178         }
5179       else if (unformat (i, "random-mac"))
5180         random_mac = 1;
5181       else if (unformat (i, "tapname %s", &tap_name))
5182         name_set = 1;
5183       else
5184         break;
5185     }
5186
5187   if (name_set == 0)
5188     {
5189       errmsg ("missing tap name\n");
5190       return -99;
5191     }
5192   if (vec_len (tap_name) > 63)
5193     {
5194       errmsg ("tap name too long\n");
5195     }
5196   vec_add1 (tap_name, 0);
5197
5198   /* Construct the API message */
5199   M (TAP_CONNECT, tap_connect);
5200
5201   mp->use_random_mac = random_mac;
5202   clib_memcpy (mp->mac_address, mac_address, 6);
5203   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5204   vec_free (tap_name);
5205
5206   /* send it... */
5207   S;
5208
5209   /* Wait for a reply... */
5210   W;
5211 }
5212
5213 static int
5214 api_tap_modify (vat_main_t * vam)
5215 {
5216   unformat_input_t *i = vam->input;
5217   vl_api_tap_modify_t *mp;
5218   f64 timeout;
5219   u8 mac_address[6];
5220   u8 random_mac = 1;
5221   u8 name_set = 0;
5222   u8 *tap_name;
5223   u32 sw_if_index = ~0;
5224   u8 sw_if_index_set = 0;
5225
5226   memset (mac_address, 0, sizeof (mac_address));
5227
5228   /* Parse args required to build the message */
5229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5230     {
5231       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5232         sw_if_index_set = 1;
5233       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5234         sw_if_index_set = 1;
5235       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5236         {
5237           random_mac = 0;
5238         }
5239       else if (unformat (i, "random-mac"))
5240         random_mac = 1;
5241       else if (unformat (i, "tapname %s", &tap_name))
5242         name_set = 1;
5243       else
5244         break;
5245     }
5246
5247   if (sw_if_index_set == 0)
5248     {
5249       errmsg ("missing vpp interface name");
5250       return -99;
5251     }
5252   if (name_set == 0)
5253     {
5254       errmsg ("missing tap name\n");
5255       return -99;
5256     }
5257   if (vec_len (tap_name) > 63)
5258     {
5259       errmsg ("tap name too long\n");
5260     }
5261   vec_add1 (tap_name, 0);
5262
5263   /* Construct the API message */
5264   M (TAP_MODIFY, tap_modify);
5265
5266   mp->use_random_mac = random_mac;
5267   mp->sw_if_index = ntohl (sw_if_index);
5268   clib_memcpy (mp->mac_address, mac_address, 6);
5269   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5270   vec_free (tap_name);
5271
5272   /* send it... */
5273   S;
5274
5275   /* Wait for a reply... */
5276   W;
5277 }
5278
5279 static int
5280 api_tap_delete (vat_main_t * vam)
5281 {
5282   unformat_input_t *i = vam->input;
5283   vl_api_tap_delete_t *mp;
5284   f64 timeout;
5285   u32 sw_if_index = ~0;
5286   u8 sw_if_index_set = 0;
5287
5288   /* Parse args required to build the message */
5289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5290     {
5291       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5292         sw_if_index_set = 1;
5293       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5294         sw_if_index_set = 1;
5295       else
5296         break;
5297     }
5298
5299   if (sw_if_index_set == 0)
5300     {
5301       errmsg ("missing vpp interface name");
5302       return -99;
5303     }
5304
5305   /* Construct the API message */
5306   M (TAP_DELETE, tap_delete);
5307
5308   mp->sw_if_index = ntohl (sw_if_index);
5309
5310   /* send it... */
5311   S;
5312
5313   /* Wait for a reply... */
5314   W;
5315 }
5316
5317 static int
5318 api_ip_add_del_route (vat_main_t * vam)
5319 {
5320   unformat_input_t *i = vam->input;
5321   vl_api_ip_add_del_route_t *mp;
5322   f64 timeout;
5323   u32 sw_if_index = ~0, vrf_id = 0;
5324   u8 sw_if_index_set = 0;
5325   u8 is_ipv6 = 0;
5326   u8 is_local = 0, is_drop = 0;
5327   u8 create_vrf_if_needed = 0;
5328   u8 is_add = 1;
5329   u8 next_hop_weight = 1;
5330   u8 not_last = 0;
5331   u8 is_multipath = 0;
5332   u8 address_set = 0;
5333   u8 address_length_set = 0;
5334   u32 lookup_in_vrf = 0;
5335   u32 resolve_attempts = 0;
5336   u32 dst_address_length = 0;
5337   u8 next_hop_set = 0;
5338   ip4_address_t v4_dst_address, v4_next_hop_address;
5339   ip6_address_t v6_dst_address, v6_next_hop_address;
5340   int count = 1;
5341   int j;
5342   f64 before = 0;
5343   u32 random_add_del = 0;
5344   u32 *random_vector = 0;
5345   uword *random_hash;
5346   u32 random_seed = 0xdeaddabe;
5347   u32 classify_table_index = ~0;
5348   u8 is_classify = 0;
5349
5350   /* Parse args required to build the message */
5351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5352     {
5353       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5354         sw_if_index_set = 1;
5355       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5356         sw_if_index_set = 1;
5357       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5358         {
5359           address_set = 1;
5360           is_ipv6 = 0;
5361         }
5362       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5363         {
5364           address_set = 1;
5365           is_ipv6 = 1;
5366         }
5367       else if (unformat (i, "/%d", &dst_address_length))
5368         {
5369           address_length_set = 1;
5370         }
5371
5372       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5373                                          &v4_next_hop_address))
5374         {
5375           next_hop_set = 1;
5376         }
5377       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5378                                          &v6_next_hop_address))
5379         {
5380           next_hop_set = 1;
5381         }
5382       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5383         ;
5384       else if (unformat (i, "weight %d", &next_hop_weight))
5385         ;
5386       else if (unformat (i, "drop"))
5387         {
5388           is_drop = 1;
5389         }
5390       else if (unformat (i, "local"))
5391         {
5392           is_local = 1;
5393         }
5394       else if (unformat (i, "classify %d", &classify_table_index))
5395         {
5396           is_classify = 1;
5397         }
5398       else if (unformat (i, "del"))
5399         is_add = 0;
5400       else if (unformat (i, "add"))
5401         is_add = 1;
5402       else if (unformat (i, "not-last"))
5403         not_last = 1;
5404       else if (unformat (i, "multipath"))
5405         is_multipath = 1;
5406       else if (unformat (i, "vrf %d", &vrf_id))
5407         ;
5408       else if (unformat (i, "create-vrf"))
5409         create_vrf_if_needed = 1;
5410       else if (unformat (i, "count %d", &count))
5411         ;
5412       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5413         ;
5414       else if (unformat (i, "random"))
5415         random_add_del = 1;
5416       else if (unformat (i, "seed %d", &random_seed))
5417         ;
5418       else
5419         {
5420           clib_warning ("parse error '%U'", format_unformat_error, i);
5421           return -99;
5422         }
5423     }
5424
5425   if (resolve_attempts > 0 && sw_if_index_set == 0)
5426     {
5427       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5428       return -99;
5429     }
5430
5431   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5432     {
5433       errmsg ("next hop / local / drop / classify not set\n");
5434       return -99;
5435     }
5436
5437   if (address_set == 0)
5438     {
5439       errmsg ("missing addresses\n");
5440       return -99;
5441     }
5442
5443   if (address_length_set == 0)
5444     {
5445       errmsg ("missing address length\n");
5446       return -99;
5447     }
5448
5449   /* Generate a pile of unique, random routes */
5450   if (random_add_del)
5451     {
5452       u32 this_random_address;
5453       random_hash = hash_create (count, sizeof (uword));
5454
5455       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5456       for (j = 0; j <= count; j++)
5457         {
5458           do
5459             {
5460               this_random_address = random_u32 (&random_seed);
5461               this_random_address =
5462                 clib_host_to_net_u32 (this_random_address);
5463             }
5464           while (hash_get (random_hash, this_random_address));
5465           vec_add1 (random_vector, this_random_address);
5466           hash_set (random_hash, this_random_address, 1);
5467         }
5468       hash_free (random_hash);
5469       v4_dst_address.as_u32 = random_vector[0];
5470     }
5471
5472   if (count > 1)
5473     {
5474       /* Turn on async mode */
5475       vam->async_mode = 1;
5476       vam->async_errors = 0;
5477       before = vat_time_now (vam);
5478     }
5479
5480   for (j = 0; j < count; j++)
5481     {
5482       /* Construct the API message */
5483       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5484
5485       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5486       mp->vrf_id = ntohl (vrf_id);
5487       if (resolve_attempts > 0)
5488         {
5489           mp->resolve_attempts = ntohl (resolve_attempts);
5490           mp->resolve_if_needed = 1;
5491         }
5492       mp->create_vrf_if_needed = create_vrf_if_needed;
5493
5494       mp->is_add = is_add;
5495       mp->is_drop = is_drop;
5496       mp->is_ipv6 = is_ipv6;
5497       mp->is_local = is_local;
5498       mp->is_classify = is_classify;
5499       mp->is_multipath = is_multipath;
5500       mp->not_last = not_last;
5501       mp->next_hop_weight = next_hop_weight;
5502       mp->dst_address_length = dst_address_length;
5503       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5504       mp->classify_table_index = ntohl (classify_table_index);
5505
5506       if (is_ipv6)
5507         {
5508           clib_memcpy (mp->dst_address, &v6_dst_address,
5509                        sizeof (v6_dst_address));
5510           if (next_hop_set)
5511             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5512                          sizeof (v6_next_hop_address));
5513           increment_v6_address (&v6_dst_address);
5514         }
5515       else
5516         {
5517           clib_memcpy (mp->dst_address, &v4_dst_address,
5518                        sizeof (v4_dst_address));
5519           if (next_hop_set)
5520             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5521                          sizeof (v4_next_hop_address));
5522           if (random_add_del)
5523             v4_dst_address.as_u32 = random_vector[j + 1];
5524           else
5525             increment_v4_address (&v4_dst_address);
5526         }
5527       /* send it... */
5528       S;
5529     }
5530
5531   /* When testing multiple add/del ops, use a control-ping to sync */
5532   if (count > 1)
5533     {
5534       vl_api_control_ping_t *mp;
5535       f64 after;
5536
5537       /* Shut off async mode */
5538       vam->async_mode = 0;
5539
5540       M (CONTROL_PING, control_ping);
5541       S;
5542
5543       timeout = vat_time_now (vam) + 1.0;
5544       while (vat_time_now (vam) < timeout)
5545         if (vam->result_ready == 1)
5546           goto out;
5547       vam->retval = -99;
5548
5549     out:
5550       if (vam->retval == -99)
5551         errmsg ("timeout\n");
5552
5553       if (vam->async_errors > 0)
5554         {
5555           errmsg ("%d asynchronous errors\n", vam->async_errors);
5556           vam->retval = -98;
5557         }
5558       vam->async_errors = 0;
5559       after = vat_time_now (vam);
5560
5561       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5562                count, after - before, count / (after - before));
5563     }
5564   else
5565     {
5566       /* Wait for a reply... */
5567       W;
5568     }
5569
5570   /* Return the good/bad news */
5571   return (vam->retval);
5572 }
5573
5574 static int
5575 api_proxy_arp_add_del (vat_main_t * vam)
5576 {
5577   unformat_input_t *i = vam->input;
5578   vl_api_proxy_arp_add_del_t *mp;
5579   f64 timeout;
5580   u32 vrf_id = 0;
5581   u8 is_add = 1;
5582   ip4_address_t lo, hi;
5583   u8 range_set = 0;
5584
5585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5586     {
5587       if (unformat (i, "vrf %d", &vrf_id))
5588         ;
5589       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5590                          unformat_ip4_address, &hi))
5591         range_set = 1;
5592       else if (unformat (i, "del"))
5593         is_add = 0;
5594       else
5595         {
5596           clib_warning ("parse error '%U'", format_unformat_error, i);
5597           return -99;
5598         }
5599     }
5600
5601   if (range_set == 0)
5602     {
5603       errmsg ("address range not set\n");
5604       return -99;
5605     }
5606
5607   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5608
5609   mp->vrf_id = ntohl (vrf_id);
5610   mp->is_add = is_add;
5611   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5612   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5613
5614   S;
5615   W;
5616   /* NOTREACHED */
5617   return 0;
5618 }
5619
5620 static int
5621 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5622 {
5623   unformat_input_t *i = vam->input;
5624   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5625   f64 timeout;
5626   u32 sw_if_index;
5627   u8 enable = 1;
5628   u8 sw_if_index_set = 0;
5629
5630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5631     {
5632       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5633         sw_if_index_set = 1;
5634       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5635         sw_if_index_set = 1;
5636       else if (unformat (i, "enable"))
5637         enable = 1;
5638       else if (unformat (i, "disable"))
5639         enable = 0;
5640       else
5641         {
5642           clib_warning ("parse error '%U'", format_unformat_error, i);
5643           return -99;
5644         }
5645     }
5646
5647   if (sw_if_index_set == 0)
5648     {
5649       errmsg ("missing interface name or sw_if_index\n");
5650       return -99;
5651     }
5652
5653   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5654
5655   mp->sw_if_index = ntohl (sw_if_index);
5656   mp->enable_disable = enable;
5657
5658   S;
5659   W;
5660   /* NOTREACHED */
5661   return 0;
5662 }
5663
5664 static int
5665 api_mpls_add_del_decap (vat_main_t * vam)
5666 {
5667   unformat_input_t *i = vam->input;
5668   vl_api_mpls_add_del_decap_t *mp;
5669   f64 timeout;
5670   u32 rx_vrf_id = 0;
5671   u32 tx_vrf_id = 0;
5672   u32 label = 0;
5673   u8 is_add = 1;
5674   u8 s_bit = 1;
5675   u32 next_index = 1;
5676
5677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5678     {
5679       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5680         ;
5681       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5682         ;
5683       else if (unformat (i, "label %d", &label))
5684         ;
5685       else if (unformat (i, "next-index %d", &next_index))
5686         ;
5687       else if (unformat (i, "del"))
5688         is_add = 0;
5689       else if (unformat (i, "s-bit-clear"))
5690         s_bit = 0;
5691       else
5692         {
5693           clib_warning ("parse error '%U'", format_unformat_error, i);
5694           return -99;
5695         }
5696     }
5697
5698   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5699
5700   mp->rx_vrf_id = ntohl (rx_vrf_id);
5701   mp->tx_vrf_id = ntohl (tx_vrf_id);
5702   mp->label = ntohl (label);
5703   mp->next_index = ntohl (next_index);
5704   mp->s_bit = s_bit;
5705   mp->is_add = is_add;
5706
5707   S;
5708   W;
5709   /* NOTREACHED */
5710   return 0;
5711 }
5712
5713 static int
5714 api_mpls_add_del_encap (vat_main_t * vam)
5715 {
5716   unformat_input_t *i = vam->input;
5717   vl_api_mpls_add_del_encap_t *mp;
5718   f64 timeout;
5719   u32 vrf_id = 0;
5720   u32 *labels = 0;
5721   u32 label;
5722   ip4_address_t dst_address;
5723   u8 is_add = 1;
5724
5725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5726     {
5727       if (unformat (i, "vrf %d", &vrf_id))
5728         ;
5729       else if (unformat (i, "label %d", &label))
5730         vec_add1 (labels, ntohl (label));
5731       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5732         ;
5733       else if (unformat (i, "del"))
5734         is_add = 0;
5735       else
5736         {
5737           clib_warning ("parse error '%U'", format_unformat_error, i);
5738           return -99;
5739         }
5740     }
5741
5742   if (vec_len (labels) == 0)
5743     {
5744       errmsg ("missing encap label stack\n");
5745       return -99;
5746     }
5747
5748   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
5749       sizeof (u32) * vec_len (labels));
5750
5751   mp->vrf_id = ntohl (vrf_id);
5752   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5753   mp->is_add = is_add;
5754   mp->nlabels = vec_len (labels);
5755   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
5756
5757   vec_free (labels);
5758
5759   S;
5760   W;
5761   /* NOTREACHED */
5762   return 0;
5763 }
5764
5765 static int
5766 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
5767 {
5768   unformat_input_t *i = vam->input;
5769   vl_api_mpls_gre_add_del_tunnel_t *mp;
5770   f64 timeout;
5771   u32 inner_vrf_id = 0;
5772   u32 outer_vrf_id = 0;
5773   ip4_address_t src_address;
5774   ip4_address_t dst_address;
5775   ip4_address_t intfc_address;
5776   u32 tmp;
5777   u8 intfc_address_length = 0;
5778   u8 is_add = 1;
5779   u8 l2_only = 0;
5780
5781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5782     {
5783       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5784         ;
5785       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5786         ;
5787       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
5788         ;
5789       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5790         ;
5791       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5792                          &intfc_address, &tmp))
5793         intfc_address_length = tmp;
5794       else if (unformat (i, "l2-only"))
5795         l2_only = 1;
5796       else if (unformat (i, "del"))
5797         is_add = 0;
5798       else
5799         {
5800           clib_warning ("parse error '%U'", format_unformat_error, i);
5801           return -99;
5802         }
5803     }
5804
5805   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
5806
5807   mp->inner_vrf_id = ntohl (inner_vrf_id);
5808   mp->outer_vrf_id = ntohl (outer_vrf_id);
5809   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
5810   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5811   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
5812   mp->intfc_address_length = intfc_address_length;
5813   mp->l2_only = l2_only;
5814   mp->is_add = is_add;
5815
5816   S;
5817   W;
5818   /* NOTREACHED */
5819   return 0;
5820 }
5821
5822 static int
5823 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
5824 {
5825   unformat_input_t *i = vam->input;
5826   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
5827   f64 timeout;
5828   u32 inner_vrf_id = 0;
5829   ip4_address_t intfc_address;
5830   u8 dst_mac_address[6];
5831   int dst_set = 1;
5832   u32 tmp;
5833   u8 intfc_address_length = 0;
5834   u8 is_add = 1;
5835   u8 l2_only = 0;
5836   u32 tx_sw_if_index;
5837   int tx_sw_if_index_set = 0;
5838
5839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5840     {
5841       if (unformat (i, "vrf %d", &inner_vrf_id))
5842         ;
5843       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5844                          &intfc_address, &tmp))
5845         intfc_address_length = tmp;
5846       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
5847         tx_sw_if_index_set = 1;
5848       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5849         tx_sw_if_index_set = 1;
5850       else if (unformat (i, "dst %U", unformat_ethernet_address,
5851                          dst_mac_address))
5852         dst_set = 1;
5853       else if (unformat (i, "l2-only"))
5854         l2_only = 1;
5855       else if (unformat (i, "del"))
5856         is_add = 0;
5857       else
5858         {
5859           clib_warning ("parse error '%U'", format_unformat_error, i);
5860           return -99;
5861         }
5862     }
5863
5864   if (!dst_set)
5865     {
5866       errmsg ("dst (mac address) not set\n");
5867       return -99;
5868     }
5869   if (!tx_sw_if_index_set)
5870     {
5871       errmsg ("tx-intfc not set\n");
5872       return -99;
5873     }
5874
5875   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
5876
5877   mp->vrf_id = ntohl (inner_vrf_id);
5878   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
5879   mp->adj_address_length = intfc_address_length;
5880   clib_memcpy (mp->dst_mac_address, dst_mac_address,
5881                sizeof (dst_mac_address));
5882   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5883   mp->l2_only = l2_only;
5884   mp->is_add = is_add;
5885
5886   S;
5887   W;
5888   /* NOTREACHED */
5889   return 0;
5890 }
5891
5892 static int
5893 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
5894 {
5895   unformat_input_t *i = vam->input;
5896   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
5897   f64 timeout;
5898   u32 inner_vrf_id = 0;
5899   u32 outer_vrf_id = 0;
5900   ip4_address_t adj_address;
5901   int adj_address_set = 0;
5902   ip4_address_t next_hop_address;
5903   int next_hop_address_set = 0;
5904   u32 tmp;
5905   u8 adj_address_length = 0;
5906   u8 l2_only = 0;
5907   u8 is_add = 1;
5908   u32 resolve_attempts = 5;
5909   u8 resolve_if_needed = 1;
5910
5911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5912     {
5913       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5914         ;
5915       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5916         ;
5917       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5918                          &adj_address, &tmp))
5919         {
5920           adj_address_length = tmp;
5921           adj_address_set = 1;
5922         }
5923       else if (unformat (i, "next-hop %U", unformat_ip4_address,
5924                          &next_hop_address))
5925         next_hop_address_set = 1;
5926       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5927         ;
5928       else if (unformat (i, "resolve-if-needed %d", &tmp))
5929         resolve_if_needed = tmp;
5930       else if (unformat (i, "l2-only"))
5931         l2_only = 1;
5932       else if (unformat (i, "del"))
5933         is_add = 0;
5934       else
5935         {
5936           clib_warning ("parse error '%U'", format_unformat_error, i);
5937           return -99;
5938         }
5939     }
5940
5941   if (!adj_address_set)
5942     {
5943       errmsg ("adjacency address/mask not set\n");
5944       return -99;
5945     }
5946   if (!next_hop_address_set)
5947     {
5948       errmsg ("ip4 next hop address (in outer fib) not set\n");
5949       return -99;
5950     }
5951
5952   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
5953
5954   mp->inner_vrf_id = ntohl (inner_vrf_id);
5955   mp->outer_vrf_id = ntohl (outer_vrf_id);
5956   mp->resolve_attempts = ntohl (resolve_attempts);
5957   mp->resolve_if_needed = resolve_if_needed;
5958   mp->is_add = is_add;
5959   mp->l2_only = l2_only;
5960   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
5961   mp->adj_address_length = adj_address_length;
5962   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
5963                sizeof (next_hop_address));
5964
5965   S;
5966   W;
5967   /* NOTREACHED */
5968   return 0;
5969 }
5970
5971 static int
5972 api_sw_interface_set_unnumbered (vat_main_t * vam)
5973 {
5974   unformat_input_t *i = vam->input;
5975   vl_api_sw_interface_set_unnumbered_t *mp;
5976   f64 timeout;
5977   u32 sw_if_index;
5978   u32 unnum_sw_index = ~0;
5979   u8 is_add = 1;
5980   u8 sw_if_index_set = 0;
5981
5982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5983     {
5984       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5985         sw_if_index_set = 1;
5986       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5987         sw_if_index_set = 1;
5988       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
5989         ;
5990       else if (unformat (i, "del"))
5991         is_add = 0;
5992       else
5993         {
5994           clib_warning ("parse error '%U'", format_unformat_error, i);
5995           return -99;
5996         }
5997     }
5998
5999   if (sw_if_index_set == 0)
6000     {
6001       errmsg ("missing interface name or sw_if_index\n");
6002       return -99;
6003     }
6004
6005   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6006
6007   mp->sw_if_index = ntohl (sw_if_index);
6008   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6009   mp->is_add = is_add;
6010
6011   S;
6012   W;
6013   /* NOTREACHED */
6014   return 0;
6015 }
6016
6017 static int
6018 api_ip_neighbor_add_del (vat_main_t * vam)
6019 {
6020   unformat_input_t *i = vam->input;
6021   vl_api_ip_neighbor_add_del_t *mp;
6022   f64 timeout;
6023   u32 sw_if_index;
6024   u8 sw_if_index_set = 0;
6025   u32 vrf_id = 0;
6026   u8 is_add = 1;
6027   u8 is_static = 0;
6028   u8 mac_address[6];
6029   u8 mac_set = 0;
6030   u8 v4_address_set = 0;
6031   u8 v6_address_set = 0;
6032   ip4_address_t v4address;
6033   ip6_address_t v6address;
6034
6035   memset (mac_address, 0, sizeof (mac_address));
6036
6037   /* Parse args required to build the message */
6038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6039     {
6040       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6041         {
6042           mac_set = 1;
6043         }
6044       else if (unformat (i, "del"))
6045         is_add = 0;
6046       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6047         sw_if_index_set = 1;
6048       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6049         sw_if_index_set = 1;
6050       else if (unformat (i, "is_static"))
6051         is_static = 1;
6052       else if (unformat (i, "vrf %d", &vrf_id))
6053         ;
6054       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6055         v4_address_set = 1;
6056       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6057         v6_address_set = 1;
6058       else
6059         {
6060           clib_warning ("parse error '%U'", format_unformat_error, i);
6061           return -99;
6062         }
6063     }
6064
6065   if (sw_if_index_set == 0)
6066     {
6067       errmsg ("missing interface name or sw_if_index\n");
6068       return -99;
6069     }
6070   if (v4_address_set && v6_address_set)
6071     {
6072       errmsg ("both v4 and v6 addresses set\n");
6073       return -99;
6074     }
6075   if (!v4_address_set && !v6_address_set)
6076     {
6077       errmsg ("no address set\n");
6078       return -99;
6079     }
6080
6081   /* Construct the API message */
6082   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6083
6084   mp->sw_if_index = ntohl (sw_if_index);
6085   mp->is_add = is_add;
6086   mp->vrf_id = ntohl (vrf_id);
6087   mp->is_static = is_static;
6088   if (mac_set)
6089     clib_memcpy (mp->mac_address, mac_address, 6);
6090   if (v6_address_set)
6091     {
6092       mp->is_ipv6 = 1;
6093       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6094     }
6095   else
6096     {
6097       /* mp->is_ipv6 = 0; via memset in M macro above */
6098       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6099     }
6100
6101   /* send it... */
6102   S;
6103
6104   /* Wait for a reply, return good/bad news  */
6105   W;
6106
6107   /* NOTREACHED */
6108   return 0;
6109 }
6110
6111 static int
6112 api_reset_vrf (vat_main_t * vam)
6113 {
6114   unformat_input_t *i = vam->input;
6115   vl_api_reset_vrf_t *mp;
6116   f64 timeout;
6117   u32 vrf_id = 0;
6118   u8 is_ipv6 = 0;
6119   u8 vrf_id_set = 0;
6120
6121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6122     {
6123       if (unformat (i, "vrf %d", &vrf_id))
6124         vrf_id_set = 1;
6125       else if (unformat (i, "ipv6"))
6126         is_ipv6 = 1;
6127       else
6128         {
6129           clib_warning ("parse error '%U'", format_unformat_error, i);
6130           return -99;
6131         }
6132     }
6133
6134   if (vrf_id_set == 0)
6135     {
6136       errmsg ("missing vrf id\n");
6137       return -99;
6138     }
6139
6140   M (RESET_VRF, reset_vrf);
6141
6142   mp->vrf_id = ntohl (vrf_id);
6143   mp->is_ipv6 = is_ipv6;
6144
6145   S;
6146   W;
6147   /* NOTREACHED */
6148   return 0;
6149 }
6150
6151 static int
6152 api_create_vlan_subif (vat_main_t * vam)
6153 {
6154   unformat_input_t *i = vam->input;
6155   vl_api_create_vlan_subif_t *mp;
6156   f64 timeout;
6157   u32 sw_if_index;
6158   u8 sw_if_index_set = 0;
6159   u32 vlan_id;
6160   u8 vlan_id_set = 0;
6161
6162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6163     {
6164       if (unformat (i, "sw_if_index %d", &sw_if_index))
6165         sw_if_index_set = 1;
6166       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6167         sw_if_index_set = 1;
6168       else if (unformat (i, "vlan %d", &vlan_id))
6169         vlan_id_set = 1;
6170       else
6171         {
6172           clib_warning ("parse error '%U'", format_unformat_error, i);
6173           return -99;
6174         }
6175     }
6176
6177   if (sw_if_index_set == 0)
6178     {
6179       errmsg ("missing interface name or sw_if_index\n");
6180       return -99;
6181     }
6182
6183   if (vlan_id_set == 0)
6184     {
6185       errmsg ("missing vlan_id\n");
6186       return -99;
6187     }
6188   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6189
6190   mp->sw_if_index = ntohl (sw_if_index);
6191   mp->vlan_id = ntohl (vlan_id);
6192
6193   S;
6194   W;
6195   /* NOTREACHED */
6196   return 0;
6197 }
6198
6199 #define foreach_create_subif_bit                \
6200 _(no_tags)                                      \
6201 _(one_tag)                                      \
6202 _(two_tags)                                     \
6203 _(dot1ad)                                       \
6204 _(exact_match)                                  \
6205 _(default_sub)                                  \
6206 _(outer_vlan_id_any)                            \
6207 _(inner_vlan_id_any)
6208
6209 static int
6210 api_create_subif (vat_main_t * vam)
6211 {
6212   unformat_input_t *i = vam->input;
6213   vl_api_create_subif_t *mp;
6214   f64 timeout;
6215   u32 sw_if_index;
6216   u8 sw_if_index_set = 0;
6217   u32 sub_id;
6218   u8 sub_id_set = 0;
6219   u32 no_tags = 0;
6220   u32 one_tag = 0;
6221   u32 two_tags = 0;
6222   u32 dot1ad = 0;
6223   u32 exact_match = 0;
6224   u32 default_sub = 0;
6225   u32 outer_vlan_id_any = 0;
6226   u32 inner_vlan_id_any = 0;
6227   u32 tmp;
6228   u16 outer_vlan_id = 0;
6229   u16 inner_vlan_id = 0;
6230
6231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6232     {
6233       if (unformat (i, "sw_if_index %d", &sw_if_index))
6234         sw_if_index_set = 1;
6235       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6236         sw_if_index_set = 1;
6237       else if (unformat (i, "sub_id %d", &sub_id))
6238         sub_id_set = 1;
6239       else if (unformat (i, "outer_vlan_id %d", &tmp))
6240         outer_vlan_id = tmp;
6241       else if (unformat (i, "inner_vlan_id %d", &tmp))
6242         inner_vlan_id = tmp;
6243
6244 #define _(a) else if (unformat (i, #a)) a = 1 ;
6245       foreach_create_subif_bit
6246 #undef _
6247         else
6248         {
6249           clib_warning ("parse error '%U'", format_unformat_error, i);
6250           return -99;
6251         }
6252     }
6253
6254   if (sw_if_index_set == 0)
6255     {
6256       errmsg ("missing interface name or sw_if_index\n");
6257       return -99;
6258     }
6259
6260   if (sub_id_set == 0)
6261     {
6262       errmsg ("missing sub_id\n");
6263       return -99;
6264     }
6265   M (CREATE_SUBIF, create_subif);
6266
6267   mp->sw_if_index = ntohl (sw_if_index);
6268   mp->sub_id = ntohl (sub_id);
6269
6270 #define _(a) mp->a = a;
6271   foreach_create_subif_bit;
6272 #undef _
6273
6274   mp->outer_vlan_id = ntohs (outer_vlan_id);
6275   mp->inner_vlan_id = ntohs (inner_vlan_id);
6276
6277   S;
6278   W;
6279   /* NOTREACHED */
6280   return 0;
6281 }
6282
6283 static int
6284 api_oam_add_del (vat_main_t * vam)
6285 {
6286   unformat_input_t *i = vam->input;
6287   vl_api_oam_add_del_t *mp;
6288   f64 timeout;
6289   u32 vrf_id = 0;
6290   u8 is_add = 1;
6291   ip4_address_t src, dst;
6292   u8 src_set = 0;
6293   u8 dst_set = 0;
6294
6295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6296     {
6297       if (unformat (i, "vrf %d", &vrf_id))
6298         ;
6299       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6300         src_set = 1;
6301       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6302         dst_set = 1;
6303       else if (unformat (i, "del"))
6304         is_add = 0;
6305       else
6306         {
6307           clib_warning ("parse error '%U'", format_unformat_error, i);
6308           return -99;
6309         }
6310     }
6311
6312   if (src_set == 0)
6313     {
6314       errmsg ("missing src addr\n");
6315       return -99;
6316     }
6317
6318   if (dst_set == 0)
6319     {
6320       errmsg ("missing dst addr\n");
6321       return -99;
6322     }
6323
6324   M (OAM_ADD_DEL, oam_add_del);
6325
6326   mp->vrf_id = ntohl (vrf_id);
6327   mp->is_add = is_add;
6328   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6329   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6330
6331   S;
6332   W;
6333   /* NOTREACHED */
6334   return 0;
6335 }
6336
6337 static int
6338 api_reset_fib (vat_main_t * vam)
6339 {
6340   unformat_input_t *i = vam->input;
6341   vl_api_reset_fib_t *mp;
6342   f64 timeout;
6343   u32 vrf_id = 0;
6344   u8 is_ipv6 = 0;
6345   u8 vrf_id_set = 0;
6346
6347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6348     {
6349       if (unformat (i, "vrf %d", &vrf_id))
6350         vrf_id_set = 1;
6351       else if (unformat (i, "ipv6"))
6352         is_ipv6 = 1;
6353       else
6354         {
6355           clib_warning ("parse error '%U'", format_unformat_error, i);
6356           return -99;
6357         }
6358     }
6359
6360   if (vrf_id_set == 0)
6361     {
6362       errmsg ("missing vrf id\n");
6363       return -99;
6364     }
6365
6366   M (RESET_FIB, reset_fib);
6367
6368   mp->vrf_id = ntohl (vrf_id);
6369   mp->is_ipv6 = is_ipv6;
6370
6371   S;
6372   W;
6373   /* NOTREACHED */
6374   return 0;
6375 }
6376
6377 static int
6378 api_dhcp_proxy_config (vat_main_t * vam)
6379 {
6380   unformat_input_t *i = vam->input;
6381   vl_api_dhcp_proxy_config_t *mp;
6382   f64 timeout;
6383   u32 vrf_id = 0;
6384   u8 is_add = 1;
6385   u8 insert_cid = 1;
6386   u8 v4_address_set = 0;
6387   u8 v6_address_set = 0;
6388   ip4_address_t v4address;
6389   ip6_address_t v6address;
6390   u8 v4_src_address_set = 0;
6391   u8 v6_src_address_set = 0;
6392   ip4_address_t v4srcaddress;
6393   ip6_address_t v6srcaddress;
6394
6395   /* Parse args required to build the message */
6396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6397     {
6398       if (unformat (i, "del"))
6399         is_add = 0;
6400       else if (unformat (i, "vrf %d", &vrf_id))
6401         ;
6402       else if (unformat (i, "insert-cid %d", &insert_cid))
6403         ;
6404       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6405         v4_address_set = 1;
6406       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6407         v6_address_set = 1;
6408       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6409         v4_src_address_set = 1;
6410       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6411         v6_src_address_set = 1;
6412       else
6413         break;
6414     }
6415
6416   if (v4_address_set && v6_address_set)
6417     {
6418       errmsg ("both v4 and v6 server addresses set\n");
6419       return -99;
6420     }
6421   if (!v4_address_set && !v6_address_set)
6422     {
6423       errmsg ("no server addresses set\n");
6424       return -99;
6425     }
6426
6427   if (v4_src_address_set && v6_src_address_set)
6428     {
6429       errmsg ("both v4 and v6  src addresses set\n");
6430       return -99;
6431     }
6432   if (!v4_src_address_set && !v6_src_address_set)
6433     {
6434       errmsg ("no src addresses set\n");
6435       return -99;
6436     }
6437
6438   if (!(v4_src_address_set && v4_address_set) &&
6439       !(v6_src_address_set && v6_address_set))
6440     {
6441       errmsg ("no matching server and src addresses set\n");
6442       return -99;
6443     }
6444
6445   /* Construct the API message */
6446   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6447
6448   mp->insert_circuit_id = insert_cid;
6449   mp->is_add = is_add;
6450   mp->vrf_id = ntohl (vrf_id);
6451   if (v6_address_set)
6452     {
6453       mp->is_ipv6 = 1;
6454       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6455       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6456     }
6457   else
6458     {
6459       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6460       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6461     }
6462
6463   /* send it... */
6464   S;
6465
6466   /* Wait for a reply, return good/bad news  */
6467   W;
6468   /* NOTREACHED */
6469   return 0;
6470 }
6471
6472 static int
6473 api_dhcp_proxy_config_2 (vat_main_t * vam)
6474 {
6475   unformat_input_t *i = vam->input;
6476   vl_api_dhcp_proxy_config_2_t *mp;
6477   f64 timeout;
6478   u32 rx_vrf_id = 0;
6479   u32 server_vrf_id = 0;
6480   u8 is_add = 1;
6481   u8 insert_cid = 1;
6482   u8 v4_address_set = 0;
6483   u8 v6_address_set = 0;
6484   ip4_address_t v4address;
6485   ip6_address_t v6address;
6486   u8 v4_src_address_set = 0;
6487   u8 v6_src_address_set = 0;
6488   ip4_address_t v4srcaddress;
6489   ip6_address_t v6srcaddress;
6490
6491   /* Parse args required to build the message */
6492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6493     {
6494       if (unformat (i, "del"))
6495         is_add = 0;
6496       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6497         ;
6498       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6499         ;
6500       else if (unformat (i, "insert-cid %d", &insert_cid))
6501         ;
6502       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6503         v4_address_set = 1;
6504       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6505         v6_address_set = 1;
6506       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6507         v4_src_address_set = 1;
6508       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6509         v6_src_address_set = 1;
6510       else
6511         break;
6512     }
6513
6514   if (v4_address_set && v6_address_set)
6515     {
6516       errmsg ("both v4 and v6 server addresses set\n");
6517       return -99;
6518     }
6519   if (!v4_address_set && !v6_address_set)
6520     {
6521       errmsg ("no server addresses set\n");
6522       return -99;
6523     }
6524
6525   if (v4_src_address_set && v6_src_address_set)
6526     {
6527       errmsg ("both v4 and v6  src addresses set\n");
6528       return -99;
6529     }
6530   if (!v4_src_address_set && !v6_src_address_set)
6531     {
6532       errmsg ("no src addresses set\n");
6533       return -99;
6534     }
6535
6536   if (!(v4_src_address_set && v4_address_set) &&
6537       !(v6_src_address_set && v6_address_set))
6538     {
6539       errmsg ("no matching server and src addresses set\n");
6540       return -99;
6541     }
6542
6543   /* Construct the API message */
6544   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6545
6546   mp->insert_circuit_id = insert_cid;
6547   mp->is_add = is_add;
6548   mp->rx_vrf_id = ntohl (rx_vrf_id);
6549   mp->server_vrf_id = ntohl (server_vrf_id);
6550   if (v6_address_set)
6551     {
6552       mp->is_ipv6 = 1;
6553       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6554       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6555     }
6556   else
6557     {
6558       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6559       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6560     }
6561
6562   /* send it... */
6563   S;
6564
6565   /* Wait for a reply, return good/bad news  */
6566   W;
6567   /* NOTREACHED */
6568   return 0;
6569 }
6570
6571 static int
6572 api_dhcp_proxy_set_vss (vat_main_t * vam)
6573 {
6574   unformat_input_t *i = vam->input;
6575   vl_api_dhcp_proxy_set_vss_t *mp;
6576   f64 timeout;
6577   u8 is_ipv6 = 0;
6578   u8 is_add = 1;
6579   u32 tbl_id;
6580   u8 tbl_id_set = 0;
6581   u32 oui;
6582   u8 oui_set = 0;
6583   u32 fib_id;
6584   u8 fib_id_set = 0;
6585
6586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6587     {
6588       if (unformat (i, "tbl_id %d", &tbl_id))
6589         tbl_id_set = 1;
6590       if (unformat (i, "fib_id %d", &fib_id))
6591         fib_id_set = 1;
6592       if (unformat (i, "oui %d", &oui))
6593         oui_set = 1;
6594       else if (unformat (i, "ipv6"))
6595         is_ipv6 = 1;
6596       else if (unformat (i, "del"))
6597         is_add = 0;
6598       else
6599         {
6600           clib_warning ("parse error '%U'", format_unformat_error, i);
6601           return -99;
6602         }
6603     }
6604
6605   if (tbl_id_set == 0)
6606     {
6607       errmsg ("missing tbl id\n");
6608       return -99;
6609     }
6610
6611   if (fib_id_set == 0)
6612     {
6613       errmsg ("missing fib id\n");
6614       return -99;
6615     }
6616   if (oui_set == 0)
6617     {
6618       errmsg ("missing oui\n");
6619       return -99;
6620     }
6621
6622   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6623   mp->tbl_id = ntohl (tbl_id);
6624   mp->fib_id = ntohl (fib_id);
6625   mp->oui = ntohl (oui);
6626   mp->is_ipv6 = is_ipv6;
6627   mp->is_add = is_add;
6628
6629   S;
6630   W;
6631   /* NOTREACHED */
6632   return 0;
6633 }
6634
6635 static int
6636 api_dhcp_client_config (vat_main_t * vam)
6637 {
6638   unformat_input_t *i = vam->input;
6639   vl_api_dhcp_client_config_t *mp;
6640   f64 timeout;
6641   u32 sw_if_index;
6642   u8 sw_if_index_set = 0;
6643   u8 is_add = 1;
6644   u8 *hostname = 0;
6645   u8 disable_event = 0;
6646
6647   /* Parse args required to build the message */
6648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6649     {
6650       if (unformat (i, "del"))
6651         is_add = 0;
6652       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6653         sw_if_index_set = 1;
6654       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6655         sw_if_index_set = 1;
6656       else if (unformat (i, "hostname %s", &hostname))
6657         ;
6658       else if (unformat (i, "disable_event"))
6659         disable_event = 1;
6660       else
6661         break;
6662     }
6663
6664   if (sw_if_index_set == 0)
6665     {
6666       errmsg ("missing interface name or sw_if_index\n");
6667       return -99;
6668     }
6669
6670   if (vec_len (hostname) > 63)
6671     {
6672       errmsg ("hostname too long\n");
6673     }
6674   vec_add1 (hostname, 0);
6675
6676   /* Construct the API message */
6677   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6678
6679   mp->sw_if_index = ntohl (sw_if_index);
6680   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6681   vec_free (hostname);
6682   mp->is_add = is_add;
6683   mp->want_dhcp_event = disable_event ? 0 : 1;
6684   mp->pid = getpid ();
6685
6686   /* send it... */
6687   S;
6688
6689   /* Wait for a reply, return good/bad news  */
6690   W;
6691   /* NOTREACHED */
6692   return 0;
6693 }
6694
6695 static int
6696 api_set_ip_flow_hash (vat_main_t * vam)
6697 {
6698   unformat_input_t *i = vam->input;
6699   vl_api_set_ip_flow_hash_t *mp;
6700   f64 timeout;
6701   u32 vrf_id = 0;
6702   u8 is_ipv6 = 0;
6703   u8 vrf_id_set = 0;
6704   u8 src = 0;
6705   u8 dst = 0;
6706   u8 sport = 0;
6707   u8 dport = 0;
6708   u8 proto = 0;
6709   u8 reverse = 0;
6710
6711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6712     {
6713       if (unformat (i, "vrf %d", &vrf_id))
6714         vrf_id_set = 1;
6715       else if (unformat (i, "ipv6"))
6716         is_ipv6 = 1;
6717       else if (unformat (i, "src"))
6718         src = 1;
6719       else if (unformat (i, "dst"))
6720         dst = 1;
6721       else if (unformat (i, "sport"))
6722         sport = 1;
6723       else if (unformat (i, "dport"))
6724         dport = 1;
6725       else if (unformat (i, "proto"))
6726         proto = 1;
6727       else if (unformat (i, "reverse"))
6728         reverse = 1;
6729
6730       else
6731         {
6732           clib_warning ("parse error '%U'", format_unformat_error, i);
6733           return -99;
6734         }
6735     }
6736
6737   if (vrf_id_set == 0)
6738     {
6739       errmsg ("missing vrf id\n");
6740       return -99;
6741     }
6742
6743   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
6744   mp->src = src;
6745   mp->dst = dst;
6746   mp->sport = sport;
6747   mp->dport = dport;
6748   mp->proto = proto;
6749   mp->reverse = reverse;
6750   mp->vrf_id = ntohl (vrf_id);
6751   mp->is_ipv6 = is_ipv6;
6752
6753   S;
6754   W;
6755   /* NOTREACHED */
6756   return 0;
6757 }
6758
6759 static int
6760 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
6761 {
6762   unformat_input_t *i = vam->input;
6763   vl_api_sw_interface_ip6_enable_disable_t *mp;
6764   f64 timeout;
6765   u32 sw_if_index;
6766   u8 sw_if_index_set = 0;
6767   u8 enable = 0;
6768
6769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6770     {
6771       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6772         sw_if_index_set = 1;
6773       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6774         sw_if_index_set = 1;
6775       else if (unformat (i, "enable"))
6776         enable = 1;
6777       else if (unformat (i, "disable"))
6778         enable = 0;
6779       else
6780         {
6781           clib_warning ("parse error '%U'", format_unformat_error, i);
6782           return -99;
6783         }
6784     }
6785
6786   if (sw_if_index_set == 0)
6787     {
6788       errmsg ("missing interface name or sw_if_index\n");
6789       return -99;
6790     }
6791
6792   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
6793
6794   mp->sw_if_index = ntohl (sw_if_index);
6795   mp->enable = enable;
6796
6797   S;
6798   W;
6799   /* NOTREACHED */
6800   return 0;
6801 }
6802
6803 static int
6804 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
6805 {
6806   unformat_input_t *i = vam->input;
6807   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
6808   f64 timeout;
6809   u32 sw_if_index;
6810   u8 sw_if_index_set = 0;
6811   u32 address_length = 0;
6812   u8 v6_address_set = 0;
6813   ip6_address_t v6address;
6814
6815   /* Parse args required to build the message */
6816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6817     {
6818       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6819         sw_if_index_set = 1;
6820       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6821         sw_if_index_set = 1;
6822       else if (unformat (i, "%U/%d",
6823                          unformat_ip6_address, &v6address, &address_length))
6824         v6_address_set = 1;
6825       else
6826         break;
6827     }
6828
6829   if (sw_if_index_set == 0)
6830     {
6831       errmsg ("missing interface name or sw_if_index\n");
6832       return -99;
6833     }
6834   if (!v6_address_set)
6835     {
6836       errmsg ("no address set\n");
6837       return -99;
6838     }
6839
6840   /* Construct the API message */
6841   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
6842      sw_interface_ip6_set_link_local_address);
6843
6844   mp->sw_if_index = ntohl (sw_if_index);
6845   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6846   mp->address_length = address_length;
6847
6848   /* send it... */
6849   S;
6850
6851   /* Wait for a reply, return good/bad news  */
6852   W;
6853
6854   /* NOTREACHED */
6855   return 0;
6856 }
6857
6858
6859 static int
6860 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
6861 {
6862   unformat_input_t *i = vam->input;
6863   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
6864   f64 timeout;
6865   u32 sw_if_index;
6866   u8 sw_if_index_set = 0;
6867   u32 address_length = 0;
6868   u8 v6_address_set = 0;
6869   ip6_address_t v6address;
6870   u8 use_default = 0;
6871   u8 no_advertise = 0;
6872   u8 off_link = 0;
6873   u8 no_autoconfig = 0;
6874   u8 no_onlink = 0;
6875   u8 is_no = 0;
6876   u32 val_lifetime = 0;
6877   u32 pref_lifetime = 0;
6878
6879   /* Parse args required to build the message */
6880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6881     {
6882       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6883         sw_if_index_set = 1;
6884       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6885         sw_if_index_set = 1;
6886       else if (unformat (i, "%U/%d",
6887                          unformat_ip6_address, &v6address, &address_length))
6888         v6_address_set = 1;
6889       else if (unformat (i, "val_life %d", &val_lifetime))
6890         ;
6891       else if (unformat (i, "pref_life %d", &pref_lifetime))
6892         ;
6893       else if (unformat (i, "def"))
6894         use_default = 1;
6895       else if (unformat (i, "noadv"))
6896         no_advertise = 1;
6897       else if (unformat (i, "offl"))
6898         off_link = 1;
6899       else if (unformat (i, "noauto"))
6900         no_autoconfig = 1;
6901       else if (unformat (i, "nolink"))
6902         no_onlink = 1;
6903       else if (unformat (i, "isno"))
6904         is_no = 1;
6905       else
6906         {
6907           clib_warning ("parse error '%U'", format_unformat_error, i);
6908           return -99;
6909         }
6910     }
6911
6912   if (sw_if_index_set == 0)
6913     {
6914       errmsg ("missing interface name or sw_if_index\n");
6915       return -99;
6916     }
6917   if (!v6_address_set)
6918     {
6919       errmsg ("no address set\n");
6920       return -99;
6921     }
6922
6923   /* Construct the API message */
6924   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
6925
6926   mp->sw_if_index = ntohl (sw_if_index);
6927   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6928   mp->address_length = address_length;
6929   mp->use_default = use_default;
6930   mp->no_advertise = no_advertise;
6931   mp->off_link = off_link;
6932   mp->no_autoconfig = no_autoconfig;
6933   mp->no_onlink = no_onlink;
6934   mp->is_no = is_no;
6935   mp->val_lifetime = ntohl (val_lifetime);
6936   mp->pref_lifetime = ntohl (pref_lifetime);
6937
6938   /* send it... */
6939   S;
6940
6941   /* Wait for a reply, return good/bad news  */
6942   W;
6943
6944   /* NOTREACHED */
6945   return 0;
6946 }
6947
6948 static int
6949 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
6950 {
6951   unformat_input_t *i = vam->input;
6952   vl_api_sw_interface_ip6nd_ra_config_t *mp;
6953   f64 timeout;
6954   u32 sw_if_index;
6955   u8 sw_if_index_set = 0;
6956   u8 suppress = 0;
6957   u8 managed = 0;
6958   u8 other = 0;
6959   u8 ll_option = 0;
6960   u8 send_unicast = 0;
6961   u8 cease = 0;
6962   u8 is_no = 0;
6963   u8 default_router = 0;
6964   u32 max_interval = 0;
6965   u32 min_interval = 0;
6966   u32 lifetime = 0;
6967   u32 initial_count = 0;
6968   u32 initial_interval = 0;
6969
6970
6971   /* Parse args required to build the message */
6972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6973     {
6974       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6975         sw_if_index_set = 1;
6976       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6977         sw_if_index_set = 1;
6978       else if (unformat (i, "maxint %d", &max_interval))
6979         ;
6980       else if (unformat (i, "minint %d", &min_interval))
6981         ;
6982       else if (unformat (i, "life %d", &lifetime))
6983         ;
6984       else if (unformat (i, "count %d", &initial_count))
6985         ;
6986       else if (unformat (i, "interval %d", &initial_interval))
6987         ;
6988       else if (unformat (i, "suppress") || unformat (i, "surpress"))
6989         suppress = 1;
6990       else if (unformat (i, "managed"))
6991         managed = 1;
6992       else if (unformat (i, "other"))
6993         other = 1;
6994       else if (unformat (i, "ll"))
6995         ll_option = 1;
6996       else if (unformat (i, "send"))
6997         send_unicast = 1;
6998       else if (unformat (i, "cease"))
6999         cease = 1;
7000       else if (unformat (i, "isno"))
7001         is_no = 1;
7002       else if (unformat (i, "def"))
7003         default_router = 1;
7004       else
7005         {
7006           clib_warning ("parse error '%U'", format_unformat_error, i);
7007           return -99;
7008         }
7009     }
7010
7011   if (sw_if_index_set == 0)
7012     {
7013       errmsg ("missing interface name or sw_if_index\n");
7014       return -99;
7015     }
7016
7017   /* Construct the API message */
7018   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7019
7020   mp->sw_if_index = ntohl (sw_if_index);
7021   mp->max_interval = ntohl (max_interval);
7022   mp->min_interval = ntohl (min_interval);
7023   mp->lifetime = ntohl (lifetime);
7024   mp->initial_count = ntohl (initial_count);
7025   mp->initial_interval = ntohl (initial_interval);
7026   mp->suppress = suppress;
7027   mp->managed = managed;
7028   mp->other = other;
7029   mp->ll_option = ll_option;
7030   mp->send_unicast = send_unicast;
7031   mp->cease = cease;
7032   mp->is_no = is_no;
7033   mp->default_router = default_router;
7034
7035   /* send it... */
7036   S;
7037
7038   /* Wait for a reply, return good/bad news  */
7039   W;
7040
7041   /* NOTREACHED */
7042   return 0;
7043 }
7044
7045 static int
7046 api_set_arp_neighbor_limit (vat_main_t * vam)
7047 {
7048   unformat_input_t *i = vam->input;
7049   vl_api_set_arp_neighbor_limit_t *mp;
7050   f64 timeout;
7051   u32 arp_nbr_limit;
7052   u8 limit_set = 0;
7053   u8 is_ipv6 = 0;
7054
7055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7056     {
7057       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7058         limit_set = 1;
7059       else if (unformat (i, "ipv6"))
7060         is_ipv6 = 1;
7061       else
7062         {
7063           clib_warning ("parse error '%U'", format_unformat_error, i);
7064           return -99;
7065         }
7066     }
7067
7068   if (limit_set == 0)
7069     {
7070       errmsg ("missing limit value\n");
7071       return -99;
7072     }
7073
7074   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7075
7076   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7077   mp->is_ipv6 = is_ipv6;
7078
7079   S;
7080   W;
7081   /* NOTREACHED */
7082   return 0;
7083 }
7084
7085 static int
7086 api_l2_patch_add_del (vat_main_t * vam)
7087 {
7088   unformat_input_t *i = vam->input;
7089   vl_api_l2_patch_add_del_t *mp;
7090   f64 timeout;
7091   u32 rx_sw_if_index;
7092   u8 rx_sw_if_index_set = 0;
7093   u32 tx_sw_if_index;
7094   u8 tx_sw_if_index_set = 0;
7095   u8 is_add = 1;
7096
7097   /* Parse args required to build the message */
7098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7099     {
7100       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7101         rx_sw_if_index_set = 1;
7102       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7103         tx_sw_if_index_set = 1;
7104       else if (unformat (i, "rx"))
7105         {
7106           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7107             {
7108               if (unformat (i, "%U", unformat_sw_if_index, vam,
7109                             &rx_sw_if_index))
7110                 rx_sw_if_index_set = 1;
7111             }
7112           else
7113             break;
7114         }
7115       else if (unformat (i, "tx"))
7116         {
7117           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7118             {
7119               if (unformat (i, "%U", unformat_sw_if_index, vam,
7120                             &tx_sw_if_index))
7121                 tx_sw_if_index_set = 1;
7122             }
7123           else
7124             break;
7125         }
7126       else if (unformat (i, "del"))
7127         is_add = 0;
7128       else
7129         break;
7130     }
7131
7132   if (rx_sw_if_index_set == 0)
7133     {
7134       errmsg ("missing rx interface name or rx_sw_if_index\n");
7135       return -99;
7136     }
7137
7138   if (tx_sw_if_index_set == 0)
7139     {
7140       errmsg ("missing tx interface name or tx_sw_if_index\n");
7141       return -99;
7142     }
7143
7144   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7145
7146   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7147   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7148   mp->is_add = is_add;
7149
7150   S;
7151   W;
7152   /* NOTREACHED */
7153   return 0;
7154 }
7155
7156 static int
7157 api_ioam_enable (vat_main_t * vam)
7158 {
7159   unformat_input_t *input = vam->input;
7160   vl_api_ioam_enable_t *mp;
7161   f64 timeout;
7162   u32 id = 0;
7163   int has_trace_option = 0;
7164   int has_pow_option = 0;
7165   int has_ppc_option = 0;
7166
7167   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7168     {
7169       if (unformat (input, "trace"))
7170         has_trace_option = 1;
7171       else if (unformat (input, "pow"))
7172         has_pow_option = 1;
7173       else if (unformat (input, "ppc encap"))
7174         has_ppc_option = PPC_ENCAP;
7175       else if (unformat (input, "ppc decap"))
7176         has_ppc_option = PPC_DECAP;
7177       else if (unformat (input, "ppc none"))
7178         has_ppc_option = PPC_NONE;
7179       else
7180         break;
7181     }
7182   M (IOAM_ENABLE, ioam_enable);
7183   mp->id = htons (id);
7184   mp->trace_ppc = has_ppc_option;
7185   mp->pow_enable = has_pow_option;
7186   mp->trace_enable = has_trace_option;
7187
7188   S;
7189   W;
7190
7191   return (0);
7192
7193 }
7194
7195
7196 static int
7197 api_ioam_disable (vat_main_t * vam)
7198 {
7199   vl_api_ioam_disable_t *mp;
7200   f64 timeout;
7201
7202   M (IOAM_DISABLE, ioam_disable);
7203   S;
7204   W;
7205   return 0;
7206 }
7207
7208 static int
7209 api_sr_tunnel_add_del (vat_main_t * vam)
7210 {
7211   unformat_input_t *i = vam->input;
7212   vl_api_sr_tunnel_add_del_t *mp;
7213   f64 timeout;
7214   int is_del = 0;
7215   int pl_index;
7216   ip6_address_t src_address;
7217   int src_address_set = 0;
7218   ip6_address_t dst_address;
7219   u32 dst_mask_width;
7220   int dst_address_set = 0;
7221   u16 flags = 0;
7222   u32 rx_table_id = 0;
7223   u32 tx_table_id = 0;
7224   ip6_address_t *segments = 0;
7225   ip6_address_t *this_seg;
7226   ip6_address_t *tags = 0;
7227   ip6_address_t *this_tag;
7228   ip6_address_t next_address, tag;
7229   u8 *name = 0;
7230   u8 *policy_name = 0;
7231
7232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7233     {
7234       if (unformat (i, "del"))
7235         is_del = 1;
7236       else if (unformat (i, "name %s", &name))
7237         ;
7238       else if (unformat (i, "policy %s", &policy_name))
7239         ;
7240       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7241         ;
7242       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7243         ;
7244       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7245         src_address_set = 1;
7246       else if (unformat (i, "dst %U/%d",
7247                          unformat_ip6_address, &dst_address, &dst_mask_width))
7248         dst_address_set = 1;
7249       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7250         {
7251           vec_add2 (segments, this_seg, 1);
7252           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7253                        sizeof (*this_seg));
7254         }
7255       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7256         {
7257           vec_add2 (tags, this_tag, 1);
7258           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7259         }
7260       else if (unformat (i, "clean"))
7261         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7262       else if (unformat (i, "protected"))
7263         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7264       else if (unformat (i, "InPE %d", &pl_index))
7265         {
7266           if (pl_index <= 0 || pl_index > 4)
7267             {
7268             pl_index_range_error:
7269               errmsg ("pl index %d out of range\n", pl_index);
7270               return -99;
7271             }
7272           flags |=
7273             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7274         }
7275       else if (unformat (i, "EgPE %d", &pl_index))
7276         {
7277           if (pl_index <= 0 || pl_index > 4)
7278             goto pl_index_range_error;
7279           flags |=
7280             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7281         }
7282       else if (unformat (i, "OrgSrc %d", &pl_index))
7283         {
7284           if (pl_index <= 0 || pl_index > 4)
7285             goto pl_index_range_error;
7286           flags |=
7287             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7288         }
7289       else
7290         break;
7291     }
7292
7293   if (!src_address_set)
7294     {
7295       errmsg ("src address required\n");
7296       return -99;
7297     }
7298
7299   if (!dst_address_set)
7300     {
7301       errmsg ("dst address required\n");
7302       return -99;
7303     }
7304
7305   if (!segments)
7306     {
7307       errmsg ("at least one sr segment required\n");
7308       return -99;
7309     }
7310
7311   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7312       vec_len (segments) * sizeof (ip6_address_t)
7313       + vec_len (tags) * sizeof (ip6_address_t));
7314
7315   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7316   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7317   mp->dst_mask_width = dst_mask_width;
7318   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7319   mp->n_segments = vec_len (segments);
7320   mp->n_tags = vec_len (tags);
7321   mp->is_add = is_del == 0;
7322   clib_memcpy (mp->segs_and_tags, segments,
7323                vec_len (segments) * sizeof (ip6_address_t));
7324   clib_memcpy (mp->segs_and_tags +
7325                vec_len (segments) * sizeof (ip6_address_t), tags,
7326                vec_len (tags) * sizeof (ip6_address_t));
7327
7328   mp->outer_vrf_id = ntohl (rx_table_id);
7329   mp->inner_vrf_id = ntohl (tx_table_id);
7330   memcpy (mp->name, name, vec_len (name));
7331   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7332
7333   vec_free (segments);
7334   vec_free (tags);
7335
7336   S;
7337   W;
7338   /* NOTREACHED */
7339 }
7340
7341 static int
7342 api_sr_policy_add_del (vat_main_t * vam)
7343 {
7344   unformat_input_t *input = vam->input;
7345   vl_api_sr_policy_add_del_t *mp;
7346   f64 timeout;
7347   int is_del = 0;
7348   u8 *name = 0;
7349   u8 *tunnel_name = 0;
7350   u8 **tunnel_names = 0;
7351
7352   int name_set = 0;
7353   int tunnel_set = 0;
7354   int j = 0;
7355   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7356   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7357
7358   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7359     {
7360       if (unformat (input, "del"))
7361         is_del = 1;
7362       else if (unformat (input, "name %s", &name))
7363         name_set = 1;
7364       else if (unformat (input, "tunnel %s", &tunnel_name))
7365         {
7366           if (tunnel_name)
7367             {
7368               vec_add1 (tunnel_names, tunnel_name);
7369               /* For serializer:
7370                  - length = #bytes to store in serial vector
7371                  - +1 = byte to store that length
7372                */
7373               tunnel_names_length += (vec_len (tunnel_name) + 1);
7374               tunnel_set = 1;
7375               tunnel_name = 0;
7376             }
7377         }
7378       else
7379         break;
7380     }
7381
7382   if (!name_set)
7383     {
7384       errmsg ("policy name required\n");
7385       return -99;
7386     }
7387
7388   if ((!tunnel_set) && (!is_del))
7389     {
7390       errmsg ("tunnel name required\n");
7391       return -99;
7392     }
7393
7394   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7395
7396
7397
7398   mp->is_add = !is_del;
7399
7400   memcpy (mp->name, name, vec_len (name));
7401   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7402   u8 *serial_orig = 0;
7403   vec_validate (serial_orig, tunnel_names_length);
7404   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7405   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7406
7407   for (j = 0; j < vec_len (tunnel_names); j++)
7408     {
7409       tun_name_len = vec_len (tunnel_names[j]);
7410       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7411       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7412       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7413       serial_orig += tun_name_len;      // Advance past the copy
7414     }
7415   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7416
7417   vec_free (tunnel_names);
7418   vec_free (tunnel_name);
7419
7420   S;
7421   W;
7422   /* NOTREACHED */
7423 }
7424
7425 static int
7426 api_sr_multicast_map_add_del (vat_main_t * vam)
7427 {
7428   unformat_input_t *input = vam->input;
7429   vl_api_sr_multicast_map_add_del_t *mp;
7430   f64 timeout;
7431   int is_del = 0;
7432   ip6_address_t multicast_address;
7433   u8 *policy_name = 0;
7434   int multicast_address_set = 0;
7435
7436   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7437     {
7438       if (unformat (input, "del"))
7439         is_del = 1;
7440       else
7441         if (unformat
7442             (input, "address %U", unformat_ip6_address, &multicast_address))
7443         multicast_address_set = 1;
7444       else if (unformat (input, "sr-policy %s", &policy_name))
7445         ;
7446       else
7447         break;
7448     }
7449
7450   if (!is_del && !policy_name)
7451     {
7452       errmsg ("sr-policy name required\n");
7453       return -99;
7454     }
7455
7456
7457   if (!multicast_address_set)
7458     {
7459       errmsg ("address required\n");
7460       return -99;
7461     }
7462
7463   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7464
7465   mp->is_add = !is_del;
7466   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7467   clib_memcpy (mp->multicast_address, &multicast_address,
7468                sizeof (mp->multicast_address));
7469
7470
7471   vec_free (policy_name);
7472
7473   S;
7474   W;
7475   /* NOTREACHED */
7476 }
7477
7478
7479 #define foreach_ip4_proto_field                 \
7480 _(src_address)                                  \
7481 _(dst_address)                                  \
7482 _(tos)                                          \
7483 _(length)                                       \
7484 _(fragment_id)                                  \
7485 _(ttl)                                          \
7486 _(protocol)                                     \
7487 _(checksum)
7488
7489 uword
7490 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7491 {
7492   u8 **maskp = va_arg (*args, u8 **);
7493   u8 *mask = 0;
7494   u8 found_something = 0;
7495   ip4_header_t *ip;
7496
7497 #define _(a) u8 a=0;
7498   foreach_ip4_proto_field;
7499 #undef _
7500   u8 version = 0;
7501   u8 hdr_length = 0;
7502
7503
7504   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7505     {
7506       if (unformat (input, "version"))
7507         version = 1;
7508       else if (unformat (input, "hdr_length"))
7509         hdr_length = 1;
7510       else if (unformat (input, "src"))
7511         src_address = 1;
7512       else if (unformat (input, "dst"))
7513         dst_address = 1;
7514       else if (unformat (input, "proto"))
7515         protocol = 1;
7516
7517 #define _(a) else if (unformat (input, #a)) a=1;
7518       foreach_ip4_proto_field
7519 #undef _
7520         else
7521         break;
7522     }
7523
7524 #define _(a) found_something += a;
7525   foreach_ip4_proto_field;
7526 #undef _
7527
7528   if (found_something == 0)
7529     return 0;
7530
7531   vec_validate (mask, sizeof (*ip) - 1);
7532
7533   ip = (ip4_header_t *) mask;
7534
7535 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7536   foreach_ip4_proto_field;
7537 #undef _
7538
7539   ip->ip_version_and_header_length = 0;
7540
7541   if (version)
7542     ip->ip_version_and_header_length |= 0xF0;
7543
7544   if (hdr_length)
7545     ip->ip_version_and_header_length |= 0x0F;
7546
7547   *maskp = mask;
7548   return 1;
7549 }
7550
7551 #define foreach_ip6_proto_field                 \
7552 _(src_address)                                  \
7553 _(dst_address)                                  \
7554 _(payload_length)                               \
7555 _(hop_limit)                                    \
7556 _(protocol)
7557
7558 uword
7559 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7560 {
7561   u8 **maskp = va_arg (*args, u8 **);
7562   u8 *mask = 0;
7563   u8 found_something = 0;
7564   ip6_header_t *ip;
7565   u32 ip_version_traffic_class_and_flow_label;
7566
7567 #define _(a) u8 a=0;
7568   foreach_ip6_proto_field;
7569 #undef _
7570   u8 version = 0;
7571   u8 traffic_class = 0;
7572   u8 flow_label = 0;
7573
7574   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7575     {
7576       if (unformat (input, "version"))
7577         version = 1;
7578       else if (unformat (input, "traffic-class"))
7579         traffic_class = 1;
7580       else if (unformat (input, "flow-label"))
7581         flow_label = 1;
7582       else if (unformat (input, "src"))
7583         src_address = 1;
7584       else if (unformat (input, "dst"))
7585         dst_address = 1;
7586       else if (unformat (input, "proto"))
7587         protocol = 1;
7588
7589 #define _(a) else if (unformat (input, #a)) a=1;
7590       foreach_ip6_proto_field
7591 #undef _
7592         else
7593         break;
7594     }
7595
7596 #define _(a) found_something += a;
7597   foreach_ip6_proto_field;
7598 #undef _
7599
7600   if (found_something == 0)
7601     return 0;
7602
7603   vec_validate (mask, sizeof (*ip) - 1);
7604
7605   ip = (ip6_header_t *) mask;
7606
7607 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7608   foreach_ip6_proto_field;
7609 #undef _
7610
7611   ip_version_traffic_class_and_flow_label = 0;
7612
7613   if (version)
7614     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7615
7616   if (traffic_class)
7617     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7618
7619   if (flow_label)
7620     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7621
7622   ip->ip_version_traffic_class_and_flow_label =
7623     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7624
7625   *maskp = mask;
7626   return 1;
7627 }
7628
7629 uword
7630 unformat_l3_mask (unformat_input_t * input, va_list * args)
7631 {
7632   u8 **maskp = va_arg (*args, u8 **);
7633
7634   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7635     {
7636       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7637         return 1;
7638       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7639         return 1;
7640       else
7641         break;
7642     }
7643   return 0;
7644 }
7645
7646 uword
7647 unformat_l2_mask (unformat_input_t * input, va_list * args)
7648 {
7649   u8 **maskp = va_arg (*args, u8 **);
7650   u8 *mask = 0;
7651   u8 src = 0;
7652   u8 dst = 0;
7653   u8 proto = 0;
7654   u8 tag1 = 0;
7655   u8 tag2 = 0;
7656   u8 ignore_tag1 = 0;
7657   u8 ignore_tag2 = 0;
7658   u8 cos1 = 0;
7659   u8 cos2 = 0;
7660   u8 dot1q = 0;
7661   u8 dot1ad = 0;
7662   int len = 14;
7663
7664   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7665     {
7666       if (unformat (input, "src"))
7667         src = 1;
7668       else if (unformat (input, "dst"))
7669         dst = 1;
7670       else if (unformat (input, "proto"))
7671         proto = 1;
7672       else if (unformat (input, "tag1"))
7673         tag1 = 1;
7674       else if (unformat (input, "tag2"))
7675         tag2 = 1;
7676       else if (unformat (input, "ignore-tag1"))
7677         ignore_tag1 = 1;
7678       else if (unformat (input, "ignore-tag2"))
7679         ignore_tag2 = 1;
7680       else if (unformat (input, "cos1"))
7681         cos1 = 1;
7682       else if (unformat (input, "cos2"))
7683         cos2 = 1;
7684       else if (unformat (input, "dot1q"))
7685         dot1q = 1;
7686       else if (unformat (input, "dot1ad"))
7687         dot1ad = 1;
7688       else
7689         break;
7690     }
7691   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7692        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7693     return 0;
7694
7695   if (tag1 || ignore_tag1 || cos1 || dot1q)
7696     len = 18;
7697   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7698     len = 22;
7699
7700   vec_validate (mask, len - 1);
7701
7702   if (dst)
7703     memset (mask, 0xff, 6);
7704
7705   if (src)
7706     memset (mask + 6, 0xff, 6);
7707
7708   if (tag2 || dot1ad)
7709     {
7710       /* inner vlan tag */
7711       if (tag2)
7712         {
7713           mask[19] = 0xff;
7714           mask[18] = 0x0f;
7715         }
7716       if (cos2)
7717         mask[18] |= 0xe0;
7718       if (proto)
7719         mask[21] = mask[20] = 0xff;
7720       if (tag1)
7721         {
7722           mask[15] = 0xff;
7723           mask[14] = 0x0f;
7724         }
7725       if (cos1)
7726         mask[14] |= 0xe0;
7727       *maskp = mask;
7728       return 1;
7729     }
7730   if (tag1 | dot1q)
7731     {
7732       if (tag1)
7733         {
7734           mask[15] = 0xff;
7735           mask[14] = 0x0f;
7736         }
7737       if (cos1)
7738         mask[14] |= 0xe0;
7739       if (proto)
7740         mask[16] = mask[17] = 0xff;
7741
7742       *maskp = mask;
7743       return 1;
7744     }
7745   if (cos2)
7746     mask[18] |= 0xe0;
7747   if (cos1)
7748     mask[14] |= 0xe0;
7749   if (proto)
7750     mask[12] = mask[13] = 0xff;
7751
7752   *maskp = mask;
7753   return 1;
7754 }
7755
7756 uword
7757 unformat_classify_mask (unformat_input_t * input, va_list * args)
7758 {
7759   u8 **maskp = va_arg (*args, u8 **);
7760   u32 *skipp = va_arg (*args, u32 *);
7761   u32 *matchp = va_arg (*args, u32 *);
7762   u32 match;
7763   u8 *mask = 0;
7764   u8 *l2 = 0;
7765   u8 *l3 = 0;
7766   int i;
7767
7768   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7769     {
7770       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7771         ;
7772       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7773         ;
7774       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7775         ;
7776       else
7777         break;
7778     }
7779
7780   if (mask || l2 || l3)
7781     {
7782       if (l2 || l3)
7783         {
7784           /* "With a free Ethernet header in every package" */
7785           if (l2 == 0)
7786             vec_validate (l2, 13);
7787           mask = l2;
7788           if (vec_len (l3))
7789             {
7790               vec_append (mask, l3);
7791               vec_free (l3);
7792             }
7793         }
7794
7795       /* Scan forward looking for the first significant mask octet */
7796       for (i = 0; i < vec_len (mask); i++)
7797         if (mask[i])
7798           break;
7799
7800       /* compute (skip, match) params */
7801       *skipp = i / sizeof (u32x4);
7802       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7803
7804       /* Pad mask to an even multiple of the vector size */
7805       while (vec_len (mask) % sizeof (u32x4))
7806         vec_add1 (mask, 0);
7807
7808       match = vec_len (mask) / sizeof (u32x4);
7809
7810       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7811         {
7812           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7813           if (*tmp || *(tmp + 1))
7814             break;
7815           match--;
7816         }
7817       if (match == 0)
7818         clib_warning ("BUG: match 0");
7819
7820       _vec_len (mask) = match * sizeof (u32x4);
7821
7822       *matchp = match;
7823       *maskp = mask;
7824
7825       return 1;
7826     }
7827
7828   return 0;
7829 }
7830
7831 #define foreach_l2_next                         \
7832 _(drop, DROP)                                   \
7833 _(ethernet, ETHERNET_INPUT)                     \
7834 _(ip4, IP4_INPUT)                               \
7835 _(ip6, IP6_INPUT)
7836
7837 uword
7838 unformat_l2_next_index (unformat_input_t * input, va_list * args)
7839 {
7840   u32 *miss_next_indexp = va_arg (*args, u32 *);
7841   u32 next_index = 0;
7842   u32 tmp;
7843
7844 #define _(n,N) \
7845   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
7846   foreach_l2_next;
7847 #undef _
7848
7849   if (unformat (input, "%d", &tmp))
7850     {
7851       next_index = tmp;
7852       goto out;
7853     }
7854
7855   return 0;
7856
7857 out:
7858   *miss_next_indexp = next_index;
7859   return 1;
7860 }
7861
7862 #define foreach_ip_next                         \
7863 _(miss, MISS)                                   \
7864 _(drop, DROP)                                   \
7865 _(local, LOCAL)                                 \
7866 _(rewrite, REWRITE)
7867
7868 uword
7869 unformat_ip_next_index (unformat_input_t * input, va_list * args)
7870 {
7871   u32 *miss_next_indexp = va_arg (*args, u32 *);
7872   u32 next_index = 0;
7873   u32 tmp;
7874
7875 #define _(n,N) \
7876   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7877   foreach_ip_next;
7878 #undef _
7879
7880   if (unformat (input, "%d", &tmp))
7881     {
7882       next_index = tmp;
7883       goto out;
7884     }
7885
7886   return 0;
7887
7888 out:
7889   *miss_next_indexp = next_index;
7890   return 1;
7891 }
7892
7893 #define foreach_acl_next                        \
7894 _(deny, DENY)
7895
7896 uword
7897 unformat_acl_next_index (unformat_input_t * input, va_list * args)
7898 {
7899   u32 *miss_next_indexp = va_arg (*args, u32 *);
7900   u32 next_index = 0;
7901   u32 tmp;
7902
7903 #define _(n,N) \
7904   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7905   foreach_acl_next;
7906 #undef _
7907
7908   if (unformat (input, "permit"))
7909     {
7910       next_index = ~0;
7911       goto out;
7912     }
7913   else if (unformat (input, "%d", &tmp))
7914     {
7915       next_index = tmp;
7916       goto out;
7917     }
7918
7919   return 0;
7920
7921 out:
7922   *miss_next_indexp = next_index;
7923   return 1;
7924 }
7925
7926 uword
7927 unformat_policer_precolor (unformat_input_t * input, va_list * args)
7928 {
7929   u32 *r = va_arg (*args, u32 *);
7930
7931   if (unformat (input, "conform-color"))
7932     *r = POLICE_CONFORM;
7933   else if (unformat (input, "exceed-color"))
7934     *r = POLICE_EXCEED;
7935   else
7936     return 0;
7937
7938   return 1;
7939 }
7940
7941 static int
7942 api_classify_add_del_table (vat_main_t * vam)
7943 {
7944   unformat_input_t *i = vam->input;
7945   vl_api_classify_add_del_table_t *mp;
7946
7947   u32 nbuckets = 2;
7948   u32 skip = ~0;
7949   u32 match = ~0;
7950   int is_add = 1;
7951   u32 table_index = ~0;
7952   u32 next_table_index = ~0;
7953   u32 miss_next_index = ~0;
7954   u32 memory_size = 32 << 20;
7955   u8 *mask = 0;
7956   f64 timeout;
7957
7958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7959     {
7960       if (unformat (i, "del"))
7961         is_add = 0;
7962       else if (unformat (i, "buckets %d", &nbuckets))
7963         ;
7964       else if (unformat (i, "memory_size %d", &memory_size))
7965         ;
7966       else if (unformat (i, "skip %d", &skip))
7967         ;
7968       else if (unformat (i, "match %d", &match))
7969         ;
7970       else if (unformat (i, "table %d", &table_index))
7971         ;
7972       else if (unformat (i, "mask %U", unformat_classify_mask,
7973                          &mask, &skip, &match))
7974         ;
7975       else if (unformat (i, "next-table %d", &next_table_index))
7976         ;
7977       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
7978                          &miss_next_index))
7979         ;
7980       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
7981                          &miss_next_index))
7982         ;
7983       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
7984                          &miss_next_index))
7985         ;
7986       else
7987         break;
7988     }
7989
7990   if (is_add && mask == 0)
7991     {
7992       errmsg ("Mask required\n");
7993       return -99;
7994     }
7995
7996   if (is_add && skip == ~0)
7997     {
7998       errmsg ("skip count required\n");
7999       return -99;
8000     }
8001
8002   if (is_add && match == ~0)
8003     {
8004       errmsg ("match count required\n");
8005       return -99;
8006     }
8007
8008   if (!is_add && table_index == ~0)
8009     {
8010       errmsg ("table index required for delete\n");
8011       return -99;
8012     }
8013
8014   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8015
8016   mp->is_add = is_add;
8017   mp->table_index = ntohl (table_index);
8018   mp->nbuckets = ntohl (nbuckets);
8019   mp->memory_size = ntohl (memory_size);
8020   mp->skip_n_vectors = ntohl (skip);
8021   mp->match_n_vectors = ntohl (match);
8022   mp->next_table_index = ntohl (next_table_index);
8023   mp->miss_next_index = ntohl (miss_next_index);
8024   clib_memcpy (mp->mask, mask, vec_len (mask));
8025
8026   vec_free (mask);
8027
8028   S;
8029   W;
8030   /* NOTREACHED */
8031 }
8032
8033 uword
8034 unformat_ip4_match (unformat_input_t * input, va_list * args)
8035 {
8036   u8 **matchp = va_arg (*args, u8 **);
8037   u8 *match = 0;
8038   ip4_header_t *ip;
8039   int version = 0;
8040   u32 version_val;
8041   int hdr_length = 0;
8042   u32 hdr_length_val;
8043   int src = 0, dst = 0;
8044   ip4_address_t src_val, dst_val;
8045   int proto = 0;
8046   u32 proto_val;
8047   int tos = 0;
8048   u32 tos_val;
8049   int length = 0;
8050   u32 length_val;
8051   int fragment_id = 0;
8052   u32 fragment_id_val;
8053   int ttl = 0;
8054   int ttl_val;
8055   int checksum = 0;
8056   u32 checksum_val;
8057
8058   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8059     {
8060       if (unformat (input, "version %d", &version_val))
8061         version = 1;
8062       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8063         hdr_length = 1;
8064       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8065         src = 1;
8066       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8067         dst = 1;
8068       else if (unformat (input, "proto %d", &proto_val))
8069         proto = 1;
8070       else if (unformat (input, "tos %d", &tos_val))
8071         tos = 1;
8072       else if (unformat (input, "length %d", &length_val))
8073         length = 1;
8074       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8075         fragment_id = 1;
8076       else if (unformat (input, "ttl %d", &ttl_val))
8077         ttl = 1;
8078       else if (unformat (input, "checksum %d", &checksum_val))
8079         checksum = 1;
8080       else
8081         break;
8082     }
8083
8084   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8085       + ttl + checksum == 0)
8086     return 0;
8087
8088   /*
8089    * Aligned because we use the real comparison functions
8090    */
8091   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8092
8093   ip = (ip4_header_t *) match;
8094
8095   /* These are realistically matched in practice */
8096   if (src)
8097     ip->src_address.as_u32 = src_val.as_u32;
8098
8099   if (dst)
8100     ip->dst_address.as_u32 = dst_val.as_u32;
8101
8102   if (proto)
8103     ip->protocol = proto_val;
8104
8105
8106   /* These are not, but they're included for completeness */
8107   if (version)
8108     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8109
8110   if (hdr_length)
8111     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8112
8113   if (tos)
8114     ip->tos = tos_val;
8115
8116   if (length)
8117     ip->length = length_val;
8118
8119   if (ttl)
8120     ip->ttl = ttl_val;
8121
8122   if (checksum)
8123     ip->checksum = checksum_val;
8124
8125   *matchp = match;
8126   return 1;
8127 }
8128
8129 uword
8130 unformat_ip6_match (unformat_input_t * input, va_list * args)
8131 {
8132   u8 **matchp = va_arg (*args, u8 **);
8133   u8 *match = 0;
8134   ip6_header_t *ip;
8135   int version = 0;
8136   u32 version_val;
8137   u8 traffic_class = 0;
8138   u32 traffic_class_val = 0;
8139   u8 flow_label = 0;
8140   u8 flow_label_val;
8141   int src = 0, dst = 0;
8142   ip6_address_t src_val, dst_val;
8143   int proto = 0;
8144   u32 proto_val;
8145   int payload_length = 0;
8146   u32 payload_length_val;
8147   int hop_limit = 0;
8148   int hop_limit_val;
8149   u32 ip_version_traffic_class_and_flow_label;
8150
8151   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8152     {
8153       if (unformat (input, "version %d", &version_val))
8154         version = 1;
8155       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8156         traffic_class = 1;
8157       else if (unformat (input, "flow_label %d", &flow_label_val))
8158         flow_label = 1;
8159       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8160         src = 1;
8161       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8162         dst = 1;
8163       else if (unformat (input, "proto %d", &proto_val))
8164         proto = 1;
8165       else if (unformat (input, "payload_length %d", &payload_length_val))
8166         payload_length = 1;
8167       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8168         hop_limit = 1;
8169       else
8170         break;
8171     }
8172
8173   if (version + traffic_class + flow_label + src + dst + proto +
8174       payload_length + hop_limit == 0)
8175     return 0;
8176
8177   /*
8178    * Aligned because we use the real comparison functions
8179    */
8180   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8181
8182   ip = (ip6_header_t *) match;
8183
8184   if (src)
8185     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8186
8187   if (dst)
8188     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8189
8190   if (proto)
8191     ip->protocol = proto_val;
8192
8193   ip_version_traffic_class_and_flow_label = 0;
8194
8195   if (version)
8196     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8197
8198   if (traffic_class)
8199     ip_version_traffic_class_and_flow_label |=
8200       (traffic_class_val & 0xFF) << 20;
8201
8202   if (flow_label)
8203     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8204
8205   ip->ip_version_traffic_class_and_flow_label =
8206     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8207
8208   if (payload_length)
8209     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8210
8211   if (hop_limit)
8212     ip->hop_limit = hop_limit_val;
8213
8214   *matchp = match;
8215   return 1;
8216 }
8217
8218 uword
8219 unformat_l3_match (unformat_input_t * input, va_list * args)
8220 {
8221   u8 **matchp = va_arg (*args, u8 **);
8222
8223   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8224     {
8225       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8226         return 1;
8227       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8228         return 1;
8229       else
8230         break;
8231     }
8232   return 0;
8233 }
8234
8235 uword
8236 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8237 {
8238   u8 *tagp = va_arg (*args, u8 *);
8239   u32 tag;
8240
8241   if (unformat (input, "%d", &tag))
8242     {
8243       tagp[0] = (tag >> 8) & 0x0F;
8244       tagp[1] = tag & 0xFF;
8245       return 1;
8246     }
8247
8248   return 0;
8249 }
8250
8251 uword
8252 unformat_l2_match (unformat_input_t * input, va_list * args)
8253 {
8254   u8 **matchp = va_arg (*args, u8 **);
8255   u8 *match = 0;
8256   u8 src = 0;
8257   u8 src_val[6];
8258   u8 dst = 0;
8259   u8 dst_val[6];
8260   u8 proto = 0;
8261   u16 proto_val;
8262   u8 tag1 = 0;
8263   u8 tag1_val[2];
8264   u8 tag2 = 0;
8265   u8 tag2_val[2];
8266   int len = 14;
8267   u8 ignore_tag1 = 0;
8268   u8 ignore_tag2 = 0;
8269   u8 cos1 = 0;
8270   u8 cos2 = 0;
8271   u32 cos1_val = 0;
8272   u32 cos2_val = 0;
8273
8274   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8275     {
8276       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8277         src = 1;
8278       else
8279         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8280         dst = 1;
8281       else if (unformat (input, "proto %U",
8282                          unformat_ethernet_type_host_byte_order, &proto_val))
8283         proto = 1;
8284       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8285         tag1 = 1;
8286       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8287         tag2 = 1;
8288       else if (unformat (input, "ignore-tag1"))
8289         ignore_tag1 = 1;
8290       else if (unformat (input, "ignore-tag2"))
8291         ignore_tag2 = 1;
8292       else if (unformat (input, "cos1 %d", &cos1_val))
8293         cos1 = 1;
8294       else if (unformat (input, "cos2 %d", &cos2_val))
8295         cos2 = 1;
8296       else
8297         break;
8298     }
8299   if ((src + dst + proto + tag1 + tag2 +
8300        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8301     return 0;
8302
8303   if (tag1 || ignore_tag1 || cos1)
8304     len = 18;
8305   if (tag2 || ignore_tag2 || cos2)
8306     len = 22;
8307
8308   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8309
8310   if (dst)
8311     clib_memcpy (match, dst_val, 6);
8312
8313   if (src)
8314     clib_memcpy (match + 6, src_val, 6);
8315
8316   if (tag2)
8317     {
8318       /* inner vlan tag */
8319       match[19] = tag2_val[1];
8320       match[18] = tag2_val[0];
8321       if (cos2)
8322         match[18] |= (cos2_val & 0x7) << 5;
8323       if (proto)
8324         {
8325           match[21] = proto_val & 0xff;
8326           match[20] = proto_val >> 8;
8327         }
8328       if (tag1)
8329         {
8330           match[15] = tag1_val[1];
8331           match[14] = tag1_val[0];
8332         }
8333       if (cos1)
8334         match[14] |= (cos1_val & 0x7) << 5;
8335       *matchp = match;
8336       return 1;
8337     }
8338   if (tag1)
8339     {
8340       match[15] = tag1_val[1];
8341       match[14] = tag1_val[0];
8342       if (proto)
8343         {
8344           match[17] = proto_val & 0xff;
8345           match[16] = proto_val >> 8;
8346         }
8347       if (cos1)
8348         match[14] |= (cos1_val & 0x7) << 5;
8349
8350       *matchp = match;
8351       return 1;
8352     }
8353   if (cos2)
8354     match[18] |= (cos2_val & 0x7) << 5;
8355   if (cos1)
8356     match[14] |= (cos1_val & 0x7) << 5;
8357   if (proto)
8358     {
8359       match[13] = proto_val & 0xff;
8360       match[12] = proto_val >> 8;
8361     }
8362
8363   *matchp = match;
8364   return 1;
8365 }
8366
8367
8368 uword
8369 unformat_classify_match (unformat_input_t * input, va_list * args)
8370 {
8371   u8 **matchp = va_arg (*args, u8 **);
8372   u32 skip_n_vectors = va_arg (*args, u32);
8373   u32 match_n_vectors = va_arg (*args, u32);
8374
8375   u8 *match = 0;
8376   u8 *l2 = 0;
8377   u8 *l3 = 0;
8378
8379   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8380     {
8381       if (unformat (input, "hex %U", unformat_hex_string, &match))
8382         ;
8383       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8384         ;
8385       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8386         ;
8387       else
8388         break;
8389     }
8390
8391   if (match || l2 || l3)
8392     {
8393       if (l2 || l3)
8394         {
8395           /* "Win a free Ethernet header in every packet" */
8396           if (l2 == 0)
8397             vec_validate_aligned (l2, 13, sizeof (u32x4));
8398           match = l2;
8399           if (vec_len (l3))
8400             {
8401               vec_append_aligned (match, l3, sizeof (u32x4));
8402               vec_free (l3);
8403             }
8404         }
8405
8406       /* Make sure the vector is big enough even if key is all 0's */
8407       vec_validate_aligned
8408         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8409          sizeof (u32x4));
8410
8411       /* Set size, include skipped vectors */
8412       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8413
8414       *matchp = match;
8415
8416       return 1;
8417     }
8418
8419   return 0;
8420 }
8421
8422 static int
8423 api_classify_add_del_session (vat_main_t * vam)
8424 {
8425   unformat_input_t *i = vam->input;
8426   vl_api_classify_add_del_session_t *mp;
8427   int is_add = 1;
8428   u32 table_index = ~0;
8429   u32 hit_next_index = ~0;
8430   u32 opaque_index = ~0;
8431   u8 *match = 0;
8432   i32 advance = 0;
8433   f64 timeout;
8434   u32 skip_n_vectors = 0;
8435   u32 match_n_vectors = 0;
8436
8437   /*
8438    * Warning: you have to supply skip_n and match_n
8439    * because the API client cant simply look at the classify
8440    * table object.
8441    */
8442
8443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8444     {
8445       if (unformat (i, "del"))
8446         is_add = 0;
8447       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8448                          &hit_next_index))
8449         ;
8450       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8451                          &hit_next_index))
8452         ;
8453       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8454                          &hit_next_index))
8455         ;
8456       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8457         ;
8458       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8459         ;
8460       else if (unformat (i, "opaque-index %d", &opaque_index))
8461         ;
8462       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8463         ;
8464       else if (unformat (i, "match_n %d", &match_n_vectors))
8465         ;
8466       else if (unformat (i, "match %U", unformat_classify_match,
8467                          &match, skip_n_vectors, match_n_vectors))
8468         ;
8469       else if (unformat (i, "advance %d", &advance))
8470         ;
8471       else if (unformat (i, "table-index %d", &table_index))
8472         ;
8473       else
8474         break;
8475     }
8476
8477   if (table_index == ~0)
8478     {
8479       errmsg ("Table index required\n");
8480       return -99;
8481     }
8482
8483   if (is_add && match == 0)
8484     {
8485       errmsg ("Match value required\n");
8486       return -99;
8487     }
8488
8489   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8490
8491   mp->is_add = is_add;
8492   mp->table_index = ntohl (table_index);
8493   mp->hit_next_index = ntohl (hit_next_index);
8494   mp->opaque_index = ntohl (opaque_index);
8495   mp->advance = ntohl (advance);
8496   clib_memcpy (mp->match, match, vec_len (match));
8497   vec_free (match);
8498
8499   S;
8500   W;
8501   /* NOTREACHED */
8502 }
8503
8504 static int
8505 api_classify_set_interface_ip_table (vat_main_t * vam)
8506 {
8507   unformat_input_t *i = vam->input;
8508   vl_api_classify_set_interface_ip_table_t *mp;
8509   f64 timeout;
8510   u32 sw_if_index;
8511   int sw_if_index_set;
8512   u32 table_index = ~0;
8513   u8 is_ipv6 = 0;
8514
8515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8516     {
8517       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8518         sw_if_index_set = 1;
8519       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8520         sw_if_index_set = 1;
8521       else if (unformat (i, "table %d", &table_index))
8522         ;
8523       else
8524         {
8525           clib_warning ("parse error '%U'", format_unformat_error, i);
8526           return -99;
8527         }
8528     }
8529
8530   if (sw_if_index_set == 0)
8531     {
8532       errmsg ("missing interface name or sw_if_index\n");
8533       return -99;
8534     }
8535
8536
8537   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8538
8539   mp->sw_if_index = ntohl (sw_if_index);
8540   mp->table_index = ntohl (table_index);
8541   mp->is_ipv6 = is_ipv6;
8542
8543   S;
8544   W;
8545   /* NOTREACHED */
8546   return 0;
8547 }
8548
8549 static int
8550 api_classify_set_interface_l2_tables (vat_main_t * vam)
8551 {
8552   unformat_input_t *i = vam->input;
8553   vl_api_classify_set_interface_l2_tables_t *mp;
8554   f64 timeout;
8555   u32 sw_if_index;
8556   int sw_if_index_set;
8557   u32 ip4_table_index = ~0;
8558   u32 ip6_table_index = ~0;
8559   u32 other_table_index = ~0;
8560   u32 is_input = 1;
8561
8562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8563     {
8564       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8565         sw_if_index_set = 1;
8566       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8567         sw_if_index_set = 1;
8568       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8569         ;
8570       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8571         ;
8572       else if (unformat (i, "other-table %d", &other_table_index))
8573         ;
8574       else if (unformat (i, "is-input %d", &is_input))
8575         ;
8576       else
8577         {
8578           clib_warning ("parse error '%U'", format_unformat_error, i);
8579           return -99;
8580         }
8581     }
8582
8583   if (sw_if_index_set == 0)
8584     {
8585       errmsg ("missing interface name or sw_if_index\n");
8586       return -99;
8587     }
8588
8589
8590   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8591
8592   mp->sw_if_index = ntohl (sw_if_index);
8593   mp->ip4_table_index = ntohl (ip4_table_index);
8594   mp->ip6_table_index = ntohl (ip6_table_index);
8595   mp->other_table_index = ntohl (other_table_index);
8596   mp->is_input = (u8) is_input;
8597
8598   S;
8599   W;
8600   /* NOTREACHED */
8601   return 0;
8602 }
8603
8604 static int
8605 api_set_ipfix_exporter (vat_main_t * vam)
8606 {
8607   unformat_input_t *i = vam->input;
8608   vl_api_set_ipfix_exporter_t *mp;
8609   ip4_address_t collector_address;
8610   u8 collector_address_set = 0;
8611   u32 collector_port = ~0;
8612   ip4_address_t src_address;
8613   u8 src_address_set = 0;
8614   u32 vrf_id = ~0;
8615   u32 path_mtu = ~0;
8616   u32 template_interval = ~0;
8617   u8 udp_checksum = 0;
8618   f64 timeout;
8619
8620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8621     {
8622       if (unformat (i, "collector_address %U", unformat_ip4_address,
8623                     &collector_address))
8624         collector_address_set = 1;
8625       else if (unformat (i, "collector_port %d", &collector_port))
8626         ;
8627       else if (unformat (i, "src_address %U", unformat_ip4_address,
8628                          &src_address))
8629         src_address_set = 1;
8630       else if (unformat (i, "vrf_id %d", &vrf_id))
8631         ;
8632       else if (unformat (i, "path_mtu %d", &path_mtu))
8633         ;
8634       else if (unformat (i, "template_interval %d", &template_interval))
8635         ;
8636       else if (unformat (i, "udp_checksum"))
8637         udp_checksum = 1;
8638       else
8639         break;
8640     }
8641
8642   if (collector_address_set == 0)
8643     {
8644       errmsg ("collector_address required\n");
8645       return -99;
8646     }
8647
8648   if (src_address_set == 0)
8649     {
8650       errmsg ("src_address required\n");
8651       return -99;
8652     }
8653
8654   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
8655
8656   memcpy (mp->collector_address, collector_address.data,
8657           sizeof (collector_address.data));
8658   mp->collector_port = htons ((u16) collector_port);
8659   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8660   mp->vrf_id = htonl (vrf_id);
8661   mp->path_mtu = htonl (path_mtu);
8662   mp->template_interval = htonl (template_interval);
8663   mp->udp_checksum = udp_checksum;
8664
8665   S;
8666   W;
8667   /* NOTREACHED */
8668 }
8669
8670 static int
8671 api_set_ipfix_classify_stream (vat_main_t * vam)
8672 {
8673   unformat_input_t *i = vam->input;
8674   vl_api_set_ipfix_classify_stream_t *mp;
8675   u32 domain_id = 0;
8676   u32 src_port = UDP_DST_PORT_ipfix;
8677   f64 timeout;
8678
8679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8680     {
8681       if (unformat (i, "domain %d", &domain_id))
8682         ;
8683       else if (unformat (i, "src_port %d", &src_port))
8684         ;
8685       else
8686         {
8687           errmsg ("unknown input `%U'", format_unformat_error, i);
8688           return -99;
8689         }
8690     }
8691
8692   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
8693
8694   mp->domain_id = htonl (domain_id);
8695   mp->src_port = htons ((u16) src_port);
8696
8697   S;
8698   W;
8699   /* NOTREACHED */
8700 }
8701
8702 static int
8703 api_ipfix_classify_table_add_del (vat_main_t * vam)
8704 {
8705   unformat_input_t *i = vam->input;
8706   vl_api_ipfix_classify_table_add_del_t *mp;
8707   int is_add = -1;
8708   u32 classify_table_index = ~0;
8709   u8 ip_version = 0;
8710   u8 transport_protocol = 255;
8711   f64 timeout;
8712
8713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8714     {
8715       if (unformat (i, "add"))
8716         is_add = 1;
8717       else if (unformat (i, "del"))
8718         is_add = 0;
8719       else if (unformat (i, "table %d", &classify_table_index))
8720         ;
8721       else if (unformat (i, "ip4"))
8722         ip_version = 4;
8723       else if (unformat (i, "ip6"))
8724         ip_version = 6;
8725       else if (unformat (i, "tcp"))
8726         transport_protocol = 6;
8727       else if (unformat (i, "udp"))
8728         transport_protocol = 17;
8729       else
8730         {
8731           errmsg ("unknown input `%U'", format_unformat_error, i);
8732           return -99;
8733         }
8734     }
8735
8736   if (is_add == -1)
8737     {
8738       errmsg ("expecting: add|del");
8739       return -99;
8740     }
8741   if (classify_table_index == ~0)
8742     {
8743       errmsg ("classifier table not specified");
8744       return -99;
8745     }
8746   if (ip_version == 0)
8747     {
8748       errmsg ("IP version not specified");
8749       return -99;
8750     }
8751
8752   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
8753
8754   mp->is_add = is_add;
8755   mp->table_id = htonl (classify_table_index);
8756   mp->ip_version = ip_version;
8757   mp->transport_protocol = transport_protocol;
8758
8759   S;
8760   W;
8761   /* NOTREACHED */
8762 }
8763
8764 static int
8765 api_get_node_index (vat_main_t * vam)
8766 {
8767   unformat_input_t *i = vam->input;
8768   vl_api_get_node_index_t *mp;
8769   f64 timeout;
8770   u8 *name = 0;
8771
8772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8773     {
8774       if (unformat (i, "node %s", &name))
8775         ;
8776       else
8777         break;
8778     }
8779   if (name == 0)
8780     {
8781       errmsg ("node name required\n");
8782       return -99;
8783     }
8784   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8785     {
8786       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8787       return -99;
8788     }
8789
8790   M (GET_NODE_INDEX, get_node_index);
8791   clib_memcpy (mp->node_name, name, vec_len (name));
8792   vec_free (name);
8793
8794   S;
8795   W;
8796   /* NOTREACHED */
8797   return 0;
8798 }
8799
8800 static int
8801 api_get_next_index (vat_main_t * vam)
8802 {
8803   unformat_input_t *i = vam->input;
8804   vl_api_get_next_index_t *mp;
8805   f64 timeout;
8806   u8 *node_name = 0, *next_node_name = 0;
8807
8808   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8809     {
8810       if (unformat (i, "node-name %s", &node_name))
8811         ;
8812       else if (unformat (i, "next-node-name %s", &next_node_name))
8813         break;
8814     }
8815
8816   if (node_name == 0)
8817     {
8818       errmsg ("node name required\n");
8819       return -99;
8820     }
8821   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
8822     {
8823       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8824       return -99;
8825     }
8826
8827   if (next_node_name == 0)
8828     {
8829       errmsg ("next node name required\n");
8830       return -99;
8831     }
8832   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
8833     {
8834       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
8835       return -99;
8836     }
8837
8838   M (GET_NEXT_INDEX, get_next_index);
8839   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
8840   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
8841   vec_free (node_name);
8842   vec_free (next_node_name);
8843
8844   S;
8845   W;
8846   /* NOTREACHED */
8847   return 0;
8848 }
8849
8850 static int
8851 api_add_node_next (vat_main_t * vam)
8852 {
8853   unformat_input_t *i = vam->input;
8854   vl_api_add_node_next_t *mp;
8855   f64 timeout;
8856   u8 *name = 0;
8857   u8 *next = 0;
8858
8859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8860     {
8861       if (unformat (i, "node %s", &name))
8862         ;
8863       else if (unformat (i, "next %s", &next))
8864         ;
8865       else
8866         break;
8867     }
8868   if (name == 0)
8869     {
8870       errmsg ("node name required\n");
8871       return -99;
8872     }
8873   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8874     {
8875       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8876       return -99;
8877     }
8878   if (next == 0)
8879     {
8880       errmsg ("next node required\n");
8881       return -99;
8882     }
8883   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
8884     {
8885       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
8886       return -99;
8887     }
8888
8889   M (ADD_NODE_NEXT, add_node_next);
8890   clib_memcpy (mp->node_name, name, vec_len (name));
8891   clib_memcpy (mp->next_name, next, vec_len (next));
8892   vec_free (name);
8893   vec_free (next);
8894
8895   S;
8896   W;
8897   /* NOTREACHED */
8898   return 0;
8899 }
8900
8901 static int
8902 api_l2tpv3_create_tunnel (vat_main_t * vam)
8903 {
8904   unformat_input_t *i = vam->input;
8905   ip6_address_t client_address, our_address;
8906   int client_address_set = 0;
8907   int our_address_set = 0;
8908   u32 local_session_id = 0;
8909   u32 remote_session_id = 0;
8910   u64 local_cookie = 0;
8911   u64 remote_cookie = 0;
8912   u8 l2_sublayer_present = 0;
8913   vl_api_l2tpv3_create_tunnel_t *mp;
8914   f64 timeout;
8915
8916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8917     {
8918       if (unformat (i, "client_address %U", unformat_ip6_address,
8919                     &client_address))
8920         client_address_set = 1;
8921       else if (unformat (i, "our_address %U", unformat_ip6_address,
8922                          &our_address))
8923         our_address_set = 1;
8924       else if (unformat (i, "local_session_id %d", &local_session_id))
8925         ;
8926       else if (unformat (i, "remote_session_id %d", &remote_session_id))
8927         ;
8928       else if (unformat (i, "local_cookie %lld", &local_cookie))
8929         ;
8930       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
8931         ;
8932       else if (unformat (i, "l2-sublayer-present"))
8933         l2_sublayer_present = 1;
8934       else
8935         break;
8936     }
8937
8938   if (client_address_set == 0)
8939     {
8940       errmsg ("client_address required\n");
8941       return -99;
8942     }
8943
8944   if (our_address_set == 0)
8945     {
8946       errmsg ("our_address required\n");
8947       return -99;
8948     }
8949
8950   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
8951
8952   clib_memcpy (mp->client_address, client_address.as_u8,
8953                sizeof (mp->client_address));
8954
8955   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
8956
8957   mp->local_session_id = ntohl (local_session_id);
8958   mp->remote_session_id = ntohl (remote_session_id);
8959   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
8960   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
8961   mp->l2_sublayer_present = l2_sublayer_present;
8962   mp->is_ipv6 = 1;
8963
8964   S;
8965   W;
8966   /* NOTREACHED */
8967   return 0;
8968 }
8969
8970 static int
8971 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
8972 {
8973   unformat_input_t *i = vam->input;
8974   u32 sw_if_index;
8975   u8 sw_if_index_set = 0;
8976   u64 new_local_cookie = 0;
8977   u64 new_remote_cookie = 0;
8978   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
8979   f64 timeout;
8980
8981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8982     {
8983       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8984         sw_if_index_set = 1;
8985       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8986         sw_if_index_set = 1;
8987       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
8988         ;
8989       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
8990         ;
8991       else
8992         break;
8993     }
8994
8995   if (sw_if_index_set == 0)
8996     {
8997       errmsg ("missing interface name or sw_if_index\n");
8998       return -99;
8999     }
9000
9001   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9002
9003   mp->sw_if_index = ntohl (sw_if_index);
9004   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9005   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9006
9007   S;
9008   W;
9009   /* NOTREACHED */
9010   return 0;
9011 }
9012
9013 static int
9014 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9015 {
9016   unformat_input_t *i = vam->input;
9017   vl_api_l2tpv3_interface_enable_disable_t *mp;
9018   f64 timeout;
9019   u32 sw_if_index;
9020   u8 sw_if_index_set = 0;
9021   u8 enable_disable = 1;
9022
9023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9024     {
9025       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9026         sw_if_index_set = 1;
9027       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9028         sw_if_index_set = 1;
9029       else if (unformat (i, "enable"))
9030         enable_disable = 1;
9031       else if (unformat (i, "disable"))
9032         enable_disable = 0;
9033       else
9034         break;
9035     }
9036
9037   if (sw_if_index_set == 0)
9038     {
9039       errmsg ("missing interface name or sw_if_index\n");
9040       return -99;
9041     }
9042
9043   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9044
9045   mp->sw_if_index = ntohl (sw_if_index);
9046   mp->enable_disable = enable_disable;
9047
9048   S;
9049   W;
9050   /* NOTREACHED */
9051   return 0;
9052 }
9053
9054 static int
9055 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9056 {
9057   unformat_input_t *i = vam->input;
9058   vl_api_l2tpv3_set_lookup_key_t *mp;
9059   f64 timeout;
9060   u8 key = ~0;
9061
9062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9063     {
9064       if (unformat (i, "lookup_v6_src"))
9065         key = L2T_LOOKUP_SRC_ADDRESS;
9066       else if (unformat (i, "lookup_v6_dst"))
9067         key = L2T_LOOKUP_DST_ADDRESS;
9068       else if (unformat (i, "lookup_session_id"))
9069         key = L2T_LOOKUP_SESSION_ID;
9070       else
9071         break;
9072     }
9073
9074   if (key == (u8) ~ 0)
9075     {
9076       errmsg ("l2tp session lookup key unset\n");
9077       return -99;
9078     }
9079
9080   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9081
9082   mp->key = key;
9083
9084   S;
9085   W;
9086   /* NOTREACHED */
9087   return 0;
9088 }
9089
9090 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9091   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9092 {
9093   vat_main_t *vam = &vat_main;
9094
9095   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9096            format_ip6_address, mp->our_address,
9097            format_ip6_address, mp->client_address,
9098            clib_net_to_host_u32 (mp->sw_if_index));
9099
9100   fformat (vam->ofp,
9101            "   local cookies %016llx %016llx remote cookie %016llx\n",
9102            clib_net_to_host_u64 (mp->local_cookie[0]),
9103            clib_net_to_host_u64 (mp->local_cookie[1]),
9104            clib_net_to_host_u64 (mp->remote_cookie));
9105
9106   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9107            clib_net_to_host_u32 (mp->local_session_id),
9108            clib_net_to_host_u32 (mp->remote_session_id));
9109
9110   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9111            mp->l2_sublayer_present ? "preset" : "absent");
9112
9113 }
9114
9115 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9116   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9117 {
9118   vat_main_t *vam = &vat_main;
9119   vat_json_node_t *node = NULL;
9120   struct in6_addr addr;
9121
9122   if (VAT_JSON_ARRAY != vam->json_tree.type)
9123     {
9124       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9125       vat_json_init_array (&vam->json_tree);
9126     }
9127   node = vat_json_array_add (&vam->json_tree);
9128
9129   vat_json_init_object (node);
9130
9131   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9132   vat_json_object_add_ip6 (node, "our_address", addr);
9133   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9134   vat_json_object_add_ip6 (node, "client_address", addr);
9135
9136   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9137   vat_json_init_array (lc);
9138   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9139   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9140   vat_json_object_add_uint (node, "remote_cookie",
9141                             clib_net_to_host_u64 (mp->remote_cookie));
9142
9143   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9144   vat_json_object_add_uint (node, "local_session_id",
9145                             clib_net_to_host_u32 (mp->local_session_id));
9146   vat_json_object_add_uint (node, "remote_session_id",
9147                             clib_net_to_host_u32 (mp->remote_session_id));
9148   vat_json_object_add_string_copy (node, "l2_sublayer",
9149                                    mp->l2_sublayer_present ? (u8 *) "present"
9150                                    : (u8 *) "absent");
9151 }
9152
9153 static int
9154 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9155 {
9156   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9157   f64 timeout;
9158
9159   /* Get list of l2tpv3-tunnel interfaces */
9160   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9161   S;
9162
9163   /* Use a control ping for synchronization */
9164   {
9165     vl_api_control_ping_t *mp;
9166     M (CONTROL_PING, control_ping);
9167     S;
9168   }
9169   W;
9170 }
9171
9172
9173 static void vl_api_sw_interface_tap_details_t_handler
9174   (vl_api_sw_interface_tap_details_t * mp)
9175 {
9176   vat_main_t *vam = &vat_main;
9177
9178   fformat (vam->ofp, "%-16s %d\n",
9179            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9180 }
9181
9182 static void vl_api_sw_interface_tap_details_t_handler_json
9183   (vl_api_sw_interface_tap_details_t * mp)
9184 {
9185   vat_main_t *vam = &vat_main;
9186   vat_json_node_t *node = NULL;
9187
9188   if (VAT_JSON_ARRAY != vam->json_tree.type)
9189     {
9190       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9191       vat_json_init_array (&vam->json_tree);
9192     }
9193   node = vat_json_array_add (&vam->json_tree);
9194
9195   vat_json_init_object (node);
9196   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9197   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9198 }
9199
9200 static int
9201 api_sw_interface_tap_dump (vat_main_t * vam)
9202 {
9203   vl_api_sw_interface_tap_dump_t *mp;
9204   f64 timeout;
9205
9206   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9207   /* Get list of tap interfaces */
9208   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9209   S;
9210
9211   /* Use a control ping for synchronization */
9212   {
9213     vl_api_control_ping_t *mp;
9214     M (CONTROL_PING, control_ping);
9215     S;
9216   }
9217   W;
9218 }
9219
9220 static uword unformat_vxlan_decap_next
9221   (unformat_input_t * input, va_list * args)
9222 {
9223   u32 *result = va_arg (*args, u32 *);
9224   u32 tmp;
9225
9226   if (unformat (input, "drop"))
9227     *result = VXLAN_INPUT_NEXT_DROP;
9228   else if (unformat (input, "ip4"))
9229     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9230   else if (unformat (input, "ip6"))
9231     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9232   else if (unformat (input, "l2"))
9233     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9234   else if (unformat (input, "%d", &tmp))
9235     *result = tmp;
9236   else
9237     return 0;
9238   return 1;
9239 }
9240
9241 static int
9242 api_vxlan_add_del_tunnel (vat_main_t * vam)
9243 {
9244   unformat_input_t *line_input = vam->input;
9245   vl_api_vxlan_add_del_tunnel_t *mp;
9246   f64 timeout;
9247   ip4_address_t src4, dst4;
9248   ip6_address_t src6, dst6;
9249   u8 is_add = 1;
9250   u8 ipv4_set = 0, ipv6_set = 0;
9251   u8 src_set = 0;
9252   u8 dst_set = 0;
9253   u32 encap_vrf_id = 0;
9254   u32 decap_next_index = ~0;
9255   u32 vni = 0;
9256
9257   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9258     {
9259       if (unformat (line_input, "del"))
9260         is_add = 0;
9261       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9262         {
9263           ipv4_set = 1;
9264           src_set = 1;
9265         }
9266       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9267         {
9268           ipv4_set = 1;
9269           dst_set = 1;
9270         }
9271       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9272         {
9273           ipv6_set = 1;
9274           src_set = 1;
9275         }
9276       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9277         {
9278           ipv6_set = 1;
9279           dst_set = 1;
9280         }
9281       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9282         ;
9283       else if (unformat (line_input, "decap-next %U",
9284                          unformat_vxlan_decap_next, &decap_next_index))
9285         ;
9286       else if (unformat (line_input, "vni %d", &vni))
9287         ;
9288       else
9289         {
9290           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9291           return -99;
9292         }
9293     }
9294
9295   if (src_set == 0)
9296     {
9297       errmsg ("tunnel src address not specified\n");
9298       return -99;
9299     }
9300   if (dst_set == 0)
9301     {
9302       errmsg ("tunnel dst address not specified\n");
9303       return -99;
9304     }
9305
9306   if (ipv4_set && ipv6_set)
9307     {
9308       errmsg ("both IPv4 and IPv6 addresses specified");
9309       return -99;
9310     }
9311
9312   if ((vni == 0) || (vni >> 24))
9313     {
9314       errmsg ("vni not specified or out of range\n");
9315       return -99;
9316     }
9317
9318   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9319
9320   if (ipv6_set)
9321     {
9322       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9323       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9324     }
9325   else
9326     {
9327       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9328       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9329     }
9330   mp->encap_vrf_id = ntohl (encap_vrf_id);
9331   mp->decap_next_index = ntohl (decap_next_index);
9332   mp->vni = ntohl (vni);
9333   mp->is_add = is_add;
9334   mp->is_ipv6 = ipv6_set;
9335
9336   S;
9337   W;
9338   /* NOTREACHED */
9339   return 0;
9340 }
9341
9342 static void vl_api_vxlan_tunnel_details_t_handler
9343   (vl_api_vxlan_tunnel_details_t * mp)
9344 {
9345   vat_main_t *vam = &vat_main;
9346
9347   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9348            ntohl (mp->sw_if_index),
9349            format_ip46_address, &(mp->src_address[0]),
9350            IP46_TYPE_ANY,
9351            format_ip46_address, &(mp->dst_address[0]),
9352            IP46_TYPE_ANY,
9353            ntohl (mp->encap_vrf_id),
9354            ntohl (mp->decap_next_index), ntohl (mp->vni));
9355 }
9356
9357 static void vl_api_vxlan_tunnel_details_t_handler_json
9358   (vl_api_vxlan_tunnel_details_t * mp)
9359 {
9360   vat_main_t *vam = &vat_main;
9361   vat_json_node_t *node = NULL;
9362   struct in_addr ip4;
9363   struct in6_addr ip6;
9364
9365   if (VAT_JSON_ARRAY != vam->json_tree.type)
9366     {
9367       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9368       vat_json_init_array (&vam->json_tree);
9369     }
9370   node = vat_json_array_add (&vam->json_tree);
9371
9372   vat_json_init_object (node);
9373   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9374   if (mp->is_ipv6)
9375     {
9376       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9377       vat_json_object_add_ip6 (node, "src_address", ip6);
9378       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9379       vat_json_object_add_ip6 (node, "dst_address", ip6);
9380     }
9381   else
9382     {
9383       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9384       vat_json_object_add_ip4 (node, "src_address", ip4);
9385       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9386       vat_json_object_add_ip4 (node, "dst_address", ip4);
9387     }
9388   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9389   vat_json_object_add_uint (node, "decap_next_index",
9390                             ntohl (mp->decap_next_index));
9391   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9392   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9393 }
9394
9395 static int
9396 api_vxlan_tunnel_dump (vat_main_t * vam)
9397 {
9398   unformat_input_t *i = vam->input;
9399   vl_api_vxlan_tunnel_dump_t *mp;
9400   f64 timeout;
9401   u32 sw_if_index;
9402   u8 sw_if_index_set = 0;
9403
9404   /* Parse args required to build the message */
9405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9406     {
9407       if (unformat (i, "sw_if_index %d", &sw_if_index))
9408         sw_if_index_set = 1;
9409       else
9410         break;
9411     }
9412
9413   if (sw_if_index_set == 0)
9414     {
9415       sw_if_index = ~0;
9416     }
9417
9418   if (!vam->json_output)
9419     {
9420       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9421                "sw_if_index", "src_address", "dst_address",
9422                "encap_vrf_id", "decap_next_index", "vni");
9423     }
9424
9425   /* Get list of vxlan-tunnel interfaces */
9426   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9427
9428   mp->sw_if_index = htonl (sw_if_index);
9429
9430   S;
9431
9432   /* Use a control ping for synchronization */
9433   {
9434     vl_api_control_ping_t *mp;
9435     M (CONTROL_PING, control_ping);
9436     S;
9437   }
9438   W;
9439 }
9440
9441 static int
9442 api_gre_add_del_tunnel (vat_main_t * vam)
9443 {
9444   unformat_input_t *line_input = vam->input;
9445   vl_api_gre_add_del_tunnel_t *mp;
9446   f64 timeout;
9447   ip4_address_t src4, dst4;
9448   u8 is_add = 1;
9449   u8 src_set = 0;
9450   u8 dst_set = 0;
9451   u32 outer_fib_id = 0;
9452
9453   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9454     {
9455       if (unformat (line_input, "del"))
9456         is_add = 0;
9457       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9458         src_set = 1;
9459       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9460         dst_set = 1;
9461       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9462         ;
9463       else
9464         {
9465           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9466           return -99;
9467         }
9468     }
9469
9470   if (src_set == 0)
9471     {
9472       errmsg ("tunnel src address not specified\n");
9473       return -99;
9474     }
9475   if (dst_set == 0)
9476     {
9477       errmsg ("tunnel dst address not specified\n");
9478       return -99;
9479     }
9480
9481
9482   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9483
9484   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9485   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9486   mp->outer_fib_id = ntohl (outer_fib_id);
9487   mp->is_add = is_add;
9488
9489   S;
9490   W;
9491   /* NOTREACHED */
9492   return 0;
9493 }
9494
9495 static void vl_api_gre_tunnel_details_t_handler
9496   (vl_api_gre_tunnel_details_t * mp)
9497 {
9498   vat_main_t *vam = &vat_main;
9499
9500   fformat (vam->ofp, "%11d%15U%15U%14d\n",
9501            ntohl (mp->sw_if_index),
9502            format_ip4_address, &mp->src_address,
9503            format_ip4_address, &mp->dst_address, ntohl (mp->outer_fib_id));
9504 }
9505
9506 static void vl_api_gre_tunnel_details_t_handler_json
9507   (vl_api_gre_tunnel_details_t * mp)
9508 {
9509   vat_main_t *vam = &vat_main;
9510   vat_json_node_t *node = NULL;
9511   struct in_addr ip4;
9512
9513   if (VAT_JSON_ARRAY != vam->json_tree.type)
9514     {
9515       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9516       vat_json_init_array (&vam->json_tree);
9517     }
9518   node = vat_json_array_add (&vam->json_tree);
9519
9520   vat_json_init_object (node);
9521   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9522   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9523   vat_json_object_add_ip4 (node, "src_address", ip4);
9524   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9525   vat_json_object_add_ip4 (node, "dst_address", ip4);
9526   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9527 }
9528
9529 static int
9530 api_gre_tunnel_dump (vat_main_t * vam)
9531 {
9532   unformat_input_t *i = vam->input;
9533   vl_api_gre_tunnel_dump_t *mp;
9534   f64 timeout;
9535   u32 sw_if_index;
9536   u8 sw_if_index_set = 0;
9537
9538   /* Parse args required to build the message */
9539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9540     {
9541       if (unformat (i, "sw_if_index %d", &sw_if_index))
9542         sw_if_index_set = 1;
9543       else
9544         break;
9545     }
9546
9547   if (sw_if_index_set == 0)
9548     {
9549       sw_if_index = ~0;
9550     }
9551
9552   if (!vam->json_output)
9553     {
9554       fformat (vam->ofp, "%11s%15s%15s%14s\n",
9555                "sw_if_index", "src_address", "dst_address", "outer_fib_id");
9556     }
9557
9558   /* Get list of gre-tunnel interfaces */
9559   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9560
9561   mp->sw_if_index = htonl (sw_if_index);
9562
9563   S;
9564
9565   /* Use a control ping for synchronization */
9566   {
9567     vl_api_control_ping_t *mp;
9568     M (CONTROL_PING, control_ping);
9569     S;
9570   }
9571   W;
9572 }
9573
9574 static int
9575 api_l2_fib_clear_table (vat_main_t * vam)
9576 {
9577 //  unformat_input_t * i = vam->input;
9578   vl_api_l2_fib_clear_table_t *mp;
9579   f64 timeout;
9580
9581   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9582
9583   S;
9584   W;
9585   /* NOTREACHED */
9586   return 0;
9587 }
9588
9589 static int
9590 api_l2_interface_efp_filter (vat_main_t * vam)
9591 {
9592   unformat_input_t *i = vam->input;
9593   vl_api_l2_interface_efp_filter_t *mp;
9594   f64 timeout;
9595   u32 sw_if_index;
9596   u8 enable = 1;
9597   u8 sw_if_index_set = 0;
9598
9599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9600     {
9601       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9602         sw_if_index_set = 1;
9603       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9604         sw_if_index_set = 1;
9605       else if (unformat (i, "enable"))
9606         enable = 1;
9607       else if (unformat (i, "disable"))
9608         enable = 0;
9609       else
9610         {
9611           clib_warning ("parse error '%U'", format_unformat_error, i);
9612           return -99;
9613         }
9614     }
9615
9616   if (sw_if_index_set == 0)
9617     {
9618       errmsg ("missing sw_if_index\n");
9619       return -99;
9620     }
9621
9622   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9623
9624   mp->sw_if_index = ntohl (sw_if_index);
9625   mp->enable_disable = enable;
9626
9627   S;
9628   W;
9629   /* NOTREACHED */
9630   return 0;
9631 }
9632
9633 #define foreach_vtr_op                          \
9634 _("disable",  L2_VTR_DISABLED)                  \
9635 _("push-1",  L2_VTR_PUSH_1)                     \
9636 _("push-2",  L2_VTR_PUSH_2)                     \
9637 _("pop-1",  L2_VTR_POP_1)                       \
9638 _("pop-2",  L2_VTR_POP_2)                       \
9639 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9640 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9641 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9642 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9643
9644 static int
9645 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9646 {
9647   unformat_input_t *i = vam->input;
9648   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9649   f64 timeout;
9650   u32 sw_if_index;
9651   u8 sw_if_index_set = 0;
9652   u8 vtr_op_set = 0;
9653   u32 vtr_op = 0;
9654   u32 push_dot1q = 1;
9655   u32 tag1 = ~0;
9656   u32 tag2 = ~0;
9657
9658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9659     {
9660       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9661         sw_if_index_set = 1;
9662       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9663         sw_if_index_set = 1;
9664       else if (unformat (i, "vtr_op %d", &vtr_op))
9665         vtr_op_set = 1;
9666 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9667       foreach_vtr_op
9668 #undef _
9669         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9670         ;
9671       else if (unformat (i, "tag1 %d", &tag1))
9672         ;
9673       else if (unformat (i, "tag2 %d", &tag2))
9674         ;
9675       else
9676         {
9677           clib_warning ("parse error '%U'", format_unformat_error, i);
9678           return -99;
9679         }
9680     }
9681
9682   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9683     {
9684       errmsg ("missing vtr operation or sw_if_index\n");
9685       return -99;
9686     }
9687
9688   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
9689     mp->sw_if_index = ntohl (sw_if_index);
9690   mp->vtr_op = ntohl (vtr_op);
9691   mp->push_dot1q = ntohl (push_dot1q);
9692   mp->tag1 = ntohl (tag1);
9693   mp->tag2 = ntohl (tag2);
9694
9695   S;
9696   W;
9697   /* NOTREACHED */
9698   return 0;
9699 }
9700
9701 static int
9702 api_create_vhost_user_if (vat_main_t * vam)
9703 {
9704   unformat_input_t *i = vam->input;
9705   vl_api_create_vhost_user_if_t *mp;
9706   f64 timeout;
9707   u8 *file_name;
9708   u8 is_server = 0;
9709   u8 file_name_set = 0;
9710   u32 custom_dev_instance = ~0;
9711   u8 hwaddr[6];
9712   u8 use_custom_mac = 0;
9713
9714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9715     {
9716       if (unformat (i, "socket %s", &file_name))
9717         {
9718           file_name_set = 1;
9719         }
9720       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9721         ;
9722       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9723         use_custom_mac = 1;
9724       else if (unformat (i, "server"))
9725         is_server = 1;
9726       else
9727         break;
9728     }
9729
9730   if (file_name_set == 0)
9731     {
9732       errmsg ("missing socket file name\n");
9733       return -99;
9734     }
9735
9736   if (vec_len (file_name) > 255)
9737     {
9738       errmsg ("socket file name too long\n");
9739       return -99;
9740     }
9741   vec_add1 (file_name, 0);
9742
9743   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
9744
9745   mp->is_server = is_server;
9746   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9747   vec_free (file_name);
9748   if (custom_dev_instance != ~0)
9749     {
9750       mp->renumber = 1;
9751       mp->custom_dev_instance = ntohl (custom_dev_instance);
9752     }
9753   mp->use_custom_mac = use_custom_mac;
9754   clib_memcpy (mp->mac_address, hwaddr, 6);
9755
9756   S;
9757   W;
9758   /* NOTREACHED */
9759   return 0;
9760 }
9761
9762 static int
9763 api_modify_vhost_user_if (vat_main_t * vam)
9764 {
9765   unformat_input_t *i = vam->input;
9766   vl_api_modify_vhost_user_if_t *mp;
9767   f64 timeout;
9768   u8 *file_name;
9769   u8 is_server = 0;
9770   u8 file_name_set = 0;
9771   u32 custom_dev_instance = ~0;
9772   u8 sw_if_index_set = 0;
9773   u32 sw_if_index = (u32) ~ 0;
9774
9775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9776     {
9777       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9778         sw_if_index_set = 1;
9779       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9780         sw_if_index_set = 1;
9781       else if (unformat (i, "socket %s", &file_name))
9782         {
9783           file_name_set = 1;
9784         }
9785       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9786         ;
9787       else if (unformat (i, "server"))
9788         is_server = 1;
9789       else
9790         break;
9791     }
9792
9793   if (sw_if_index_set == 0)
9794     {
9795       errmsg ("missing sw_if_index or interface name\n");
9796       return -99;
9797     }
9798
9799   if (file_name_set == 0)
9800     {
9801       errmsg ("missing socket file name\n");
9802       return -99;
9803     }
9804
9805   if (vec_len (file_name) > 255)
9806     {
9807       errmsg ("socket file name too long\n");
9808       return -99;
9809     }
9810   vec_add1 (file_name, 0);
9811
9812   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
9813
9814   mp->sw_if_index = ntohl (sw_if_index);
9815   mp->is_server = is_server;
9816   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9817   vec_free (file_name);
9818   if (custom_dev_instance != ~0)
9819     {
9820       mp->renumber = 1;
9821       mp->custom_dev_instance = ntohl (custom_dev_instance);
9822     }
9823
9824   S;
9825   W;
9826   /* NOTREACHED */
9827   return 0;
9828 }
9829
9830 static int
9831 api_delete_vhost_user_if (vat_main_t * vam)
9832 {
9833   unformat_input_t *i = vam->input;
9834   vl_api_delete_vhost_user_if_t *mp;
9835   f64 timeout;
9836   u32 sw_if_index = ~0;
9837   u8 sw_if_index_set = 0;
9838
9839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9840     {
9841       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9842         sw_if_index_set = 1;
9843       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9844         sw_if_index_set = 1;
9845       else
9846         break;
9847     }
9848
9849   if (sw_if_index_set == 0)
9850     {
9851       errmsg ("missing sw_if_index or interface name\n");
9852       return -99;
9853     }
9854
9855
9856   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
9857
9858   mp->sw_if_index = ntohl (sw_if_index);
9859
9860   S;
9861   W;
9862   /* NOTREACHED */
9863   return 0;
9864 }
9865
9866 static void vl_api_sw_interface_vhost_user_details_t_handler
9867   (vl_api_sw_interface_vhost_user_details_t * mp)
9868 {
9869   vat_main_t *vam = &vat_main;
9870
9871   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
9872            (char *) mp->interface_name,
9873            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
9874            clib_net_to_host_u64 (mp->features), mp->is_server,
9875            ntohl (mp->num_regions), (char *) mp->sock_filename);
9876   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
9877 }
9878
9879 static void vl_api_sw_interface_vhost_user_details_t_handler_json
9880   (vl_api_sw_interface_vhost_user_details_t * mp)
9881 {
9882   vat_main_t *vam = &vat_main;
9883   vat_json_node_t *node = NULL;
9884
9885   if (VAT_JSON_ARRAY != vam->json_tree.type)
9886     {
9887       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9888       vat_json_init_array (&vam->json_tree);
9889     }
9890   node = vat_json_array_add (&vam->json_tree);
9891
9892   vat_json_init_object (node);
9893   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9894   vat_json_object_add_string_copy (node, "interface_name",
9895                                    mp->interface_name);
9896   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
9897                             ntohl (mp->virtio_net_hdr_sz));
9898   vat_json_object_add_uint (node, "features",
9899                             clib_net_to_host_u64 (mp->features));
9900   vat_json_object_add_uint (node, "is_server", mp->is_server);
9901   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
9902   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
9903   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
9904 }
9905
9906 static int
9907 api_sw_interface_vhost_user_dump (vat_main_t * vam)
9908 {
9909   vl_api_sw_interface_vhost_user_dump_t *mp;
9910   f64 timeout;
9911   fformat (vam->ofp,
9912            "Interface name           idx hdr_sz features server regions filename\n");
9913
9914   /* Get list of vhost-user interfaces */
9915   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
9916   S;
9917
9918   /* Use a control ping for synchronization */
9919   {
9920     vl_api_control_ping_t *mp;
9921     M (CONTROL_PING, control_ping);
9922     S;
9923   }
9924   W;
9925 }
9926
9927 static int
9928 api_show_version (vat_main_t * vam)
9929 {
9930   vl_api_show_version_t *mp;
9931   f64 timeout;
9932
9933   M (SHOW_VERSION, show_version);
9934
9935   S;
9936   W;
9937   /* NOTREACHED */
9938   return 0;
9939 }
9940
9941
9942 static int
9943 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
9944 {
9945   unformat_input_t *line_input = vam->input;
9946   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
9947   f64 timeout;
9948   ip4_address_t local4, remote4;
9949   ip6_address_t local6, remote6;
9950   u8 is_add = 1;
9951   u8 ipv4_set = 0, ipv6_set = 0;
9952   u8 local_set = 0;
9953   u8 remote_set = 0;
9954   u32 encap_vrf_id = 0;
9955   u32 decap_vrf_id = 0;
9956   u8 protocol = ~0;
9957   u32 vni;
9958   u8 vni_set = 0;
9959
9960   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9961     {
9962       if (unformat (line_input, "del"))
9963         is_add = 0;
9964       else if (unformat (line_input, "local %U",
9965                          unformat_ip4_address, &local4))
9966         {
9967           local_set = 1;
9968           ipv4_set = 1;
9969         }
9970       else if (unformat (line_input, "remote %U",
9971                          unformat_ip4_address, &remote4))
9972         {
9973           remote_set = 1;
9974           ipv4_set = 1;
9975         }
9976       else if (unformat (line_input, "local %U",
9977                          unformat_ip6_address, &local6))
9978         {
9979           local_set = 1;
9980           ipv6_set = 1;
9981         }
9982       else if (unformat (line_input, "remote %U",
9983                          unformat_ip6_address, &remote6))
9984         {
9985           remote_set = 1;
9986           ipv6_set = 1;
9987         }
9988       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9989         ;
9990       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
9991         ;
9992       else if (unformat (line_input, "vni %d", &vni))
9993         vni_set = 1;
9994       else if (unformat (line_input, "next-ip4"))
9995         protocol = 1;
9996       else if (unformat (line_input, "next-ip6"))
9997         protocol = 2;
9998       else if (unformat (line_input, "next-ethernet"))
9999         protocol = 3;
10000       else if (unformat (line_input, "next-nsh"))
10001         protocol = 4;
10002       else
10003         {
10004           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10005           return -99;
10006         }
10007     }
10008
10009   if (local_set == 0)
10010     {
10011       errmsg ("tunnel local address not specified\n");
10012       return -99;
10013     }
10014   if (remote_set == 0)
10015     {
10016       errmsg ("tunnel remote address not specified\n");
10017       return -99;
10018     }
10019   if (ipv4_set && ipv6_set)
10020     {
10021       errmsg ("both IPv4 and IPv6 addresses specified");
10022       return -99;
10023     }
10024
10025   if (vni_set == 0)
10026     {
10027       errmsg ("vni not specified\n");
10028       return -99;
10029     }
10030
10031   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10032
10033
10034   if (ipv6_set)
10035     {
10036       clib_memcpy (&mp->local, &local6, sizeof (local6));
10037       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10038     }
10039   else
10040     {
10041       clib_memcpy (&mp->local, &local4, sizeof (local4));
10042       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10043     }
10044
10045   mp->encap_vrf_id = ntohl (encap_vrf_id);
10046   mp->decap_vrf_id = ntohl (decap_vrf_id);
10047   mp->protocol = ntohl (protocol);
10048   mp->vni = ntohl (vni);
10049   mp->is_add = is_add;
10050   mp->is_ipv6 = ipv6_set;
10051
10052   S;
10053   W;
10054   /* NOTREACHED */
10055   return 0;
10056 }
10057
10058 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10059   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10060 {
10061   vat_main_t *vam = &vat_main;
10062
10063   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10064            ntohl (mp->sw_if_index),
10065            format_ip46_address, &(mp->local[0]),
10066            format_ip46_address, &(mp->remote[0]),
10067            ntohl (mp->vni),
10068            ntohl (mp->protocol),
10069            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10070 }
10071
10072 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10073   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10074 {
10075   vat_main_t *vam = &vat_main;
10076   vat_json_node_t *node = NULL;
10077   struct in_addr ip4;
10078   struct in6_addr ip6;
10079
10080   if (VAT_JSON_ARRAY != vam->json_tree.type)
10081     {
10082       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10083       vat_json_init_array (&vam->json_tree);
10084     }
10085   node = vat_json_array_add (&vam->json_tree);
10086
10087   vat_json_init_object (node);
10088   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10089   if (mp->is_ipv6)
10090     {
10091       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10092       vat_json_object_add_ip6 (node, "local", ip6);
10093       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10094       vat_json_object_add_ip6 (node, "remote", ip6);
10095     }
10096   else
10097     {
10098       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10099       vat_json_object_add_ip4 (node, "local", ip4);
10100       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10101       vat_json_object_add_ip4 (node, "remote", ip4);
10102     }
10103   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10104   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10105   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10106   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10107   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10108 }
10109
10110 static int
10111 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10112 {
10113   unformat_input_t *i = vam->input;
10114   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10115   f64 timeout;
10116   u32 sw_if_index;
10117   u8 sw_if_index_set = 0;
10118
10119   /* Parse args required to build the message */
10120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10121     {
10122       if (unformat (i, "sw_if_index %d", &sw_if_index))
10123         sw_if_index_set = 1;
10124       else
10125         break;
10126     }
10127
10128   if (sw_if_index_set == 0)
10129     {
10130       sw_if_index = ~0;
10131     }
10132
10133   if (!vam->json_output)
10134     {
10135       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10136                "sw_if_index", "local", "remote", "vni",
10137                "protocol", "encap_vrf_id", "decap_vrf_id");
10138     }
10139
10140   /* Get list of vxlan-tunnel interfaces */
10141   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10142
10143   mp->sw_if_index = htonl (sw_if_index);
10144
10145   S;
10146
10147   /* Use a control ping for synchronization */
10148   {
10149     vl_api_control_ping_t *mp;
10150     M (CONTROL_PING, control_ping);
10151     S;
10152   }
10153   W;
10154 }
10155
10156 u8 *
10157 format_l2_fib_mac_address (u8 * s, va_list * args)
10158 {
10159   u8 *a = va_arg (*args, u8 *);
10160
10161   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10162                  a[2], a[3], a[4], a[5], a[6], a[7]);
10163 }
10164
10165 static void vl_api_l2_fib_table_entry_t_handler
10166   (vl_api_l2_fib_table_entry_t * mp)
10167 {
10168   vat_main_t *vam = &vat_main;
10169
10170   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10171            "       %d       %d     %d\n",
10172            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10173            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10174            mp->bvi_mac);
10175 }
10176
10177 static void vl_api_l2_fib_table_entry_t_handler_json
10178   (vl_api_l2_fib_table_entry_t * mp)
10179 {
10180   vat_main_t *vam = &vat_main;
10181   vat_json_node_t *node = NULL;
10182
10183   if (VAT_JSON_ARRAY != vam->json_tree.type)
10184     {
10185       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10186       vat_json_init_array (&vam->json_tree);
10187     }
10188   node = vat_json_array_add (&vam->json_tree);
10189
10190   vat_json_init_object (node);
10191   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10192   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10193   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10194   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10195   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10196   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10197 }
10198
10199 static int
10200 api_l2_fib_table_dump (vat_main_t * vam)
10201 {
10202   unformat_input_t *i = vam->input;
10203   vl_api_l2_fib_table_dump_t *mp;
10204   f64 timeout;
10205   u32 bd_id;
10206   u8 bd_id_set = 0;
10207
10208   /* Parse args required to build the message */
10209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10210     {
10211       if (unformat (i, "bd_id %d", &bd_id))
10212         bd_id_set = 1;
10213       else
10214         break;
10215     }
10216
10217   if (bd_id_set == 0)
10218     {
10219       errmsg ("missing bridge domain\n");
10220       return -99;
10221     }
10222
10223   fformat (vam->ofp,
10224            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10225
10226   /* Get list of l2 fib entries */
10227   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10228
10229   mp->bd_id = ntohl (bd_id);
10230   S;
10231
10232   /* Use a control ping for synchronization */
10233   {
10234     vl_api_control_ping_t *mp;
10235     M (CONTROL_PING, control_ping);
10236     S;
10237   }
10238   W;
10239 }
10240
10241
10242 static int
10243 api_interface_name_renumber (vat_main_t * vam)
10244 {
10245   unformat_input_t *line_input = vam->input;
10246   vl_api_interface_name_renumber_t *mp;
10247   u32 sw_if_index = ~0;
10248   f64 timeout;
10249   u32 new_show_dev_instance = ~0;
10250
10251   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10252     {
10253       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10254                     &sw_if_index))
10255         ;
10256       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10257         ;
10258       else if (unformat (line_input, "new_show_dev_instance %d",
10259                          &new_show_dev_instance))
10260         ;
10261       else
10262         break;
10263     }
10264
10265   if (sw_if_index == ~0)
10266     {
10267       errmsg ("missing interface name or sw_if_index\n");
10268       return -99;
10269     }
10270
10271   if (new_show_dev_instance == ~0)
10272     {
10273       errmsg ("missing new_show_dev_instance\n");
10274       return -99;
10275     }
10276
10277   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10278
10279   mp->sw_if_index = ntohl (sw_if_index);
10280   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10281
10282   S;
10283   W;
10284 }
10285
10286 static int
10287 api_want_ip4_arp_events (vat_main_t * vam)
10288 {
10289   unformat_input_t *line_input = vam->input;
10290   vl_api_want_ip4_arp_events_t *mp;
10291   f64 timeout;
10292   ip4_address_t address;
10293   int address_set = 0;
10294   u32 enable_disable = 1;
10295
10296   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10297     {
10298       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10299         address_set = 1;
10300       else if (unformat (line_input, "del"))
10301         enable_disable = 0;
10302       else
10303         break;
10304     }
10305
10306   if (address_set == 0)
10307     {
10308       errmsg ("missing addresses\n");
10309       return -99;
10310     }
10311
10312   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10313   mp->enable_disable = enable_disable;
10314   mp->pid = getpid ();
10315   mp->address = address.as_u32;
10316
10317   S;
10318   W;
10319 }
10320
10321 static int
10322 api_want_ip6_nd_events (vat_main_t * vam)
10323 {
10324   unformat_input_t *line_input = vam->input;
10325   vl_api_want_ip6_nd_events_t *mp;
10326   f64 timeout;
10327   ip6_address_t address;
10328   int address_set = 0;
10329   u32 enable_disable = 1;
10330
10331   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10332     {
10333       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
10334         address_set = 1;
10335       else if (unformat (line_input, "del"))
10336         enable_disable = 0;
10337       else
10338         break;
10339     }
10340
10341   if (address_set == 0)
10342     {
10343       errmsg ("missing addresses\n");
10344       return -99;
10345     }
10346
10347   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
10348   mp->enable_disable = enable_disable;
10349   mp->pid = getpid ();
10350   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
10351
10352   S;
10353   W;
10354 }
10355
10356 static int
10357 api_input_acl_set_interface (vat_main_t * vam)
10358 {
10359   unformat_input_t *i = vam->input;
10360   vl_api_input_acl_set_interface_t *mp;
10361   f64 timeout;
10362   u32 sw_if_index;
10363   int sw_if_index_set;
10364   u32 ip4_table_index = ~0;
10365   u32 ip6_table_index = ~0;
10366   u32 l2_table_index = ~0;
10367   u8 is_add = 1;
10368
10369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10370     {
10371       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10372         sw_if_index_set = 1;
10373       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10374         sw_if_index_set = 1;
10375       else if (unformat (i, "del"))
10376         is_add = 0;
10377       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10378         ;
10379       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10380         ;
10381       else if (unformat (i, "l2-table %d", &l2_table_index))
10382         ;
10383       else
10384         {
10385           clib_warning ("parse error '%U'", format_unformat_error, i);
10386           return -99;
10387         }
10388     }
10389
10390   if (sw_if_index_set == 0)
10391     {
10392       errmsg ("missing interface name or sw_if_index\n");
10393       return -99;
10394     }
10395
10396   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10397
10398   mp->sw_if_index = ntohl (sw_if_index);
10399   mp->ip4_table_index = ntohl (ip4_table_index);
10400   mp->ip6_table_index = ntohl (ip6_table_index);
10401   mp->l2_table_index = ntohl (l2_table_index);
10402   mp->is_add = is_add;
10403
10404   S;
10405   W;
10406   /* NOTREACHED */
10407   return 0;
10408 }
10409
10410 static int
10411 api_ip_address_dump (vat_main_t * vam)
10412 {
10413   unformat_input_t *i = vam->input;
10414   vl_api_ip_address_dump_t *mp;
10415   u32 sw_if_index = ~0;
10416   u8 sw_if_index_set = 0;
10417   u8 ipv4_set = 0;
10418   u8 ipv6_set = 0;
10419   f64 timeout;
10420
10421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10422     {
10423       if (unformat (i, "sw_if_index %d", &sw_if_index))
10424         sw_if_index_set = 1;
10425       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10426         sw_if_index_set = 1;
10427       else if (unformat (i, "ipv4"))
10428         ipv4_set = 1;
10429       else if (unformat (i, "ipv6"))
10430         ipv6_set = 1;
10431       else
10432         break;
10433     }
10434
10435   if (ipv4_set && ipv6_set)
10436     {
10437       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10438       return -99;
10439     }
10440
10441   if ((!ipv4_set) && (!ipv6_set))
10442     {
10443       errmsg ("no ipv4 nor ipv6 flag set\n");
10444       return -99;
10445     }
10446
10447   if (sw_if_index_set == 0)
10448     {
10449       errmsg ("missing interface name or sw_if_index\n");
10450       return -99;
10451     }
10452
10453   vam->current_sw_if_index = sw_if_index;
10454   vam->is_ipv6 = ipv6_set;
10455
10456   M (IP_ADDRESS_DUMP, ip_address_dump);
10457   mp->sw_if_index = ntohl (sw_if_index);
10458   mp->is_ipv6 = ipv6_set;
10459   S;
10460
10461   /* Use a control ping for synchronization */
10462   {
10463     vl_api_control_ping_t *mp;
10464     M (CONTROL_PING, control_ping);
10465     S;
10466   }
10467   W;
10468 }
10469
10470 static int
10471 api_ip_dump (vat_main_t * vam)
10472 {
10473   vl_api_ip_dump_t *mp;
10474   unformat_input_t *in = vam->input;
10475   int ipv4_set = 0;
10476   int ipv6_set = 0;
10477   int is_ipv6;
10478   f64 timeout;
10479   int i;
10480
10481   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10482     {
10483       if (unformat (in, "ipv4"))
10484         ipv4_set = 1;
10485       else if (unformat (in, "ipv6"))
10486         ipv6_set = 1;
10487       else
10488         break;
10489     }
10490
10491   if (ipv4_set && ipv6_set)
10492     {
10493       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10494       return -99;
10495     }
10496
10497   if ((!ipv4_set) && (!ipv6_set))
10498     {
10499       errmsg ("no ipv4 nor ipv6 flag set\n");
10500       return -99;
10501     }
10502
10503   is_ipv6 = ipv6_set;
10504   vam->is_ipv6 = is_ipv6;
10505
10506   /* free old data */
10507   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10508     {
10509       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10510     }
10511   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10512
10513   M (IP_DUMP, ip_dump);
10514   mp->is_ipv6 = ipv6_set;
10515   S;
10516
10517   /* Use a control ping for synchronization */
10518   {
10519     vl_api_control_ping_t *mp;
10520     M (CONTROL_PING, control_ping);
10521     S;
10522   }
10523   W;
10524 }
10525
10526 static int
10527 api_ipsec_spd_add_del (vat_main_t * vam)
10528 {
10529 #if DPDK > 0
10530   unformat_input_t *i = vam->input;
10531   vl_api_ipsec_spd_add_del_t *mp;
10532   f64 timeout;
10533   u32 spd_id = ~0;
10534   u8 is_add = 1;
10535
10536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10537     {
10538       if (unformat (i, "spd_id %d", &spd_id))
10539         ;
10540       else if (unformat (i, "del"))
10541         is_add = 0;
10542       else
10543         {
10544           clib_warning ("parse error '%U'", format_unformat_error, i);
10545           return -99;
10546         }
10547     }
10548   if (spd_id == ~0)
10549     {
10550       errmsg ("spd_id must be set\n");
10551       return -99;
10552     }
10553
10554   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10555
10556   mp->spd_id = ntohl (spd_id);
10557   mp->is_add = is_add;
10558
10559   S;
10560   W;
10561   /* NOTREACHED */
10562   return 0;
10563 #else
10564   clib_warning ("unsupported (no dpdk)");
10565   return -99;
10566 #endif
10567 }
10568
10569 static int
10570 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10571 {
10572 #if DPDK > 0
10573   unformat_input_t *i = vam->input;
10574   vl_api_ipsec_interface_add_del_spd_t *mp;
10575   f64 timeout;
10576   u32 sw_if_index;
10577   u8 sw_if_index_set = 0;
10578   u32 spd_id = (u32) ~ 0;
10579   u8 is_add = 1;
10580
10581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10582     {
10583       if (unformat (i, "del"))
10584         is_add = 0;
10585       else if (unformat (i, "spd_id %d", &spd_id))
10586         ;
10587       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10588         sw_if_index_set = 1;
10589       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10590         sw_if_index_set = 1;
10591       else
10592         {
10593           clib_warning ("parse error '%U'", format_unformat_error, i);
10594           return -99;
10595         }
10596
10597     }
10598
10599   if (spd_id == (u32) ~ 0)
10600     {
10601       errmsg ("spd_id must be set\n");
10602       return -99;
10603     }
10604
10605   if (sw_if_index_set == 0)
10606     {
10607       errmsg ("missing interface name or sw_if_index\n");
10608       return -99;
10609     }
10610
10611   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10612
10613   mp->spd_id = ntohl (spd_id);
10614   mp->sw_if_index = ntohl (sw_if_index);
10615   mp->is_add = is_add;
10616
10617   S;
10618   W;
10619   /* NOTREACHED */
10620   return 0;
10621 #else
10622   clib_warning ("unsupported (no dpdk)");
10623   return -99;
10624 #endif
10625 }
10626
10627 static int
10628 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10629 {
10630 #if DPDK > 0
10631   unformat_input_t *i = vam->input;
10632   vl_api_ipsec_spd_add_del_entry_t *mp;
10633   f64 timeout;
10634   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10635   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10636   i32 priority = 0;
10637   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10638   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10639   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10640   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10641
10642   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10643   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10644   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10645   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10646   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10647   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10648
10649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10650     {
10651       if (unformat (i, "del"))
10652         is_add = 0;
10653       if (unformat (i, "outbound"))
10654         is_outbound = 1;
10655       if (unformat (i, "inbound"))
10656         is_outbound = 0;
10657       else if (unformat (i, "spd_id %d", &spd_id))
10658         ;
10659       else if (unformat (i, "sa_id %d", &sa_id))
10660         ;
10661       else if (unformat (i, "priority %d", &priority))
10662         ;
10663       else if (unformat (i, "protocol %d", &protocol))
10664         ;
10665       else if (unformat (i, "lport_start %d", &lport_start))
10666         ;
10667       else if (unformat (i, "lport_stop %d", &lport_stop))
10668         ;
10669       else if (unformat (i, "rport_start %d", &rport_start))
10670         ;
10671       else if (unformat (i, "rport_stop %d", &rport_stop))
10672         ;
10673       else
10674         if (unformat
10675             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10676         {
10677           is_ipv6 = 0;
10678           is_ip_any = 0;
10679         }
10680       else
10681         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10682         {
10683           is_ipv6 = 0;
10684           is_ip_any = 0;
10685         }
10686       else
10687         if (unformat
10688             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
10689         {
10690           is_ipv6 = 0;
10691           is_ip_any = 0;
10692         }
10693       else
10694         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
10695         {
10696           is_ipv6 = 0;
10697           is_ip_any = 0;
10698         }
10699       else
10700         if (unformat
10701             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
10702         {
10703           is_ipv6 = 1;
10704           is_ip_any = 0;
10705         }
10706       else
10707         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
10708         {
10709           is_ipv6 = 1;
10710           is_ip_any = 0;
10711         }
10712       else
10713         if (unformat
10714             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
10715         {
10716           is_ipv6 = 1;
10717           is_ip_any = 0;
10718         }
10719       else
10720         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
10721         {
10722           is_ipv6 = 1;
10723           is_ip_any = 0;
10724         }
10725       else
10726         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10727         {
10728           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10729             {
10730               clib_warning ("unsupported action: 'resolve'");
10731               return -99;
10732             }
10733         }
10734       else
10735         {
10736           clib_warning ("parse error '%U'", format_unformat_error, i);
10737           return -99;
10738         }
10739
10740     }
10741
10742   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
10743
10744   mp->spd_id = ntohl (spd_id);
10745   mp->priority = ntohl (priority);
10746   mp->is_outbound = is_outbound;
10747
10748   mp->is_ipv6 = is_ipv6;
10749   if (is_ipv6 || is_ip_any)
10750     {
10751       clib_memcpy (mp->remote_address_start, &raddr6_start,
10752                    sizeof (ip6_address_t));
10753       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
10754                    sizeof (ip6_address_t));
10755       clib_memcpy (mp->local_address_start, &laddr6_start,
10756                    sizeof (ip6_address_t));
10757       clib_memcpy (mp->local_address_stop, &laddr6_stop,
10758                    sizeof (ip6_address_t));
10759     }
10760   else
10761     {
10762       clib_memcpy (mp->remote_address_start, &raddr4_start,
10763                    sizeof (ip4_address_t));
10764       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
10765                    sizeof (ip4_address_t));
10766       clib_memcpy (mp->local_address_start, &laddr4_start,
10767                    sizeof (ip4_address_t));
10768       clib_memcpy (mp->local_address_stop, &laddr4_stop,
10769                    sizeof (ip4_address_t));
10770     }
10771   mp->protocol = (u8) protocol;
10772   mp->local_port_start = ntohs ((u16) lport_start);
10773   mp->local_port_stop = ntohs ((u16) lport_stop);
10774   mp->remote_port_start = ntohs ((u16) rport_start);
10775   mp->remote_port_stop = ntohs ((u16) rport_stop);
10776   mp->policy = (u8) policy;
10777   mp->sa_id = ntohl (sa_id);
10778   mp->is_add = is_add;
10779   mp->is_ip_any = is_ip_any;
10780   S;
10781   W;
10782   /* NOTREACHED */
10783   return 0;
10784 #else
10785   clib_warning ("unsupported (no dpdk)");
10786   return -99;
10787 #endif
10788 }
10789
10790 static int
10791 api_ipsec_sad_add_del_entry (vat_main_t * vam)
10792 {
10793 #if DPDK > 0
10794   unformat_input_t *i = vam->input;
10795   vl_api_ipsec_sad_add_del_entry_t *mp;
10796   f64 timeout;
10797   u32 sad_id = 0, spi = 0;
10798   u8 *ck = 0, *ik = 0;
10799   u8 is_add = 1;
10800
10801   u8 protocol = IPSEC_PROTOCOL_AH;
10802   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
10803   u32 crypto_alg = 0, integ_alg = 0;
10804   ip4_address_t tun_src4;
10805   ip4_address_t tun_dst4;
10806   ip6_address_t tun_src6;
10807   ip6_address_t tun_dst6;
10808
10809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10810     {
10811       if (unformat (i, "del"))
10812         is_add = 0;
10813       else if (unformat (i, "sad_id %d", &sad_id))
10814         ;
10815       else if (unformat (i, "spi %d", &spi))
10816         ;
10817       else if (unformat (i, "esp"))
10818         protocol = IPSEC_PROTOCOL_ESP;
10819       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
10820         {
10821           is_tunnel = 1;
10822           is_tunnel_ipv6 = 0;
10823         }
10824       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
10825         {
10826           is_tunnel = 1;
10827           is_tunnel_ipv6 = 0;
10828         }
10829       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
10830         {
10831           is_tunnel = 1;
10832           is_tunnel_ipv6 = 1;
10833         }
10834       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
10835         {
10836           is_tunnel = 1;
10837           is_tunnel_ipv6 = 1;
10838         }
10839       else
10840         if (unformat
10841             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
10842         {
10843           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
10844               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
10845             {
10846               clib_warning ("unsupported crypto-alg: '%U'",
10847                             format_ipsec_crypto_alg, crypto_alg);
10848               return -99;
10849             }
10850         }
10851       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10852         ;
10853       else
10854         if (unformat
10855             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
10856         {
10857           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
10858               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
10859             {
10860               clib_warning ("unsupported integ-alg: '%U'",
10861                             format_ipsec_integ_alg, integ_alg);
10862               return -99;
10863             }
10864         }
10865       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10866         ;
10867       else
10868         {
10869           clib_warning ("parse error '%U'", format_unformat_error, i);
10870           return -99;
10871         }
10872
10873     }
10874
10875   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
10876
10877   mp->sad_id = ntohl (sad_id);
10878   mp->is_add = is_add;
10879   mp->protocol = protocol;
10880   mp->spi = ntohl (spi);
10881   mp->is_tunnel = is_tunnel;
10882   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
10883   mp->crypto_algorithm = crypto_alg;
10884   mp->integrity_algorithm = integ_alg;
10885   mp->crypto_key_length = vec_len (ck);
10886   mp->integrity_key_length = vec_len (ik);
10887
10888   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10889     mp->crypto_key_length = sizeof (mp->crypto_key);
10890
10891   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10892     mp->integrity_key_length = sizeof (mp->integrity_key);
10893
10894   if (ck)
10895     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10896   if (ik)
10897     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10898
10899   if (is_tunnel)
10900     {
10901       if (is_tunnel_ipv6)
10902         {
10903           clib_memcpy (mp->tunnel_src_address, &tun_src6,
10904                        sizeof (ip6_address_t));
10905           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
10906                        sizeof (ip6_address_t));
10907         }
10908       else
10909         {
10910           clib_memcpy (mp->tunnel_src_address, &tun_src4,
10911                        sizeof (ip4_address_t));
10912           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
10913                        sizeof (ip4_address_t));
10914         }
10915     }
10916
10917   S;
10918   W;
10919   /* NOTREACHED */
10920   return 0;
10921 #else
10922   clib_warning ("unsupported (no dpdk)");
10923   return -99;
10924 #endif
10925 }
10926
10927 static int
10928 api_ipsec_sa_set_key (vat_main_t * vam)
10929 {
10930 #if DPDK > 0
10931   unformat_input_t *i = vam->input;
10932   vl_api_ipsec_sa_set_key_t *mp;
10933   f64 timeout;
10934   u32 sa_id;
10935   u8 *ck = 0, *ik = 0;
10936
10937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10938     {
10939       if (unformat (i, "sa_id %d", &sa_id))
10940         ;
10941       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10942         ;
10943       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10944         ;
10945       else
10946         {
10947           clib_warning ("parse error '%U'", format_unformat_error, i);
10948           return -99;
10949         }
10950     }
10951
10952   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
10953
10954   mp->sa_id = ntohl (sa_id);
10955   mp->crypto_key_length = vec_len (ck);
10956   mp->integrity_key_length = vec_len (ik);
10957
10958   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10959     mp->crypto_key_length = sizeof (mp->crypto_key);
10960
10961   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10962     mp->integrity_key_length = sizeof (mp->integrity_key);
10963
10964   if (ck)
10965     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10966   if (ik)
10967     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10968
10969   S;
10970   W;
10971   /* NOTREACHED */
10972   return 0;
10973 #else
10974   clib_warning ("unsupported (no dpdk)");
10975   return -99;
10976 #endif
10977 }
10978
10979 static int
10980 api_ikev2_profile_add_del (vat_main_t * vam)
10981 {
10982 #if DPDK > 0
10983   unformat_input_t *i = vam->input;
10984   vl_api_ikev2_profile_add_del_t *mp;
10985   f64 timeout;
10986   u8 is_add = 1;
10987   u8 *name = 0;
10988
10989   const char *valid_chars = "a-zA-Z0-9_";
10990
10991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10992     {
10993       if (unformat (i, "del"))
10994         is_add = 0;
10995       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10996         vec_add1 (name, 0);
10997       else
10998         {
10999           errmsg ("parse error '%U'", format_unformat_error, i);
11000           return -99;
11001         }
11002     }
11003
11004   if (!vec_len (name))
11005     {
11006       errmsg ("profile name must be specified");
11007       return -99;
11008     }
11009
11010   if (vec_len (name) > 64)
11011     {
11012       errmsg ("profile name too long");
11013       return -99;
11014     }
11015
11016   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11017
11018   clib_memcpy (mp->name, name, vec_len (name));
11019   mp->is_add = is_add;
11020   vec_free (name);
11021
11022   S;
11023   W;
11024   /* NOTREACHED */
11025   return 0;
11026 #else
11027   clib_warning ("unsupported (no dpdk)");
11028   return -99;
11029 #endif
11030 }
11031
11032 static int
11033 api_ikev2_profile_set_auth (vat_main_t * vam)
11034 {
11035 #if DPDK > 0
11036   unformat_input_t *i = vam->input;
11037   vl_api_ikev2_profile_set_auth_t *mp;
11038   f64 timeout;
11039   u8 *name = 0;
11040   u8 *data = 0;
11041   u32 auth_method = 0;
11042   u8 is_hex = 0;
11043
11044   const char *valid_chars = "a-zA-Z0-9_";
11045
11046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11047     {
11048       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11049         vec_add1 (name, 0);
11050       else if (unformat (i, "auth_method %U",
11051                          unformat_ikev2_auth_method, &auth_method))
11052         ;
11053       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11054         is_hex = 1;
11055       else if (unformat (i, "auth_data %v", &data))
11056         ;
11057       else
11058         {
11059           errmsg ("parse error '%U'", format_unformat_error, i);
11060           return -99;
11061         }
11062     }
11063
11064   if (!vec_len (name))
11065     {
11066       errmsg ("profile name must be specified");
11067       return -99;
11068     }
11069
11070   if (vec_len (name) > 64)
11071     {
11072       errmsg ("profile name too long");
11073       return -99;
11074     }
11075
11076   if (!vec_len (data))
11077     {
11078       errmsg ("auth_data must be specified");
11079       return -99;
11080     }
11081
11082   if (!auth_method)
11083     {
11084       errmsg ("auth_method must be specified");
11085       return -99;
11086     }
11087
11088   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11089
11090   mp->is_hex = is_hex;
11091   mp->auth_method = (u8) auth_method;
11092   mp->data_len = vec_len (data);
11093   clib_memcpy (mp->name, name, vec_len (name));
11094   clib_memcpy (mp->data, data, vec_len (data));
11095   vec_free (name);
11096   vec_free (data);
11097
11098   S;
11099   W;
11100   /* NOTREACHED */
11101   return 0;
11102 #else
11103   clib_warning ("unsupported (no dpdk)");
11104   return -99;
11105 #endif
11106 }
11107
11108 static int
11109 api_ikev2_profile_set_id (vat_main_t * vam)
11110 {
11111 #if DPDK > 0
11112   unformat_input_t *i = vam->input;
11113   vl_api_ikev2_profile_set_id_t *mp;
11114   f64 timeout;
11115   u8 *name = 0;
11116   u8 *data = 0;
11117   u8 is_local = 0;
11118   u32 id_type = 0;
11119   ip4_address_t ip4;
11120
11121   const char *valid_chars = "a-zA-Z0-9_";
11122
11123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11124     {
11125       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11126         vec_add1 (name, 0);
11127       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11128         ;
11129       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11130         {
11131           data = vec_new (u8, 4);
11132           clib_memcpy (data, ip4.as_u8, 4);
11133         }
11134       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11135         ;
11136       else if (unformat (i, "id_data %v", &data))
11137         ;
11138       else if (unformat (i, "local"))
11139         is_local = 1;
11140       else if (unformat (i, "remote"))
11141         is_local = 0;
11142       else
11143         {
11144           errmsg ("parse error '%U'", format_unformat_error, i);
11145           return -99;
11146         }
11147     }
11148
11149   if (!vec_len (name))
11150     {
11151       errmsg ("profile name must be specified");
11152       return -99;
11153     }
11154
11155   if (vec_len (name) > 64)
11156     {
11157       errmsg ("profile name too long");
11158       return -99;
11159     }
11160
11161   if (!vec_len (data))
11162     {
11163       errmsg ("id_data must be specified");
11164       return -99;
11165     }
11166
11167   if (!id_type)
11168     {
11169       errmsg ("id_type must be specified");
11170       return -99;
11171     }
11172
11173   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11174
11175   mp->is_local = is_local;
11176   mp->id_type = (u8) id_type;
11177   mp->data_len = vec_len (data);
11178   clib_memcpy (mp->name, name, vec_len (name));
11179   clib_memcpy (mp->data, data, vec_len (data));
11180   vec_free (name);
11181   vec_free (data);
11182
11183   S;
11184   W;
11185   /* NOTREACHED */
11186   return 0;
11187 #else
11188   clib_warning ("unsupported (no dpdk)");
11189   return -99;
11190 #endif
11191 }
11192
11193 static int
11194 api_ikev2_profile_set_ts (vat_main_t * vam)
11195 {
11196 #if DPDK > 0
11197   unformat_input_t *i = vam->input;
11198   vl_api_ikev2_profile_set_ts_t *mp;
11199   f64 timeout;
11200   u8 *name = 0;
11201   u8 is_local = 0;
11202   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11203   ip4_address_t start_addr, end_addr;
11204
11205   const char *valid_chars = "a-zA-Z0-9_";
11206
11207   start_addr.as_u32 = 0;
11208   end_addr.as_u32 = (u32) ~ 0;
11209
11210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11211     {
11212       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11213         vec_add1 (name, 0);
11214       else if (unformat (i, "protocol %d", &proto))
11215         ;
11216       else if (unformat (i, "start_port %d", &start_port))
11217         ;
11218       else if (unformat (i, "end_port %d", &end_port))
11219         ;
11220       else
11221         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11222         ;
11223       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11224         ;
11225       else if (unformat (i, "local"))
11226         is_local = 1;
11227       else if (unformat (i, "remote"))
11228         is_local = 0;
11229       else
11230         {
11231           errmsg ("parse error '%U'", format_unformat_error, i);
11232           return -99;
11233         }
11234     }
11235
11236   if (!vec_len (name))
11237     {
11238       errmsg ("profile name must be specified");
11239       return -99;
11240     }
11241
11242   if (vec_len (name) > 64)
11243     {
11244       errmsg ("profile name too long");
11245       return -99;
11246     }
11247
11248   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11249
11250   mp->is_local = is_local;
11251   mp->proto = (u8) proto;
11252   mp->start_port = (u16) start_port;
11253   mp->end_port = (u16) end_port;
11254   mp->start_addr = start_addr.as_u32;
11255   mp->end_addr = end_addr.as_u32;
11256   clib_memcpy (mp->name, name, vec_len (name));
11257   vec_free (name);
11258
11259   S;
11260   W;
11261   /* NOTREACHED */
11262   return 0;
11263 #else
11264   clib_warning ("unsupported (no dpdk)");
11265   return -99;
11266 #endif
11267 }
11268
11269 static int
11270 api_ikev2_set_local_key (vat_main_t * vam)
11271 {
11272 #if DPDK > 0
11273   unformat_input_t *i = vam->input;
11274   vl_api_ikev2_set_local_key_t *mp;
11275   f64 timeout;
11276   u8 *file = 0;
11277
11278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11279     {
11280       if (unformat (i, "file %v", &file))
11281         vec_add1 (file, 0);
11282       else
11283         {
11284           errmsg ("parse error '%U'", format_unformat_error, i);
11285           return -99;
11286         }
11287     }
11288
11289   if (!vec_len (file))
11290     {
11291       errmsg ("RSA key file must be specified");
11292       return -99;
11293     }
11294
11295   if (vec_len (file) > 256)
11296     {
11297       errmsg ("file name too long");
11298       return -99;
11299     }
11300
11301   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11302
11303   clib_memcpy (mp->key_file, file, vec_len (file));
11304   vec_free (file);
11305
11306   S;
11307   W;
11308   /* NOTREACHED */
11309   return 0;
11310 #else
11311   clib_warning ("unsupported (no dpdk)");
11312   return -99;
11313 #endif
11314 }
11315
11316 /*
11317  * MAP
11318  */
11319 static int
11320 api_map_add_domain (vat_main_t * vam)
11321 {
11322   unformat_input_t *i = vam->input;
11323   vl_api_map_add_domain_t *mp;
11324   f64 timeout;
11325
11326   ip4_address_t ip4_prefix;
11327   ip6_address_t ip6_prefix;
11328   ip6_address_t ip6_src;
11329   u32 num_m_args = 0;
11330   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11331     0, psid_length = 0;
11332   u8 is_translation = 0;
11333   u32 mtu = 0;
11334   u32 ip6_src_len = 128;
11335
11336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11337     {
11338       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11339                     &ip4_prefix, &ip4_prefix_len))
11340         num_m_args++;
11341       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11342                          &ip6_prefix, &ip6_prefix_len))
11343         num_m_args++;
11344       else
11345         if (unformat
11346             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11347              &ip6_src_len))
11348         num_m_args++;
11349       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11350         num_m_args++;
11351       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11352         num_m_args++;
11353       else if (unformat (i, "psid-offset %d", &psid_offset))
11354         num_m_args++;
11355       else if (unformat (i, "psid-len %d", &psid_length))
11356         num_m_args++;
11357       else if (unformat (i, "mtu %d", &mtu))
11358         num_m_args++;
11359       else if (unformat (i, "map-t"))
11360         is_translation = 1;
11361       else
11362         {
11363           clib_warning ("parse error '%U'", format_unformat_error, i);
11364           return -99;
11365         }
11366     }
11367
11368   if (num_m_args < 3)
11369     {
11370       errmsg ("mandatory argument(s) missing\n");
11371       return -99;
11372     }
11373
11374   /* Construct the API message */
11375   M (MAP_ADD_DOMAIN, map_add_domain);
11376
11377   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11378   mp->ip4_prefix_len = ip4_prefix_len;
11379
11380   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11381   mp->ip6_prefix_len = ip6_prefix_len;
11382
11383   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11384   mp->ip6_src_prefix_len = ip6_src_len;
11385
11386   mp->ea_bits_len = ea_bits_len;
11387   mp->psid_offset = psid_offset;
11388   mp->psid_length = psid_length;
11389   mp->is_translation = is_translation;
11390   mp->mtu = htons (mtu);
11391
11392   /* send it... */
11393   S;
11394
11395   /* Wait for a reply, return good/bad news  */
11396   W;
11397 }
11398
11399 static int
11400 api_map_del_domain (vat_main_t * vam)
11401 {
11402   unformat_input_t *i = vam->input;
11403   vl_api_map_del_domain_t *mp;
11404   f64 timeout;
11405
11406   u32 num_m_args = 0;
11407   u32 index;
11408
11409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11410     {
11411       if (unformat (i, "index %d", &index))
11412         num_m_args++;
11413       else
11414         {
11415           clib_warning ("parse error '%U'", format_unformat_error, i);
11416           return -99;
11417         }
11418     }
11419
11420   if (num_m_args != 1)
11421     {
11422       errmsg ("mandatory argument(s) missing\n");
11423       return -99;
11424     }
11425
11426   /* Construct the API message */
11427   M (MAP_DEL_DOMAIN, map_del_domain);
11428
11429   mp->index = ntohl (index);
11430
11431   /* send it... */
11432   S;
11433
11434   /* Wait for a reply, return good/bad news  */
11435   W;
11436 }
11437
11438 static int
11439 api_map_add_del_rule (vat_main_t * vam)
11440 {
11441   unformat_input_t *i = vam->input;
11442   vl_api_map_add_del_rule_t *mp;
11443   f64 timeout;
11444   u8 is_add = 1;
11445   ip6_address_t ip6_dst;
11446   u32 num_m_args = 0, index, psid = 0;
11447
11448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11449     {
11450       if (unformat (i, "index %d", &index))
11451         num_m_args++;
11452       else if (unformat (i, "psid %d", &psid))
11453         num_m_args++;
11454       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11455         num_m_args++;
11456       else if (unformat (i, "del"))
11457         {
11458           is_add = 0;
11459         }
11460       else
11461         {
11462           clib_warning ("parse error '%U'", format_unformat_error, i);
11463           return -99;
11464         }
11465     }
11466
11467   /* Construct the API message */
11468   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11469
11470   mp->index = ntohl (index);
11471   mp->is_add = is_add;
11472   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11473   mp->psid = ntohs (psid);
11474
11475   /* send it... */
11476   S;
11477
11478   /* Wait for a reply, return good/bad news  */
11479   W;
11480 }
11481
11482 static int
11483 api_map_domain_dump (vat_main_t * vam)
11484 {
11485   vl_api_map_domain_dump_t *mp;
11486   f64 timeout;
11487
11488   /* Construct the API message */
11489   M (MAP_DOMAIN_DUMP, map_domain_dump);
11490
11491   /* send it... */
11492   S;
11493
11494   /* Use a control ping for synchronization */
11495   {
11496     vl_api_control_ping_t *mp;
11497     M (CONTROL_PING, control_ping);
11498     S;
11499   }
11500   W;
11501 }
11502
11503 static int
11504 api_map_rule_dump (vat_main_t * vam)
11505 {
11506   unformat_input_t *i = vam->input;
11507   vl_api_map_rule_dump_t *mp;
11508   f64 timeout;
11509   u32 domain_index = ~0;
11510
11511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11512     {
11513       if (unformat (i, "index %u", &domain_index))
11514         ;
11515       else
11516         break;
11517     }
11518
11519   if (domain_index == ~0)
11520     {
11521       clib_warning ("parse error: domain index expected");
11522       return -99;
11523     }
11524
11525   /* Construct the API message */
11526   M (MAP_RULE_DUMP, map_rule_dump);
11527
11528   mp->domain_index = htonl (domain_index);
11529
11530   /* send it... */
11531   S;
11532
11533   /* Use a control ping for synchronization */
11534   {
11535     vl_api_control_ping_t *mp;
11536     M (CONTROL_PING, control_ping);
11537     S;
11538   }
11539   W;
11540 }
11541
11542 static void vl_api_map_add_domain_reply_t_handler
11543   (vl_api_map_add_domain_reply_t * mp)
11544 {
11545   vat_main_t *vam = &vat_main;
11546   i32 retval = ntohl (mp->retval);
11547
11548   if (vam->async_mode)
11549     {
11550       vam->async_errors += (retval < 0);
11551     }
11552   else
11553     {
11554       vam->retval = retval;
11555       vam->result_ready = 1;
11556     }
11557 }
11558
11559 static void vl_api_map_add_domain_reply_t_handler_json
11560   (vl_api_map_add_domain_reply_t * mp)
11561 {
11562   vat_main_t *vam = &vat_main;
11563   vat_json_node_t node;
11564
11565   vat_json_init_object (&node);
11566   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11567   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11568
11569   vat_json_print (vam->ofp, &node);
11570   vat_json_free (&node);
11571
11572   vam->retval = ntohl (mp->retval);
11573   vam->result_ready = 1;
11574 }
11575
11576 static int
11577 api_get_first_msg_id (vat_main_t * vam)
11578 {
11579   vl_api_get_first_msg_id_t *mp;
11580   f64 timeout;
11581   unformat_input_t *i = vam->input;
11582   u8 *name;
11583   u8 name_set = 0;
11584
11585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11586     {
11587       if (unformat (i, "client %s", &name))
11588         name_set = 1;
11589       else
11590         break;
11591     }
11592
11593   if (name_set == 0)
11594     {
11595       errmsg ("missing client name\n");
11596       return -99;
11597     }
11598   vec_add1 (name, 0);
11599
11600   if (vec_len (name) > 63)
11601     {
11602       errmsg ("client name too long\n");
11603       return -99;
11604     }
11605
11606   M (GET_FIRST_MSG_ID, get_first_msg_id);
11607   clib_memcpy (mp->name, name, vec_len (name));
11608   S;
11609   W;
11610   /* NOTREACHED */
11611   return 0;
11612 }
11613
11614 static int
11615 api_cop_interface_enable_disable (vat_main_t * vam)
11616 {
11617   unformat_input_t *line_input = vam->input;
11618   vl_api_cop_interface_enable_disable_t *mp;
11619   f64 timeout;
11620   u32 sw_if_index = ~0;
11621   u8 enable_disable = 1;
11622
11623   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11624     {
11625       if (unformat (line_input, "disable"))
11626         enable_disable = 0;
11627       if (unformat (line_input, "enable"))
11628         enable_disable = 1;
11629       else if (unformat (line_input, "%U", unformat_sw_if_index,
11630                          vam, &sw_if_index))
11631         ;
11632       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11633         ;
11634       else
11635         break;
11636     }
11637
11638   if (sw_if_index == ~0)
11639     {
11640       errmsg ("missing interface name or sw_if_index\n");
11641       return -99;
11642     }
11643
11644   /* Construct the API message */
11645   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11646   mp->sw_if_index = ntohl (sw_if_index);
11647   mp->enable_disable = enable_disable;
11648
11649   /* send it... */
11650   S;
11651   /* Wait for the reply */
11652   W;
11653 }
11654
11655 static int
11656 api_cop_whitelist_enable_disable (vat_main_t * vam)
11657 {
11658   unformat_input_t *line_input = vam->input;
11659   vl_api_cop_whitelist_enable_disable_t *mp;
11660   f64 timeout;
11661   u32 sw_if_index = ~0;
11662   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11663   u32 fib_id = 0;
11664
11665   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11666     {
11667       if (unformat (line_input, "ip4"))
11668         ip4 = 1;
11669       else if (unformat (line_input, "ip6"))
11670         ip6 = 1;
11671       else if (unformat (line_input, "default"))
11672         default_cop = 1;
11673       else if (unformat (line_input, "%U", unformat_sw_if_index,
11674                          vam, &sw_if_index))
11675         ;
11676       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11677         ;
11678       else if (unformat (line_input, "fib-id %d", &fib_id))
11679         ;
11680       else
11681         break;
11682     }
11683
11684   if (sw_if_index == ~0)
11685     {
11686       errmsg ("missing interface name or sw_if_index\n");
11687       return -99;
11688     }
11689
11690   /* Construct the API message */
11691   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
11692   mp->sw_if_index = ntohl (sw_if_index);
11693   mp->fib_id = ntohl (fib_id);
11694   mp->ip4 = ip4;
11695   mp->ip6 = ip6;
11696   mp->default_cop = default_cop;
11697
11698   /* send it... */
11699   S;
11700   /* Wait for the reply */
11701   W;
11702 }
11703
11704 static int
11705 api_get_node_graph (vat_main_t * vam)
11706 {
11707   vl_api_get_node_graph_t *mp;
11708   f64 timeout;
11709
11710   M (GET_NODE_GRAPH, get_node_graph);
11711
11712   /* send it... */
11713   S;
11714   /* Wait for the reply */
11715   W;
11716 }
11717
11718 /* *INDENT-OFF* */
11719 /** Used for parsing LISP eids */
11720 typedef CLIB_PACKED(struct{
11721   u8 addr[16];   /**< eid address */
11722   u32 len;       /**< prefix length if IP */
11723   u8 type;      /**< type of eid */
11724 }) lisp_eid_vat_t;
11725 /* *INDENT-ON* */
11726
11727 static uword
11728 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
11729 {
11730   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
11731
11732   memset (a, 0, sizeof (a[0]));
11733
11734   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
11735     {
11736       a->type = 0;              /* ipv4 type */
11737     }
11738   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
11739     {
11740       a->type = 1;              /* ipv6 type */
11741     }
11742   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
11743     {
11744       a->type = 2;              /* mac type */
11745     }
11746   else
11747     {
11748       return 0;
11749     }
11750
11751   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
11752     {
11753       return 0;
11754     }
11755
11756   return 1;
11757 }
11758
11759 static int
11760 lisp_eid_size_vat (u8 type)
11761 {
11762   switch (type)
11763     {
11764     case 0:
11765       return 4;
11766     case 1:
11767       return 16;
11768     case 2:
11769       return 6;
11770     }
11771   return 0;
11772 }
11773
11774 static void
11775 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
11776 {
11777   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
11778 }
11779
11780 /* *INDENT-OFF* */
11781 /** Used for transferring locators via VPP API */
11782 typedef CLIB_PACKED(struct
11783 {
11784   u32 sw_if_index; /**< locator sw_if_index */
11785   u8 priority; /**< locator priority */
11786   u8 weight;   /**< locator weight */
11787 }) ls_locator_t;
11788 /* *INDENT-ON* */
11789
11790 static int
11791 api_lisp_add_del_locator_set (vat_main_t * vam)
11792 {
11793   unformat_input_t *input = vam->input;
11794   vl_api_lisp_add_del_locator_set_t *mp;
11795   f64 timeout = ~0;
11796   u8 is_add = 1;
11797   u8 *locator_set_name = NULL;
11798   u8 locator_set_name_set = 0;
11799   ls_locator_t locator, *locators = 0;
11800   u32 sw_if_index, priority, weight;
11801
11802   /* Parse args required to build the message */
11803   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11804     {
11805       if (unformat (input, "del"))
11806         {
11807           is_add = 0;
11808         }
11809       else if (unformat (input, "locator-set %s", &locator_set_name))
11810         {
11811           locator_set_name_set = 1;
11812         }
11813       else if (unformat (input, "sw_if_index %u p %u w %u",
11814                          &sw_if_index, &priority, &weight))
11815         {
11816           locator.sw_if_index = htonl (sw_if_index);
11817           locator.priority = priority;
11818           locator.weight = weight;
11819           vec_add1 (locators, locator);
11820         }
11821       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
11822                          vam, &sw_if_index, &priority, &weight))
11823         {
11824           locator.sw_if_index = htonl (sw_if_index);
11825           locator.priority = priority;
11826           locator.weight = weight;
11827           vec_add1 (locators, locator);
11828         }
11829       else
11830         break;
11831     }
11832
11833   if (locator_set_name_set == 0)
11834     {
11835       errmsg ("missing locator-set name");
11836       vec_free (locators);
11837       return -99;
11838     }
11839
11840   if (vec_len (locator_set_name) > 64)
11841     {
11842       errmsg ("locator-set name too long\n");
11843       vec_free (locator_set_name);
11844       vec_free (locators);
11845       return -99;
11846     }
11847   vec_add1 (locator_set_name, 0);
11848
11849   /* Construct the API message */
11850   M (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
11851
11852   mp->is_add = is_add;
11853   clib_memcpy (mp->locator_set_name, locator_set_name,
11854                vec_len (locator_set_name));
11855   vec_free (locator_set_name);
11856
11857   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
11858   if (locators)
11859     clib_memcpy (mp->locators, locators,
11860                  (sizeof (ls_locator_t) * vec_len (locators)));
11861   vec_free (locators);
11862
11863   /* send it... */
11864   S;
11865
11866   /* Wait for a reply... */
11867   W;
11868
11869   /* NOTREACHED */
11870   return 0;
11871 }
11872
11873 static int
11874 api_lisp_add_del_locator (vat_main_t * vam)
11875 {
11876   unformat_input_t *input = vam->input;
11877   vl_api_lisp_add_del_locator_t *mp;
11878   f64 timeout = ~0;
11879   u32 tmp_if_index = ~0;
11880   u32 sw_if_index = ~0;
11881   u8 sw_if_index_set = 0;
11882   u8 sw_if_index_if_name_set = 0;
11883   u32 priority = ~0;
11884   u8 priority_set = 0;
11885   u32 weight = ~0;
11886   u8 weight_set = 0;
11887   u8 is_add = 1;
11888   u8 *locator_set_name = NULL;
11889   u8 locator_set_name_set = 0;
11890
11891   /* Parse args required to build the message */
11892   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11893     {
11894       if (unformat (input, "del"))
11895         {
11896           is_add = 0;
11897         }
11898       else if (unformat (input, "locator-set %s", &locator_set_name))
11899         {
11900           locator_set_name_set = 1;
11901         }
11902       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
11903                          &tmp_if_index))
11904         {
11905           sw_if_index_if_name_set = 1;
11906           sw_if_index = tmp_if_index;
11907         }
11908       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
11909         {
11910           sw_if_index_set = 1;
11911           sw_if_index = tmp_if_index;
11912         }
11913       else if (unformat (input, "p %d", &priority))
11914         {
11915           priority_set = 1;
11916         }
11917       else if (unformat (input, "w %d", &weight))
11918         {
11919           weight_set = 1;
11920         }
11921       else
11922         break;
11923     }
11924
11925   if (locator_set_name_set == 0)
11926     {
11927       errmsg ("missing locator-set name");
11928       return -99;
11929     }
11930
11931   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
11932     {
11933       errmsg ("missing sw_if_index");
11934       vec_free (locator_set_name);
11935       return -99;
11936     }
11937
11938   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
11939     {
11940       errmsg ("cannot use both params interface name and sw_if_index");
11941       vec_free (locator_set_name);
11942       return -99;
11943     }
11944
11945   if (priority_set == 0)
11946     {
11947       errmsg ("missing locator-set priority\n");
11948       vec_free (locator_set_name);
11949       return -99;
11950     }
11951
11952   if (weight_set == 0)
11953     {
11954       errmsg ("missing locator-set weight\n");
11955       vec_free (locator_set_name);
11956       return -99;
11957     }
11958
11959   if (vec_len (locator_set_name) > 64)
11960     {
11961       errmsg ("locator-set name too long\n");
11962       vec_free (locator_set_name);
11963       return -99;
11964     }
11965   vec_add1 (locator_set_name, 0);
11966
11967   /* Construct the API message */
11968   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
11969
11970   mp->is_add = is_add;
11971   mp->sw_if_index = ntohl (sw_if_index);
11972   mp->priority = priority;
11973   mp->weight = weight;
11974   clib_memcpy (mp->locator_set_name, locator_set_name,
11975                vec_len (locator_set_name));
11976   vec_free (locator_set_name);
11977
11978   /* send it... */
11979   S;
11980
11981   /* Wait for a reply... */
11982   W;
11983
11984   /* NOTREACHED */
11985   return 0;
11986 }
11987
11988 static int
11989 api_lisp_add_del_local_eid (vat_main_t * vam)
11990 {
11991   unformat_input_t *input = vam->input;
11992   vl_api_lisp_add_del_local_eid_t *mp;
11993   f64 timeout = ~0;
11994   u8 is_add = 1;
11995   u8 eid_set = 0;
11996   lisp_eid_vat_t _eid, *eid = &_eid;
11997   u8 *locator_set_name = 0;
11998   u8 locator_set_name_set = 0;
11999   u32 vni = 0;
12000
12001   /* Parse args required to build the message */
12002   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12003     {
12004       if (unformat (input, "del"))
12005         {
12006           is_add = 0;
12007         }
12008       else if (unformat (input, "vni %d", &vni))
12009         {
12010           ;
12011         }
12012       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12013         {
12014           eid_set = 1;
12015         }
12016       else if (unformat (input, "locator-set %s", &locator_set_name))
12017         {
12018           locator_set_name_set = 1;
12019         }
12020       else
12021         break;
12022     }
12023
12024   if (locator_set_name_set == 0)
12025     {
12026       errmsg ("missing locator-set name\n");
12027       return -99;
12028     }
12029
12030   if (0 == eid_set)
12031     {
12032       errmsg ("EID address not set!");
12033       vec_free (locator_set_name);
12034       return -99;
12035     }
12036
12037   if (vec_len (locator_set_name) > 64)
12038     {
12039       errmsg ("locator-set name too long\n");
12040       vec_free (locator_set_name);
12041       return -99;
12042     }
12043   vec_add1 (locator_set_name, 0);
12044
12045   /* Construct the API message */
12046   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12047
12048   mp->is_add = is_add;
12049   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12050   mp->eid_type = eid->type;
12051   mp->prefix_len = eid->len;
12052   mp->vni = clib_host_to_net_u32 (vni);
12053   clib_memcpy (mp->locator_set_name, locator_set_name,
12054                vec_len (locator_set_name));
12055
12056   vec_free (locator_set_name);
12057
12058   /* send it... */
12059   S;
12060
12061   /* Wait for a reply... */
12062   W;
12063
12064   /* NOTREACHED */
12065   return 0;
12066 }
12067
12068 /* *INDENT-OFF* */
12069 /** Used for transferring locators via VPP API */
12070 typedef CLIB_PACKED(struct
12071 {
12072   u8 is_ip4; /**< is locator an IPv4 address? */
12073   u8 priority; /**< locator priority */
12074   u8 weight;   /**< locator weight */
12075   u8 addr[16]; /**< IPv4/IPv6 address */
12076 }) rloc_t;
12077 /* *INDENT-ON* */
12078
12079 static int
12080 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12081 {
12082   unformat_input_t *input = vam->input;
12083   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12084   f64 timeout = ~0;
12085   u8 is_add = 1;
12086   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12087   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12088   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12089   u32 action = ~0, p, w;
12090   ip4_address_t rmt_rloc4, lcl_rloc4;
12091   ip6_address_t rmt_rloc6, lcl_rloc6;
12092   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12093
12094   memset (&rloc, 0, sizeof (rloc));
12095
12096   /* Parse args required to build the message */
12097   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12098     {
12099       if (unformat (input, "del"))
12100         {
12101           is_add = 0;
12102         }
12103       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12104         {
12105           rmt_eid_set = 1;
12106         }
12107       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12108         {
12109           lcl_eid_set = 1;
12110         }
12111       else if (unformat (input, "p %d w %d", &p, &w))
12112         {
12113           if (!curr_rloc)
12114             {
12115               errmsg ("No RLOC configured for setting priority/weight!");
12116               return -99;
12117             }
12118           curr_rloc->priority = p;
12119           curr_rloc->weight = w;
12120         }
12121       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12122                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12123         {
12124           rloc.is_ip4 = 1;
12125
12126           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12127           rloc.priority = rloc.weight = 0;
12128           vec_add1 (lcl_locs, rloc);
12129
12130           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12131           vec_add1 (rmt_locs, rloc);
12132           /* priority and weight saved in rmt loc */
12133           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12134         }
12135       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12136                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12137         {
12138           rloc.is_ip4 = 0;
12139           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12140           rloc.priority = rloc.weight = 0;
12141           vec_add1 (lcl_locs, rloc);
12142
12143           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12144           vec_add1 (rmt_locs, rloc);
12145           /* priority and weight saved in rmt loc */
12146           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12147         }
12148       else if (unformat (input, "action %d", &action))
12149         {
12150           ;
12151         }
12152       else
12153         {
12154           clib_warning ("parse error '%U'", format_unformat_error, input);
12155           return -99;
12156         }
12157     }
12158
12159   if (!rmt_eid_set)
12160     {
12161       errmsg ("remote eid addresses not set\n");
12162       return -99;
12163     }
12164
12165   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12166     {
12167       errmsg ("eid types don't match\n");
12168       return -99;
12169     }
12170
12171   if (0 == rmt_locs && (u32) ~ 0 == action)
12172     {
12173       errmsg ("action not set for negative mapping\n");
12174       return -99;
12175     }
12176
12177   /* Construct the API message */
12178   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12179
12180   mp->is_add = is_add;
12181   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12182   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12183   mp->eid_type = rmt_eid->type;
12184   mp->rmt_len = rmt_eid->len;
12185   mp->lcl_len = lcl_eid->len;
12186   mp->action = action;
12187
12188   if (0 != rmt_locs && 0 != lcl_locs)
12189     {
12190       mp->loc_num = vec_len (rmt_locs);
12191       clib_memcpy (mp->lcl_locs, lcl_locs,
12192                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12193       clib_memcpy (mp->rmt_locs, rmt_locs,
12194                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12195     }
12196   vec_free (lcl_locs);
12197   vec_free (rmt_locs);
12198
12199   /* send it... */
12200   S;
12201
12202   /* Wait for a reply... */
12203   W;
12204
12205   /* NOTREACHED */
12206   return 0;
12207 }
12208
12209 static int
12210 api_lisp_add_del_map_resolver (vat_main_t * vam)
12211 {
12212   unformat_input_t *input = vam->input;
12213   vl_api_lisp_add_del_map_resolver_t *mp;
12214   f64 timeout = ~0;
12215   u8 is_add = 1;
12216   u8 ipv4_set = 0;
12217   u8 ipv6_set = 0;
12218   ip4_address_t ipv4;
12219   ip6_address_t ipv6;
12220
12221   /* Parse args required to build the message */
12222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12223     {
12224       if (unformat (input, "del"))
12225         {
12226           is_add = 0;
12227         }
12228       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12229         {
12230           ipv4_set = 1;
12231         }
12232       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12233         {
12234           ipv6_set = 1;
12235         }
12236       else
12237         break;
12238     }
12239
12240   if (ipv4_set && ipv6_set)
12241     {
12242       errmsg ("both eid v4 and v6 addresses set\n");
12243       return -99;
12244     }
12245
12246   if (!ipv4_set && !ipv6_set)
12247     {
12248       errmsg ("eid addresses not set\n");
12249       return -99;
12250     }
12251
12252   /* Construct the API message */
12253   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12254
12255   mp->is_add = is_add;
12256   if (ipv6_set)
12257     {
12258       mp->is_ipv6 = 1;
12259       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12260     }
12261   else
12262     {
12263       mp->is_ipv6 = 0;
12264       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12265     }
12266
12267   /* send it... */
12268   S;
12269
12270   /* Wait for a reply... */
12271   W;
12272
12273   /* NOTREACHED */
12274   return 0;
12275 }
12276
12277 static int
12278 api_lisp_gpe_enable_disable (vat_main_t * vam)
12279 {
12280   unformat_input_t *input = vam->input;
12281   vl_api_lisp_gpe_enable_disable_t *mp;
12282   f64 timeout = ~0;
12283   u8 is_set = 0;
12284   u8 is_en = 1;
12285
12286   /* Parse args required to build the message */
12287   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12288     {
12289       if (unformat (input, "enable"))
12290         {
12291           is_set = 1;
12292           is_en = 1;
12293         }
12294       else if (unformat (input, "disable"))
12295         {
12296           is_set = 1;
12297           is_en = 0;
12298         }
12299       else
12300         break;
12301     }
12302
12303   if (is_set == 0)
12304     {
12305       errmsg ("Value not set\n");
12306       return -99;
12307     }
12308
12309   /* Construct the API message */
12310   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12311
12312   mp->is_en = is_en;
12313
12314   /* send it... */
12315   S;
12316
12317   /* Wait for a reply... */
12318   W;
12319
12320   /* NOTREACHED */
12321   return 0;
12322 }
12323
12324 static int
12325 api_lisp_enable_disable (vat_main_t * vam)
12326 {
12327   unformat_input_t *input = vam->input;
12328   vl_api_lisp_enable_disable_t *mp;
12329   f64 timeout = ~0;
12330   u8 is_set = 0;
12331   u8 is_en = 0;
12332
12333   /* Parse args required to build the message */
12334   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12335     {
12336       if (unformat (input, "enable"))
12337         {
12338           is_set = 1;
12339           is_en = 1;
12340         }
12341       else if (unformat (input, "disable"))
12342         {
12343           is_set = 1;
12344         }
12345       else
12346         break;
12347     }
12348
12349   if (!is_set)
12350     {
12351       errmsg ("Value not set\n");
12352       return -99;
12353     }
12354
12355   /* Construct the API message */
12356   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12357
12358   mp->is_en = is_en;
12359
12360   /* send it... */
12361   S;
12362
12363   /* Wait for a reply... */
12364   W;
12365
12366   /* NOTREACHED */
12367   return 0;
12368 }
12369
12370 /**
12371  * Enable/disable LISP proxy ITR.
12372  *
12373  * @param vam vpp API test context
12374  * @return return code
12375  */
12376 static int
12377 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12378 {
12379   f64 timeout = ~0;
12380   u8 ls_name_set = 0;
12381   unformat_input_t *input = vam->input;
12382   vl_api_lisp_pitr_set_locator_set_t *mp;
12383   u8 is_add = 1;
12384   u8 *ls_name = 0;
12385
12386   /* Parse args required to build the message */
12387   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12388     {
12389       if (unformat (input, "del"))
12390         is_add = 0;
12391       else if (unformat (input, "locator-set %s", &ls_name))
12392         ls_name_set = 1;
12393       else
12394         {
12395           errmsg ("parse error '%U'", format_unformat_error, input);
12396           return -99;
12397         }
12398     }
12399
12400   if (!ls_name_set)
12401     {
12402       errmsg ("locator-set name not set!");
12403       return -99;
12404     }
12405
12406   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12407
12408   mp->is_add = is_add;
12409   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12410   vec_free (ls_name);
12411
12412   /* send */
12413   S;
12414
12415   /* wait for reply */
12416   W;
12417
12418   /* notreached */
12419   return 0;
12420 }
12421
12422 static int
12423 api_show_lisp_pitr (vat_main_t * vam)
12424 {
12425   vl_api_show_lisp_pitr_t *mp;
12426   f64 timeout = ~0;
12427
12428   if (!vam->json_output)
12429     {
12430       fformat (vam->ofp, "%=20s\n", "lisp status:");
12431     }
12432
12433   M (SHOW_LISP_PITR, show_lisp_pitr);
12434   /* send it... */
12435   S;
12436
12437   /* Wait for a reply... */
12438   W;
12439
12440   /* NOTREACHED */
12441   return 0;
12442 }
12443
12444 /**
12445  * Add/delete mapping between vni and vrf
12446  */
12447 static int
12448 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12449 {
12450   f64 timeout = ~0;
12451   unformat_input_t *input = vam->input;
12452   vl_api_lisp_eid_table_add_del_map_t *mp;
12453   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12454   u32 vni, vrf, bd_index;
12455
12456   /* Parse args required to build the message */
12457   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12458     {
12459       if (unformat (input, "del"))
12460         is_add = 0;
12461       else if (unformat (input, "vrf %d", &vrf))
12462         vrf_set = 1;
12463       else if (unformat (input, "bd_index %d", &bd_index))
12464         bd_index_set = 1;
12465       else if (unformat (input, "vni %d", &vni))
12466         vni_set = 1;
12467       else
12468         break;
12469     }
12470
12471   if (!vni_set || (!vrf_set && !bd_index_set))
12472     {
12473       errmsg ("missing arguments!");
12474       return -99;
12475     }
12476
12477   if (vrf_set && bd_index_set)
12478     {
12479       errmsg ("error: both vrf and bd entered!");
12480       return -99;
12481     }
12482
12483   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12484
12485   mp->is_add = is_add;
12486   mp->vni = htonl (vni);
12487   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
12488   mp->is_l2 = bd_index_set;
12489
12490   /* send */
12491   S;
12492
12493   /* wait for reply */
12494   W;
12495
12496   /* notreached */
12497   return 0;
12498 }
12499
12500 uword
12501 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
12502 {
12503   u32 *action = va_arg (*args, u32 *);
12504   u8 *s = 0;
12505
12506   if (unformat (input, "%s", &s))
12507     {
12508       if (!strcmp ((char *) s, "no-action"))
12509         action[0] = 0;
12510       else if (!strcmp ((char *) s, "natively-forward"))
12511         action[0] = 1;
12512       else if (!strcmp ((char *) s, "send-map-request"))
12513         action[0] = 2;
12514       else if (!strcmp ((char *) s, "drop"))
12515         action[0] = 3;
12516       else
12517         {
12518           clib_warning ("invalid action: '%s'", s);
12519           action[0] = 3;
12520         }
12521     }
12522   else
12523     return 0;
12524
12525   vec_free (s);
12526   return 1;
12527 }
12528
12529 /**
12530  * Add/del remote mapping to/from LISP control plane
12531  *
12532  * @param vam vpp API test context
12533  * @return return code
12534  */
12535 static int
12536 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12537 {
12538   unformat_input_t *input = vam->input;
12539   vl_api_lisp_add_del_remote_mapping_t *mp;
12540   f64 timeout = ~0;
12541   u32 vni = 0;
12542   lisp_eid_vat_t _eid, *eid = &_eid;
12543   lisp_eid_vat_t _seid, *seid = &_seid;
12544   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
12545   u32 action = ~0, p, w;
12546   ip4_address_t rloc4;
12547   ip6_address_t rloc6;
12548   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12549
12550   memset (&rloc, 0, sizeof (rloc));
12551
12552   /* Parse args required to build the message */
12553   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12554     {
12555       if (unformat (input, "del-all"))
12556         {
12557           del_all = 1;
12558         }
12559       else if (unformat (input, "del"))
12560         {
12561           is_add = 0;
12562         }
12563       else if (unformat (input, "add"))
12564         {
12565           is_add = 1;
12566         }
12567       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12568         {
12569           eid_set = 1;
12570         }
12571       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
12572         {
12573           seid_set = 1;
12574         }
12575       else if (unformat (input, "vni %d", &vni))
12576         {
12577           ;
12578         }
12579       else if (unformat (input, "p %d w %d", &p, &w))
12580         {
12581           if (!curr_rloc)
12582             {
12583               errmsg ("No RLOC configured for setting priority/weight!");
12584               return -99;
12585             }
12586           curr_rloc->priority = p;
12587           curr_rloc->weight = w;
12588         }
12589       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12590         {
12591           rloc.is_ip4 = 1;
12592           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12593           vec_add1 (rlocs, rloc);
12594           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12595         }
12596       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12597         {
12598           rloc.is_ip4 = 0;
12599           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12600           vec_add1 (rlocs, rloc);
12601           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12602         }
12603       else if (unformat (input, "action %U",
12604                          unformat_negative_mapping_action, &action))
12605         {
12606           ;
12607         }
12608       else
12609         {
12610           clib_warning ("parse error '%U'", format_unformat_error, input);
12611           return -99;
12612         }
12613     }
12614
12615   if (0 == eid_set)
12616     {
12617       errmsg ("missing params!");
12618       return -99;
12619     }
12620
12621   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12622     {
12623       errmsg ("no action set for negative map-reply!");
12624       return -99;
12625     }
12626
12627   M (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
12628   mp->is_add = is_add;
12629   mp->vni = htonl (vni);
12630   mp->action = (u8) action;
12631   mp->is_src_dst = seid_set;
12632   mp->eid_len = eid->len;
12633   mp->seid_len = seid->len;
12634   mp->del_all = del_all;
12635   mp->eid_type = eid->type;
12636   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12637   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
12638
12639   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
12640   clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
12641   vec_free (rlocs);
12642
12643   /* send it... */
12644   S;
12645
12646   /* Wait for a reply... */
12647   W;
12648
12649   /* NOTREACHED */
12650   return 0;
12651 }
12652
12653 /**
12654  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
12655  * forwarding entries in data-plane accordingly.
12656  *
12657  * @param vam vpp API test context
12658  * @return return code
12659  */
12660 static int
12661 api_lisp_add_del_adjacency (vat_main_t * vam)
12662 {
12663   unformat_input_t *input = vam->input;
12664   vl_api_lisp_add_del_adjacency_t *mp;
12665   f64 timeout = ~0;
12666   u32 vni = 0;
12667   ip4_address_t seid4, deid4;
12668   ip6_address_t seid6, deid6;
12669   u8 deid_mac[6] = { 0 };
12670   u8 seid_mac[6] = { 0 };
12671   u8 deid_type, seid_type;
12672   u32 seid_len = 0, deid_len = 0, len;
12673   u8 is_add = 1;
12674
12675   seid_type = deid_type = (u8) ~ 0;
12676
12677   /* Parse args required to build the message */
12678   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12679     {
12680       if (unformat (input, "del"))
12681         {
12682           is_add = 0;
12683         }
12684       else if (unformat (input, "add"))
12685         {
12686           is_add = 1;
12687         }
12688       else if (unformat (input, "deid %U/%d", unformat_ip4_address,
12689                          &deid4, &len))
12690         {
12691           deid_type = 0;        /* ipv4 */
12692           deid_len = len;
12693         }
12694       else if (unformat (input, "deid %U/%d", unformat_ip6_address,
12695                          &deid6, &len))
12696         {
12697           deid_type = 1;        /* ipv6 */
12698           deid_len = len;
12699         }
12700       else if (unformat (input, "deid %U", unformat_ethernet_address,
12701                          deid_mac))
12702         {
12703           deid_type = 2;        /* mac */
12704         }
12705       else if (unformat (input, "seid %U/%d", unformat_ip4_address,
12706                          &seid4, &len))
12707         {
12708           seid_type = 0;        /* ipv4 */
12709           seid_len = len;
12710         }
12711       else if (unformat (input, "seid %U/%d", unformat_ip6_address,
12712                          &seid6, &len))
12713         {
12714           seid_type = 1;        /* ipv6 */
12715           seid_len = len;
12716         }
12717       else if (unformat (input, "seid %U", unformat_ethernet_address,
12718                          seid_mac))
12719         {
12720           seid_type = 2;        /* mac */
12721         }
12722       else if (unformat (input, "vni %d", &vni))
12723         {
12724           ;
12725         }
12726       else
12727         {
12728           errmsg ("parse error '%U'", format_unformat_error, input);
12729           return -99;
12730         }
12731     }
12732
12733   if ((u8) ~ 0 == deid_type)
12734     {
12735       errmsg ("missing params!");
12736       return -99;
12737     }
12738
12739   if (seid_type != deid_type)
12740     {
12741       errmsg ("source and destination EIDs are of different types!");
12742       return -99;
12743     }
12744
12745   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
12746   mp->is_add = is_add;
12747   mp->vni = htonl (vni);
12748   mp->seid_len = seid_len;
12749   mp->deid_len = deid_len;
12750   mp->eid_type = deid_type;
12751
12752   switch (mp->eid_type)
12753     {
12754     case 0:
12755       clib_memcpy (mp->seid, &seid4, sizeof (seid4));
12756       clib_memcpy (mp->deid, &deid4, sizeof (deid4));
12757       break;
12758     case 1:
12759       clib_memcpy (mp->seid, &seid6, sizeof (seid6));
12760       clib_memcpy (mp->deid, &deid6, sizeof (deid6));
12761       break;
12762     case 2:
12763       clib_memcpy (mp->seid, seid_mac, 6);
12764       clib_memcpy (mp->deid, deid_mac, 6);
12765       break;
12766     default:
12767       errmsg ("unknown EID type %d!", mp->eid_type);
12768       return 0;
12769     }
12770
12771   /* send it... */
12772   S;
12773
12774   /* Wait for a reply... */
12775   W;
12776
12777   /* NOTREACHED */
12778   return 0;
12779 }
12780
12781 static int
12782 api_lisp_gpe_add_del_iface (vat_main_t * vam)
12783 {
12784   unformat_input_t *input = vam->input;
12785   vl_api_lisp_gpe_add_del_iface_t *mp;
12786   f64 timeout = ~0;
12787   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
12788   u32 dp_table = 0, vni = 0;
12789
12790   /* Parse args required to build the message */
12791   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12792     {
12793       if (unformat (input, "up"))
12794         {
12795           action_set = 1;
12796           is_add = 1;
12797         }
12798       else if (unformat (input, "down"))
12799         {
12800           action_set = 1;
12801           is_add = 0;
12802         }
12803       else if (unformat (input, "table_id %d", &dp_table))
12804         {
12805           dp_table_set = 1;
12806         }
12807       else if (unformat (input, "bd_id %d", &dp_table))
12808         {
12809           dp_table_set = 1;
12810           is_l2 = 1;
12811         }
12812       else if (unformat (input, "vni %d", &vni))
12813         {
12814           vni_set = 1;
12815         }
12816       else
12817         break;
12818     }
12819
12820   if (action_set == 0)
12821     {
12822       errmsg ("Action not set\n");
12823       return -99;
12824     }
12825   if (dp_table_set == 0 || vni_set == 0)
12826     {
12827       errmsg ("vni and dp_table must be set\n");
12828       return -99;
12829     }
12830
12831   /* Construct the API message */
12832   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
12833
12834   mp->is_add = is_add;
12835   mp->dp_table = dp_table;
12836   mp->is_l2 = is_l2;
12837   mp->vni = vni;
12838
12839   /* send it... */
12840   S;
12841
12842   /* Wait for a reply... */
12843   W;
12844
12845   /* NOTREACHED */
12846   return 0;
12847 }
12848
12849 /**
12850  * Add/del map request itr rlocs from LISP control plane and updates
12851  *
12852  * @param vam vpp API test context
12853  * @return return code
12854  */
12855 static int
12856 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
12857 {
12858   unformat_input_t *input = vam->input;
12859   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
12860   f64 timeout = ~0;
12861   u8 *locator_set_name = 0;
12862   u8 locator_set_name_set = 0;
12863   u8 is_add = 1;
12864
12865   /* Parse args required to build the message */
12866   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12867     {
12868       if (unformat (input, "del"))
12869         {
12870           is_add = 0;
12871         }
12872       else if (unformat (input, "%_%v%_", &locator_set_name))
12873         {
12874           locator_set_name_set = 1;
12875         }
12876       else
12877         {
12878           clib_warning ("parse error '%U'", format_unformat_error, input);
12879           return -99;
12880         }
12881     }
12882
12883   if (is_add && !locator_set_name_set)
12884     {
12885       errmsg ("itr-rloc is not set!");
12886       return -99;
12887     }
12888
12889   if (is_add && vec_len (locator_set_name) > 64)
12890     {
12891       errmsg ("itr-rloc locator-set name too long\n");
12892       vec_free (locator_set_name);
12893       return -99;
12894     }
12895
12896   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
12897   mp->is_add = is_add;
12898   if (is_add)
12899     {
12900       clib_memcpy (mp->locator_set_name, locator_set_name,
12901                    vec_len (locator_set_name));
12902     }
12903   else
12904     {
12905       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
12906     }
12907   vec_free (locator_set_name);
12908
12909   /* send it... */
12910   S;
12911
12912   /* Wait for a reply... */
12913   W;
12914
12915   /* NOTREACHED */
12916   return 0;
12917 }
12918
12919 static int
12920 api_lisp_locator_dump (vat_main_t * vam)
12921 {
12922   unformat_input_t *input = vam->input;
12923   vl_api_lisp_locator_dump_t *mp;
12924   f64 timeout = ~0;
12925   u8 is_index_set = 0, is_name_set = 0;
12926   u8 *ls_name = 0;
12927   u32 ls_index = ~0;
12928
12929   /* Parse args required to build the message */
12930   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12931     {
12932       if (unformat (input, "ls_name %_%v%_", &ls_name))
12933         {
12934           is_name_set = 1;
12935         }
12936       else if (unformat (input, "ls_index %d", &ls_index))
12937         {
12938           is_index_set = 1;
12939         }
12940       else
12941         {
12942           errmsg ("parse error '%U'", format_unformat_error, input);
12943           return -99;
12944         }
12945     }
12946
12947   if (!is_index_set && !is_name_set)
12948     {
12949       errmsg ("error: expected one of index or name!\n");
12950       return -99;
12951     }
12952
12953   if (is_index_set && is_name_set)
12954     {
12955       errmsg ("error: only one param expected!\n");
12956       return -99;
12957     }
12958
12959   if (!vam->json_output)
12960     {
12961       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
12962                "weight");
12963     }
12964
12965   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
12966   mp->is_index_set = is_index_set;
12967
12968   if (is_index_set)
12969     mp->ls_index = clib_host_to_net_u32 (ls_index);
12970   else
12971     {
12972       vec_add1 (ls_name, 0);
12973       strcpy ((char *) mp->ls_name, (char *) ls_name);
12974     }
12975
12976   /* send it... */
12977   S;
12978
12979   /* Use a control ping for synchronization */
12980   {
12981     vl_api_control_ping_t *mp;
12982     M (CONTROL_PING, control_ping);
12983     S;
12984   }
12985   /* Wait for a reply... */
12986   W;
12987
12988   /* NOTREACHED */
12989   return 0;
12990 }
12991
12992 static int
12993 api_lisp_locator_set_dump (vat_main_t * vam)
12994 {
12995   vl_api_lisp_locator_set_dump_t *mp;
12996   unformat_input_t *input = vam->input;
12997   f64 timeout = ~0;
12998   u8 filter = 0;
12999
13000   /* Parse args required to build the message */
13001   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13002     {
13003       if (unformat (input, "local"))
13004         {
13005           filter = 1;
13006         }
13007       else if (unformat (input, "remote"))
13008         {
13009           filter = 2;
13010         }
13011       else
13012         {
13013           errmsg ("parse error '%U'", format_unformat_error, input);
13014           return -99;
13015         }
13016     }
13017
13018   if (!vam->json_output)
13019     {
13020       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13021     }
13022
13023   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13024
13025   mp->filter = filter;
13026
13027   /* send it... */
13028   S;
13029
13030   /* Use a control ping for synchronization */
13031   {
13032     vl_api_control_ping_t *mp;
13033     M (CONTROL_PING, control_ping);
13034     S;
13035   }
13036   /* Wait for a reply... */
13037   W;
13038
13039   /* NOTREACHED */
13040   return 0;
13041 }
13042
13043 static int
13044 api_lisp_eid_table_map_dump (vat_main_t * vam)
13045 {
13046   u8 is_l2 = 0;
13047   u8 mode_set = 0;
13048   unformat_input_t *input = vam->input;
13049   vl_api_lisp_eid_table_map_dump_t *mp;
13050   f64 timeout = ~0;
13051
13052   /* Parse args required to build the message */
13053   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13054     {
13055       if (unformat (input, "l2"))
13056         {
13057           is_l2 = 1;
13058           mode_set = 1;
13059         }
13060       else if (unformat (input, "l3"))
13061         {
13062           is_l2 = 0;
13063           mode_set = 1;
13064         }
13065       else
13066         {
13067           errmsg ("parse error '%U'", format_unformat_error, input);
13068           return -99;
13069         }
13070     }
13071
13072   if (!mode_set)
13073     {
13074       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13075       return -99;
13076     }
13077
13078   if (!vam->json_output)
13079     {
13080       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13081     }
13082
13083   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13084   mp->is_l2 = is_l2;
13085
13086   /* send it... */
13087   S;
13088
13089   /* Use a control ping for synchronization */
13090   {
13091     vl_api_control_ping_t *mp;
13092     M (CONTROL_PING, control_ping);
13093     S;
13094   }
13095   /* Wait for a reply... */
13096   W;
13097
13098   /* NOTREACHED */
13099   return 0;
13100 }
13101
13102 static int
13103 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13104 {
13105   vl_api_lisp_eid_table_vni_dump_t *mp;
13106   f64 timeout = ~0;
13107
13108   if (!vam->json_output)
13109     {
13110       fformat (vam->ofp, "VNI\n");
13111     }
13112
13113   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13114
13115   /* send it... */
13116   S;
13117
13118   /* Use a control ping for synchronization */
13119   {
13120     vl_api_control_ping_t *mp;
13121     M (CONTROL_PING, control_ping);
13122     S;
13123   }
13124   /* Wait for a reply... */
13125   W;
13126
13127   /* NOTREACHED */
13128   return 0;
13129 }
13130
13131 static int
13132 api_lisp_eid_table_dump (vat_main_t * vam)
13133 {
13134   unformat_input_t *i = vam->input;
13135   vl_api_lisp_eid_table_dump_t *mp;
13136   f64 timeout = ~0;
13137   struct in_addr ip4;
13138   struct in6_addr ip6;
13139   u8 mac[6];
13140   u8 eid_type = ~0, eid_set = 0;
13141   u32 prefix_length = ~0, t, vni = 0;
13142   u8 filter = 0;
13143
13144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13145     {
13146       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13147         {
13148           eid_set = 1;
13149           eid_type = 0;
13150           prefix_length = t;
13151         }
13152       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13153         {
13154           eid_set = 1;
13155           eid_type = 1;
13156           prefix_length = t;
13157         }
13158       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13159         {
13160           eid_set = 1;
13161           eid_type = 2;
13162         }
13163       else if (unformat (i, "vni %d", &t))
13164         {
13165           vni = t;
13166         }
13167       else if (unformat (i, "local"))
13168         {
13169           filter = 1;
13170         }
13171       else if (unformat (i, "remote"))
13172         {
13173           filter = 2;
13174         }
13175       else
13176         {
13177           errmsg ("parse error '%U'", format_unformat_error, i);
13178           return -99;
13179         }
13180     }
13181
13182   if (!vam->json_output)
13183     {
13184       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
13185                "ls_index", "ttl", "authoritative");
13186     }
13187
13188   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13189
13190   mp->filter = filter;
13191   if (eid_set)
13192     {
13193       mp->eid_set = 1;
13194       mp->vni = htonl (vni);
13195       mp->eid_type = eid_type;
13196       switch (eid_type)
13197         {
13198         case 0:
13199           mp->prefix_length = prefix_length;
13200           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13201           break;
13202         case 1:
13203           mp->prefix_length = prefix_length;
13204           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13205           break;
13206         case 2:
13207           clib_memcpy (mp->eid, mac, sizeof (mac));
13208           break;
13209         default:
13210           errmsg ("unknown EID type %d!", eid_type);
13211           return -99;
13212         }
13213     }
13214
13215   /* send it... */
13216   S;
13217
13218   /* Use a control ping for synchronization */
13219   {
13220     vl_api_control_ping_t *mp;
13221     M (CONTROL_PING, control_ping);
13222     S;
13223   }
13224
13225   /* Wait for a reply... */
13226   W;
13227
13228   /* NOTREACHED */
13229   return 0;
13230 }
13231
13232 static int
13233 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13234 {
13235   vl_api_lisp_gpe_tunnel_dump_t *mp;
13236   f64 timeout = ~0;
13237
13238   if (!vam->json_output)
13239     {
13240       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13241                "%=16s%=16s%=16s%=16s%=16s\n",
13242                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13243                "Decap next", "Lisp version", "Flags", "Next protocol",
13244                "ver_res", "res", "iid");
13245     }
13246
13247   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13248   /* send it... */
13249   S;
13250
13251   /* Use a control ping for synchronization */
13252   {
13253     vl_api_control_ping_t *mp;
13254     M (CONTROL_PING, control_ping);
13255     S;
13256   }
13257   /* Wait for a reply... */
13258   W;
13259
13260   /* NOTREACHED */
13261   return 0;
13262 }
13263
13264 static int
13265 api_lisp_map_resolver_dump (vat_main_t * vam)
13266 {
13267   vl_api_lisp_map_resolver_dump_t *mp;
13268   f64 timeout = ~0;
13269
13270   if (!vam->json_output)
13271     {
13272       fformat (vam->ofp, "%=20s\n", "Map resolver");
13273     }
13274
13275   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13276   /* send it... */
13277   S;
13278
13279   /* Use a control ping for synchronization */
13280   {
13281     vl_api_control_ping_t *mp;
13282     M (CONTROL_PING, control_ping);
13283     S;
13284   }
13285   /* Wait for a reply... */
13286   W;
13287
13288   /* NOTREACHED */
13289   return 0;
13290 }
13291
13292 static int
13293 api_show_lisp_status (vat_main_t * vam)
13294 {
13295   vl_api_show_lisp_status_t *mp;
13296   f64 timeout = ~0;
13297
13298   if (!vam->json_output)
13299     {
13300       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13301     }
13302
13303   M (SHOW_LISP_STATUS, show_lisp_status);
13304   /* send it... */
13305   S;
13306   /* Wait for a reply... */
13307   W;
13308
13309   /* NOTREACHED */
13310   return 0;
13311 }
13312
13313 static int
13314 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13315 {
13316   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13317   f64 timeout = ~0;
13318
13319   if (!vam->json_output)
13320     {
13321       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13322     }
13323
13324   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13325   /* send it... */
13326   S;
13327   /* Wait for a reply... */
13328   W;
13329
13330   /* NOTREACHED */
13331   return 0;
13332 }
13333
13334 static int
13335 api_af_packet_create (vat_main_t * vam)
13336 {
13337   unformat_input_t *i = vam->input;
13338   vl_api_af_packet_create_t *mp;
13339   f64 timeout;
13340   u8 *host_if_name = 0;
13341   u8 hw_addr[6];
13342   u8 random_hw_addr = 1;
13343
13344   memset (hw_addr, 0, sizeof (hw_addr));
13345
13346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13347     {
13348       if (unformat (i, "name %s", &host_if_name))
13349         vec_add1 (host_if_name, 0);
13350       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13351         random_hw_addr = 0;
13352       else
13353         break;
13354     }
13355
13356   if (!vec_len (host_if_name))
13357     {
13358       errmsg ("host-interface name must be specified");
13359       return -99;
13360     }
13361
13362   if (vec_len (host_if_name) > 64)
13363     {
13364       errmsg ("host-interface name too long");
13365       return -99;
13366     }
13367
13368   M (AF_PACKET_CREATE, af_packet_create);
13369
13370   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13371   clib_memcpy (mp->hw_addr, hw_addr, 6);
13372   mp->use_random_hw_addr = random_hw_addr;
13373   vec_free (host_if_name);
13374
13375   S;
13376   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
13377   /* NOTREACHED */
13378   return 0;
13379 }
13380
13381 static int
13382 api_af_packet_delete (vat_main_t * vam)
13383 {
13384   unformat_input_t *i = vam->input;
13385   vl_api_af_packet_delete_t *mp;
13386   f64 timeout;
13387   u8 *host_if_name = 0;
13388
13389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13390     {
13391       if (unformat (i, "name %s", &host_if_name))
13392         vec_add1 (host_if_name, 0);
13393       else
13394         break;
13395     }
13396
13397   if (!vec_len (host_if_name))
13398     {
13399       errmsg ("host-interface name must be specified");
13400       return -99;
13401     }
13402
13403   if (vec_len (host_if_name) > 64)
13404     {
13405       errmsg ("host-interface name too long");
13406       return -99;
13407     }
13408
13409   M (AF_PACKET_DELETE, af_packet_delete);
13410
13411   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13412   vec_free (host_if_name);
13413
13414   S;
13415   W;
13416   /* NOTREACHED */
13417   return 0;
13418 }
13419
13420 static int
13421 api_policer_add_del (vat_main_t * vam)
13422 {
13423   unformat_input_t *i = vam->input;
13424   vl_api_policer_add_del_t *mp;
13425   f64 timeout;
13426   u8 is_add = 1;
13427   u8 *name = 0;
13428   u32 cir = 0;
13429   u32 eir = 0;
13430   u64 cb = 0;
13431   u64 eb = 0;
13432   u8 rate_type = 0;
13433   u8 round_type = 0;
13434   u8 type = 0;
13435   u8 color_aware = 0;
13436   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
13437
13438   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
13439   conform_action.dscp = 0;
13440   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
13441   exceed_action.dscp = 0;
13442   violate_action.action_type = SSE2_QOS_ACTION_DROP;
13443   violate_action.dscp = 0;
13444
13445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13446     {
13447       if (unformat (i, "del"))
13448         is_add = 0;
13449       else if (unformat (i, "name %s", &name))
13450         vec_add1 (name, 0);
13451       else if (unformat (i, "cir %u", &cir))
13452         ;
13453       else if (unformat (i, "eir %u", &eir))
13454         ;
13455       else if (unformat (i, "cb %u", &cb))
13456         ;
13457       else if (unformat (i, "eb %u", &eb))
13458         ;
13459       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
13460                          &rate_type))
13461         ;
13462       else if (unformat (i, "round_type %U", unformat_policer_round_type,
13463                          &round_type))
13464         ;
13465       else if (unformat (i, "type %U", unformat_policer_type, &type))
13466         ;
13467       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
13468                          &conform_action))
13469         ;
13470       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
13471                          &exceed_action))
13472         ;
13473       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
13474                          &violate_action))
13475         ;
13476       else if (unformat (i, "color-aware"))
13477         color_aware = 1;
13478       else
13479         break;
13480     }
13481
13482   if (!vec_len (name))
13483     {
13484       errmsg ("policer name must be specified");
13485       return -99;
13486     }
13487
13488   if (vec_len (name) > 64)
13489     {
13490       errmsg ("policer name too long");
13491       return -99;
13492     }
13493
13494   M (POLICER_ADD_DEL, policer_add_del);
13495
13496   clib_memcpy (mp->name, name, vec_len (name));
13497   vec_free (name);
13498   mp->is_add = is_add;
13499   mp->cir = cir;
13500   mp->eir = eir;
13501   mp->cb = cb;
13502   mp->eb = eb;
13503   mp->rate_type = rate_type;
13504   mp->round_type = round_type;
13505   mp->type = type;
13506   mp->conform_action_type = conform_action.action_type;
13507   mp->conform_dscp = conform_action.dscp;
13508   mp->exceed_action_type = exceed_action.action_type;
13509   mp->exceed_dscp = exceed_action.dscp;
13510   mp->violate_action_type = violate_action.action_type;
13511   mp->violate_dscp = violate_action.dscp;
13512   mp->color_aware = color_aware;
13513
13514   S;
13515   W;
13516   /* NOTREACHED */
13517   return 0;
13518 }
13519
13520 static int
13521 api_policer_dump (vat_main_t * vam)
13522 {
13523   unformat_input_t *i = vam->input;
13524   vl_api_policer_dump_t *mp;
13525   f64 timeout = ~0;
13526   u8 *match_name = 0;
13527   u8 match_name_valid = 0;
13528
13529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13530     {
13531       if (unformat (i, "name %s", &match_name))
13532         {
13533           vec_add1 (match_name, 0);
13534           match_name_valid = 1;
13535         }
13536       else
13537         break;
13538     }
13539
13540   M (POLICER_DUMP, policer_dump);
13541   mp->match_name_valid = match_name_valid;
13542   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
13543   vec_free (match_name);
13544   /* send it... */
13545   S;
13546
13547   /* Use a control ping for synchronization */
13548   {
13549     vl_api_control_ping_t *mp;
13550     M (CONTROL_PING, control_ping);
13551     S;
13552   }
13553   /* Wait for a reply... */
13554   W;
13555
13556   /* NOTREACHED */
13557   return 0;
13558 }
13559
13560 static int
13561 api_policer_classify_set_interface (vat_main_t * vam)
13562 {
13563   unformat_input_t *i = vam->input;
13564   vl_api_policer_classify_set_interface_t *mp;
13565   f64 timeout;
13566   u32 sw_if_index;
13567   int sw_if_index_set;
13568   u32 ip4_table_index = ~0;
13569   u32 ip6_table_index = ~0;
13570   u32 l2_table_index = ~0;
13571   u8 is_add = 1;
13572
13573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13574     {
13575       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
13576         sw_if_index_set = 1;
13577       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13578         sw_if_index_set = 1;
13579       else if (unformat (i, "del"))
13580         is_add = 0;
13581       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13582         ;
13583       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13584         ;
13585       else if (unformat (i, "l2-table %d", &l2_table_index))
13586         ;
13587       else
13588         {
13589           clib_warning ("parse error '%U'", format_unformat_error, i);
13590           return -99;
13591         }
13592     }
13593
13594   if (sw_if_index_set == 0)
13595     {
13596       errmsg ("missing interface name or sw_if_index\n");
13597       return -99;
13598     }
13599
13600   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
13601
13602   mp->sw_if_index = ntohl (sw_if_index);
13603   mp->ip4_table_index = ntohl (ip4_table_index);
13604   mp->ip6_table_index = ntohl (ip6_table_index);
13605   mp->l2_table_index = ntohl (l2_table_index);
13606   mp->is_add = is_add;
13607
13608   S;
13609   W;
13610   /* NOTREACHED */
13611   return 0;
13612 }
13613
13614 static int
13615 api_policer_classify_dump (vat_main_t * vam)
13616 {
13617   unformat_input_t *i = vam->input;
13618   vl_api_policer_classify_dump_t *mp;
13619   f64 timeout = ~0;
13620   u8 type = POLICER_CLASSIFY_N_TABLES;
13621
13622   if (unformat (i, "type %U", unformat_classify_table_type, &type))
13623     ;
13624   else
13625     {
13626       errmsg ("classify table type must be specified\n");
13627       return -99;
13628     }
13629
13630   if (!vam->json_output)
13631     {
13632       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
13633     }
13634
13635   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
13636   mp->type = type;
13637   /* send it... */
13638   S;
13639
13640   /* Use a control ping for synchronization */
13641   {
13642     vl_api_control_ping_t *mp;
13643     M (CONTROL_PING, control_ping);
13644     S;
13645   }
13646   /* Wait for a reply... */
13647   W;
13648
13649   /* NOTREACHED */
13650   return 0;
13651 }
13652
13653 static int
13654 api_netmap_create (vat_main_t * vam)
13655 {
13656   unformat_input_t *i = vam->input;
13657   vl_api_netmap_create_t *mp;
13658   f64 timeout;
13659   u8 *if_name = 0;
13660   u8 hw_addr[6];
13661   u8 random_hw_addr = 1;
13662   u8 is_pipe = 0;
13663   u8 is_master = 0;
13664
13665   memset (hw_addr, 0, sizeof (hw_addr));
13666
13667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13668     {
13669       if (unformat (i, "name %s", &if_name))
13670         vec_add1 (if_name, 0);
13671       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13672         random_hw_addr = 0;
13673       else if (unformat (i, "pipe"))
13674         is_pipe = 1;
13675       else if (unformat (i, "master"))
13676         is_master = 1;
13677       else if (unformat (i, "slave"))
13678         is_master = 0;
13679       else
13680         break;
13681     }
13682
13683   if (!vec_len (if_name))
13684     {
13685       errmsg ("interface name must be specified");
13686       return -99;
13687     }
13688
13689   if (vec_len (if_name) > 64)
13690     {
13691       errmsg ("interface name too long");
13692       return -99;
13693     }
13694
13695   M (NETMAP_CREATE, netmap_create);
13696
13697   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
13698   clib_memcpy (mp->hw_addr, hw_addr, 6);
13699   mp->use_random_hw_addr = random_hw_addr;
13700   mp->is_pipe = is_pipe;
13701   mp->is_master = is_master;
13702   vec_free (if_name);
13703
13704   S;
13705   W;
13706   /* NOTREACHED */
13707   return 0;
13708 }
13709
13710 static int
13711 api_netmap_delete (vat_main_t * vam)
13712 {
13713   unformat_input_t *i = vam->input;
13714   vl_api_netmap_delete_t *mp;
13715   f64 timeout;
13716   u8 *if_name = 0;
13717
13718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13719     {
13720       if (unformat (i, "name %s", &if_name))
13721         vec_add1 (if_name, 0);
13722       else
13723         break;
13724     }
13725
13726   if (!vec_len (if_name))
13727     {
13728       errmsg ("interface name must be specified");
13729       return -99;
13730     }
13731
13732   if (vec_len (if_name) > 64)
13733     {
13734       errmsg ("interface name too long");
13735       return -99;
13736     }
13737
13738   M (NETMAP_DELETE, netmap_delete);
13739
13740   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
13741   vec_free (if_name);
13742
13743   S;
13744   W;
13745   /* NOTREACHED */
13746   return 0;
13747 }
13748
13749 static void vl_api_mpls_gre_tunnel_details_t_handler
13750   (vl_api_mpls_gre_tunnel_details_t * mp)
13751 {
13752   vat_main_t *vam = &vat_main;
13753   i32 i;
13754   i32 len = ntohl (mp->nlabels);
13755
13756   if (mp->l2_only == 0)
13757     {
13758       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
13759                ntohl (mp->tunnel_index),
13760                format_ip4_address, &mp->tunnel_src,
13761                format_ip4_address, &mp->tunnel_dst,
13762                format_ip4_address, &mp->intfc_address,
13763                ntohl (mp->mask_width));
13764       for (i = 0; i < len; i++)
13765         {
13766           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
13767         }
13768       fformat (vam->ofp, "\n");
13769       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
13770                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
13771     }
13772   else
13773     {
13774       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
13775                ntohl (mp->tunnel_index),
13776                format_ip4_address, &mp->tunnel_src,
13777                format_ip4_address, &mp->tunnel_dst,
13778                format_ip4_address, &mp->intfc_address);
13779       for (i = 0; i < len; i++)
13780         {
13781           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
13782         }
13783       fformat (vam->ofp, "\n");
13784       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
13785                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
13786     }
13787 }
13788
13789 static void vl_api_mpls_gre_tunnel_details_t_handler_json
13790   (vl_api_mpls_gre_tunnel_details_t * mp)
13791 {
13792   vat_main_t *vam = &vat_main;
13793   vat_json_node_t *node = NULL;
13794   struct in_addr ip4;
13795   i32 i;
13796   i32 len = ntohl (mp->nlabels);
13797
13798   if (VAT_JSON_ARRAY != vam->json_tree.type)
13799     {
13800       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13801       vat_json_init_array (&vam->json_tree);
13802     }
13803   node = vat_json_array_add (&vam->json_tree);
13804
13805   vat_json_init_object (node);
13806   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
13807   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
13808   vat_json_object_add_ip4 (node, "intfc_address", ip4);
13809   vat_json_object_add_uint (node, "inner_fib_index",
13810                             ntohl (mp->inner_fib_index));
13811   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
13812   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
13813   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
13814   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
13815   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
13816   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
13817   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
13818   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
13819   vat_json_object_add_uint (node, "outer_fib_index",
13820                             ntohl (mp->outer_fib_index));
13821   vat_json_object_add_uint (node, "label_count", len);
13822   for (i = 0; i < len; i++)
13823     {
13824       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
13825     }
13826 }
13827
13828 static int
13829 api_mpls_gre_tunnel_dump (vat_main_t * vam)
13830 {
13831   vl_api_mpls_gre_tunnel_dump_t *mp;
13832   f64 timeout;
13833   i32 index = -1;
13834
13835   /* Parse args required to build the message */
13836   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
13837     {
13838       if (!unformat (vam->input, "tunnel_index %d", &index))
13839         {
13840           index = -1;
13841           break;
13842         }
13843     }
13844
13845   fformat (vam->ofp, "  tunnel_index %d\n", index);
13846
13847   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
13848   mp->tunnel_index = htonl (index);
13849   S;
13850
13851   /* Use a control ping for synchronization */
13852   {
13853     vl_api_control_ping_t *mp;
13854     M (CONTROL_PING, control_ping);
13855     S;
13856   }
13857   W;
13858 }
13859
13860 static void vl_api_mpls_eth_tunnel_details_t_handler
13861   (vl_api_mpls_eth_tunnel_details_t * mp)
13862 {
13863   vat_main_t *vam = &vat_main;
13864   i32 i;
13865   i32 len = ntohl (mp->nlabels);
13866
13867   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
13868            ntohl (mp->tunnel_index),
13869            format_ethernet_address, &mp->tunnel_dst_mac,
13870            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
13871   for (i = 0; i < len; i++)
13872     {
13873       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
13874     }
13875   fformat (vam->ofp, "\n");
13876   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
13877            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
13878 }
13879
13880 static void vl_api_mpls_eth_tunnel_details_t_handler_json
13881   (vl_api_mpls_eth_tunnel_details_t * mp)
13882 {
13883   vat_main_t *vam = &vat_main;
13884   vat_json_node_t *node = NULL;
13885   struct in_addr ip4;
13886   i32 i;
13887   i32 len = ntohl (mp->nlabels);
13888
13889   if (VAT_JSON_ARRAY != vam->json_tree.type)
13890     {
13891       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13892       vat_json_init_array (&vam->json_tree);
13893     }
13894   node = vat_json_array_add (&vam->json_tree);
13895
13896   vat_json_init_object (node);
13897   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
13898   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
13899   vat_json_object_add_ip4 (node, "intfc_address", ip4);
13900   vat_json_object_add_uint (node, "inner_fib_index",
13901                             ntohl (mp->inner_fib_index));
13902   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
13903   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
13904   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
13905   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
13906   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
13907                                    format (0, "%U", format_ethernet_address,
13908                                            &mp->tunnel_dst_mac));
13909   vat_json_object_add_uint (node, "tx_sw_if_index",
13910                             ntohl (mp->tx_sw_if_index));
13911   vat_json_object_add_uint (node, "label_count", len);
13912   for (i = 0; i < len; i++)
13913     {
13914       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
13915     }
13916 }
13917
13918 static int
13919 api_mpls_eth_tunnel_dump (vat_main_t * vam)
13920 {
13921   vl_api_mpls_eth_tunnel_dump_t *mp;
13922   f64 timeout;
13923   i32 index = -1;
13924
13925   /* Parse args required to build the message */
13926   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
13927     {
13928       if (!unformat (vam->input, "tunnel_index %d", &index))
13929         {
13930           index = -1;
13931           break;
13932         }
13933     }
13934
13935   fformat (vam->ofp, "  tunnel_index %d\n", index);
13936
13937   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
13938   mp->tunnel_index = htonl (index);
13939   S;
13940
13941   /* Use a control ping for synchronization */
13942   {
13943     vl_api_control_ping_t *mp;
13944     M (CONTROL_PING, control_ping);
13945     S;
13946   }
13947   W;
13948 }
13949
13950 static void vl_api_mpls_fib_encap_details_t_handler
13951   (vl_api_mpls_fib_encap_details_t * mp)
13952 {
13953   vat_main_t *vam = &vat_main;
13954   i32 i;
13955   i32 len = ntohl (mp->nlabels);
13956
13957   fformat (vam->ofp, "table %d, dest %U, label ",
13958            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
13959   for (i = 0; i < len; i++)
13960     {
13961       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
13962     }
13963   fformat (vam->ofp, "\n");
13964 }
13965
13966 static void vl_api_mpls_fib_encap_details_t_handler_json
13967   (vl_api_mpls_fib_encap_details_t * mp)
13968 {
13969   vat_main_t *vam = &vat_main;
13970   vat_json_node_t *node = NULL;
13971   i32 i;
13972   i32 len = ntohl (mp->nlabels);
13973   struct in_addr ip4;
13974
13975   if (VAT_JSON_ARRAY != vam->json_tree.type)
13976     {
13977       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13978       vat_json_init_array (&vam->json_tree);
13979     }
13980   node = vat_json_array_add (&vam->json_tree);
13981
13982   vat_json_init_object (node);
13983   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
13984   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
13985   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
13986   vat_json_object_add_ip4 (node, "dest", ip4);
13987   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
13988   vat_json_object_add_uint (node, "label_count", len);
13989   for (i = 0; i < len; i++)
13990     {
13991       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
13992     }
13993 }
13994
13995 static int
13996 api_mpls_fib_encap_dump (vat_main_t * vam)
13997 {
13998   vl_api_mpls_fib_encap_dump_t *mp;
13999   f64 timeout;
14000
14001   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14002   S;
14003
14004   /* Use a control ping for synchronization */
14005   {
14006     vl_api_control_ping_t *mp;
14007     M (CONTROL_PING, control_ping);
14008     S;
14009   }
14010   W;
14011 }
14012
14013 static void vl_api_mpls_fib_decap_details_t_handler
14014   (vl_api_mpls_fib_decap_details_t * mp)
14015 {
14016   vat_main_t *vam = &vat_main;
14017
14018   fformat (vam->ofp,
14019            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14020            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14021            ntohl (mp->label), ntohl (mp->s_bit));
14022 }
14023
14024 static void vl_api_mpls_fib_decap_details_t_handler_json
14025   (vl_api_mpls_fib_decap_details_t * mp)
14026 {
14027   vat_main_t *vam = &vat_main;
14028   vat_json_node_t *node = NULL;
14029   struct in_addr ip4;
14030
14031   if (VAT_JSON_ARRAY != vam->json_tree.type)
14032     {
14033       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14034       vat_json_init_array (&vam->json_tree);
14035     }
14036   node = vat_json_array_add (&vam->json_tree);
14037
14038   vat_json_init_object (node);
14039   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14040   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14041   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14042   vat_json_object_add_ip4 (node, "dest", ip4);
14043   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14044   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14045   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14046   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14047   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14048 }
14049
14050 static int
14051 api_mpls_fib_decap_dump (vat_main_t * vam)
14052 {
14053   vl_api_mpls_fib_decap_dump_t *mp;
14054   f64 timeout;
14055
14056   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14057   S;
14058
14059   /* Use a control ping for synchronization */
14060   {
14061     vl_api_control_ping_t *mp;
14062     M (CONTROL_PING, control_ping);
14063     S;
14064   }
14065   W;
14066 }
14067
14068 int
14069 api_classify_table_ids (vat_main_t * vam)
14070 {
14071   vl_api_classify_table_ids_t *mp;
14072   f64 timeout;
14073
14074   /* Construct the API message */
14075   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14076   mp->context = 0;
14077
14078   S;
14079   W;
14080   /* NOTREACHED */
14081   return 0;
14082 }
14083
14084 int
14085 api_classify_table_by_interface (vat_main_t * vam)
14086 {
14087   unformat_input_t *input = vam->input;
14088   vl_api_classify_table_by_interface_t *mp;
14089   f64 timeout;
14090
14091   u32 sw_if_index = ~0;
14092   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14093     {
14094       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14095         ;
14096       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14097         ;
14098       else
14099         break;
14100     }
14101   if (sw_if_index == ~0)
14102     {
14103       errmsg ("missing interface name or sw_if_index\n");
14104       return -99;
14105     }
14106
14107   /* Construct the API message */
14108   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14109   mp->context = 0;
14110   mp->sw_if_index = ntohl (sw_if_index);
14111
14112   S;
14113   W;
14114   /* NOTREACHED */
14115   return 0;
14116 }
14117
14118 int
14119 api_classify_table_info (vat_main_t * vam)
14120 {
14121   unformat_input_t *input = vam->input;
14122   vl_api_classify_table_info_t *mp;
14123   f64 timeout;
14124
14125   u32 table_id = ~0;
14126   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14127     {
14128       if (unformat (input, "table_id %d", &table_id))
14129         ;
14130       else
14131         break;
14132     }
14133   if (table_id == ~0)
14134     {
14135       errmsg ("missing table id\n");
14136       return -99;
14137     }
14138
14139   /* Construct the API message */
14140   M (CLASSIFY_TABLE_INFO, classify_table_info);
14141   mp->context = 0;
14142   mp->table_id = ntohl (table_id);
14143
14144   S;
14145   W;
14146   /* NOTREACHED */
14147   return 0;
14148 }
14149
14150 int
14151 api_classify_session_dump (vat_main_t * vam)
14152 {
14153   unformat_input_t *input = vam->input;
14154   vl_api_classify_session_dump_t *mp;
14155   f64 timeout;
14156
14157   u32 table_id = ~0;
14158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14159     {
14160       if (unformat (input, "table_id %d", &table_id))
14161         ;
14162       else
14163         break;
14164     }
14165   if (table_id == ~0)
14166     {
14167       errmsg ("missing table id\n");
14168       return -99;
14169     }
14170
14171   /* Construct the API message */
14172   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14173   mp->context = 0;
14174   mp->table_id = ntohl (table_id);
14175   S;
14176
14177   /* Use a control ping for synchronization */
14178   {
14179     vl_api_control_ping_t *mp;
14180     M (CONTROL_PING, control_ping);
14181     S;
14182   }
14183   W;
14184   /* NOTREACHED */
14185   return 0;
14186 }
14187
14188 static void
14189 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
14190 {
14191   vat_main_t *vam = &vat_main;
14192
14193   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14194            "src_address %U, vrf_id %d, path_mtu %u, "
14195            "template_interval %u, udp_checksum %d\n",
14196            format_ip4_address, mp->collector_address,
14197            ntohs (mp->collector_port),
14198            format_ip4_address, mp->src_address,
14199            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
14200            ntohl (mp->template_interval), mp->udp_checksum);
14201
14202   vam->retval = 0;
14203   vam->result_ready = 1;
14204 }
14205
14206 static void
14207   vl_api_ipfix_exporter_details_t_handler_json
14208   (vl_api_ipfix_exporter_details_t * mp)
14209 {
14210   vat_main_t *vam = &vat_main;
14211   vat_json_node_t node;
14212   struct in_addr collector_address;
14213   struct in_addr src_address;
14214
14215   vat_json_init_object (&node);
14216   clib_memcpy (&collector_address, &mp->collector_address,
14217                sizeof (collector_address));
14218   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14219   vat_json_object_add_uint (&node, "collector_port",
14220                             ntohs (mp->collector_port));
14221   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14222   vat_json_object_add_ip4 (&node, "src_address", src_address);
14223   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
14224   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14225   vat_json_object_add_uint (&node, "template_interval",
14226                             ntohl (mp->template_interval));
14227   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
14228
14229   vat_json_print (vam->ofp, &node);
14230   vat_json_free (&node);
14231   vam->retval = 0;
14232   vam->result_ready = 1;
14233 }
14234
14235 int
14236 api_ipfix_exporter_dump (vat_main_t * vam)
14237 {
14238   vl_api_ipfix_exporter_dump_t *mp;
14239   f64 timeout;
14240
14241   /* Construct the API message */
14242   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
14243   mp->context = 0;
14244
14245   S;
14246   W;
14247   /* NOTREACHED */
14248   return 0;
14249 }
14250
14251 static int
14252 api_ipfix_classify_stream_dump (vat_main_t * vam)
14253 {
14254   vl_api_ipfix_classify_stream_dump_t *mp;
14255   f64 timeout;
14256
14257   /* Construct the API message */
14258   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
14259   mp->context = 0;
14260
14261   S;
14262   W;
14263   /* NOTREACHED */
14264   return 0;
14265 }
14266
14267 static void
14268   vl_api_ipfix_classify_stream_details_t_handler
14269   (vl_api_ipfix_classify_stream_details_t * mp)
14270 {
14271   vat_main_t *vam = &vat_main;
14272   fformat (vam->ofp, "domain_id %d, src_port %d\n",
14273            ntohl (mp->domain_id), ntohs (mp->src_port));
14274   vam->retval = 0;
14275   vam->result_ready = 1;
14276 }
14277
14278 static void
14279   vl_api_ipfix_classify_stream_details_t_handler_json
14280   (vl_api_ipfix_classify_stream_details_t * mp)
14281 {
14282   vat_main_t *vam = &vat_main;
14283   vat_json_node_t node;
14284
14285   vat_json_init_object (&node);
14286   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
14287   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
14288
14289   vat_json_print (vam->ofp, &node);
14290   vat_json_free (&node);
14291   vam->retval = 0;
14292   vam->result_ready = 1;
14293 }
14294
14295 static int
14296 api_ipfix_classify_table_dump (vat_main_t * vam)
14297 {
14298   vl_api_ipfix_classify_table_dump_t *mp;
14299   f64 timeout;
14300
14301   if (!vam->json_output)
14302     {
14303       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
14304                "transport_protocol");
14305     }
14306
14307   /* Construct the API message */
14308   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
14309
14310   /* send it... */
14311   S;
14312
14313   /* Use a control ping for synchronization */
14314   {
14315     vl_api_control_ping_t *mp;
14316     M (CONTROL_PING, control_ping);
14317     S;
14318   }
14319   W;
14320 }
14321
14322 static void
14323   vl_api_ipfix_classify_table_details_t_handler
14324   (vl_api_ipfix_classify_table_details_t * mp)
14325 {
14326   vat_main_t *vam = &vat_main;
14327   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
14328            mp->transport_protocol);
14329 }
14330
14331 static void
14332   vl_api_ipfix_classify_table_details_t_handler_json
14333   (vl_api_ipfix_classify_table_details_t * mp)
14334 {
14335   vat_json_node_t *node = NULL;
14336   vat_main_t *vam = &vat_main;
14337
14338   if (VAT_JSON_ARRAY != vam->json_tree.type)
14339     {
14340       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14341       vat_json_init_array (&vam->json_tree);
14342     }
14343
14344   node = vat_json_array_add (&vam->json_tree);
14345   vat_json_init_object (node);
14346
14347   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
14348   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
14349   vat_json_object_add_uint (node, "transport_protocol",
14350                             mp->transport_protocol);
14351 }
14352
14353 int
14354 api_pg_create_interface (vat_main_t * vam)
14355 {
14356   unformat_input_t *input = vam->input;
14357   vl_api_pg_create_interface_t *mp;
14358   f64 timeout;
14359
14360   u32 if_id = ~0;
14361   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14362     {
14363       if (unformat (input, "if_id %d", &if_id))
14364         ;
14365       else
14366         break;
14367     }
14368   if (if_id == ~0)
14369     {
14370       errmsg ("missing pg interface index\n");
14371       return -99;
14372     }
14373
14374   /* Construct the API message */
14375   M (PG_CREATE_INTERFACE, pg_create_interface);
14376   mp->context = 0;
14377   mp->interface_id = ntohl (if_id);
14378
14379   S;
14380   W;
14381   /* NOTREACHED */
14382   return 0;
14383 }
14384
14385 int
14386 api_pg_capture (vat_main_t * vam)
14387 {
14388   unformat_input_t *input = vam->input;
14389   vl_api_pg_capture_t *mp;
14390   f64 timeout;
14391
14392   u32 if_id = ~0;
14393   u8 enable = 1;
14394   u32 count = 1;
14395   u8 pcap_file_set = 0;
14396   u8 *pcap_file = 0;
14397   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14398     {
14399       if (unformat (input, "if_id %d", &if_id))
14400         ;
14401       else if (unformat (input, "pcap %s", &pcap_file))
14402         pcap_file_set = 1;
14403       else if (unformat (input, "count %d", &count))
14404         ;
14405       else if (unformat (input, "disable"))
14406         enable = 0;
14407       else
14408         break;
14409     }
14410   if (if_id == ~0)
14411     {
14412       errmsg ("missing pg interface index\n");
14413       return -99;
14414     }
14415   if (pcap_file_set > 0)
14416     {
14417       if (vec_len (pcap_file) > 255)
14418         {
14419           errmsg ("pcap file name is too long\n");
14420           return -99;
14421         }
14422     }
14423
14424   u32 name_len = vec_len (pcap_file);
14425   /* Construct the API message */
14426   M (PG_CAPTURE, pg_capture);
14427   mp->context = 0;
14428   mp->interface_id = ntohl (if_id);
14429   mp->is_enabled = enable;
14430   mp->count = ntohl (count);
14431   mp->pcap_name_length = ntohl (name_len);
14432   if (pcap_file_set != 0)
14433     {
14434       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
14435     }
14436   vec_free (pcap_file);
14437
14438   S;
14439   W;
14440   /* NOTREACHED */
14441   return 0;
14442 }
14443
14444 int
14445 api_pg_enable_disable (vat_main_t * vam)
14446 {
14447   unformat_input_t *input = vam->input;
14448   vl_api_pg_enable_disable_t *mp;
14449   f64 timeout;
14450
14451   u8 enable = 1;
14452   u8 stream_name_set = 0;
14453   u8 *stream_name = 0;
14454   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14455     {
14456       if (unformat (input, "stream %s", &stream_name))
14457         stream_name_set = 1;
14458       else if (unformat (input, "disable"))
14459         enable = 0;
14460       else
14461         break;
14462     }
14463
14464   if (stream_name_set > 0)
14465     {
14466       if (vec_len (stream_name) > 255)
14467         {
14468           errmsg ("stream name too long\n");
14469           return -99;
14470         }
14471     }
14472
14473   u32 name_len = vec_len (stream_name);
14474   /* Construct the API message */
14475   M (PG_ENABLE_DISABLE, pg_enable_disable);
14476   mp->context = 0;
14477   mp->is_enabled = enable;
14478   if (stream_name_set != 0)
14479     {
14480       mp->stream_name_length = ntohl (name_len);
14481       clib_memcpy (mp->stream_name, stream_name, name_len);
14482     }
14483   vec_free (stream_name);
14484
14485   S;
14486   W;
14487   /* NOTREACHED */
14488   return 0;
14489 }
14490
14491 int
14492 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
14493 {
14494   unformat_input_t *input = vam->input;
14495   vl_api_ip_source_and_port_range_check_add_del_t *mp;
14496   f64 timeout;
14497
14498   u16 *low_ports = 0;
14499   u16 *high_ports = 0;
14500   u16 this_low;
14501   u16 this_hi;
14502   ip4_address_t ip4_addr;
14503   ip6_address_t ip6_addr;
14504   u32 length;
14505   u32 tmp, tmp2;
14506   u8 prefix_set = 0;
14507   u32 vrf_id = ~0;
14508   u8 is_add = 1;
14509   u8 is_ipv6 = 0;
14510
14511   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14512     {
14513       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
14514         {
14515           prefix_set = 1;
14516         }
14517       else
14518         if (unformat
14519             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
14520         {
14521           prefix_set = 1;
14522           is_ipv6 = 1;
14523         }
14524       else if (unformat (input, "vrf %d", &vrf_id))
14525         ;
14526       else if (unformat (input, "del"))
14527         is_add = 0;
14528       else if (unformat (input, "port %d", &tmp))
14529         {
14530           if (tmp == 0 || tmp > 65535)
14531             {
14532               errmsg ("port %d out of range", tmp);
14533               return -99;
14534             }
14535           this_low = tmp;
14536           this_hi = this_low + 1;
14537           vec_add1 (low_ports, this_low);
14538           vec_add1 (high_ports, this_hi);
14539         }
14540       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
14541         {
14542           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
14543             {
14544               errmsg ("incorrect range parameters\n");
14545               return -99;
14546             }
14547           this_low = tmp;
14548           /* Note: in debug CLI +1 is added to high before
14549              passing to real fn that does "the work"
14550              (ip_source_and_port_range_check_add_del).
14551              This fn is a wrapper around the binary API fn a
14552              control plane will call, which expects this increment
14553              to have occurred. Hence letting the binary API control
14554              plane fn do the increment for consistency between VAT
14555              and other control planes.
14556            */
14557           this_hi = tmp2;
14558           vec_add1 (low_ports, this_low);
14559           vec_add1 (high_ports, this_hi);
14560         }
14561       else
14562         break;
14563     }
14564
14565   if (prefix_set == 0)
14566     {
14567       errmsg ("<address>/<mask> not specified\n");
14568       return -99;
14569     }
14570
14571   if (vrf_id == ~0)
14572     {
14573       errmsg ("VRF ID required, not specified\n");
14574       return -99;
14575     }
14576
14577   if (vrf_id == 0)
14578     {
14579       errmsg
14580         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
14581       return -99;
14582     }
14583
14584   if (vec_len (low_ports) == 0)
14585     {
14586       errmsg ("At least one port or port range required\n");
14587       return -99;
14588     }
14589
14590   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
14591      ip_source_and_port_range_check_add_del);
14592
14593   mp->is_add = is_add;
14594
14595   if (is_ipv6)
14596     {
14597       mp->is_ipv6 = 1;
14598       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
14599     }
14600   else
14601     {
14602       mp->is_ipv6 = 0;
14603       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
14604     }
14605
14606   mp->mask_length = length;
14607   mp->number_of_ranges = vec_len (low_ports);
14608
14609   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
14610   vec_free (low_ports);
14611
14612   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
14613   vec_free (high_ports);
14614
14615   mp->vrf_id = ntohl (vrf_id);
14616
14617   S;
14618   W;
14619   /* NOTREACHED */
14620   return 0;
14621 }
14622
14623 int
14624 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
14625 {
14626   unformat_input_t *input = vam->input;
14627   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
14628   f64 timeout;
14629   u32 sw_if_index = ~0;
14630   int vrf_set = 0;
14631   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
14632   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
14633   u8 is_add = 1;
14634
14635   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14636     {
14637       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14638         ;
14639       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14640         ;
14641       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
14642         vrf_set = 1;
14643       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
14644         vrf_set = 1;
14645       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
14646         vrf_set = 1;
14647       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
14648         vrf_set = 1;
14649       else if (unformat (input, "del"))
14650         is_add = 0;
14651       else
14652         break;
14653     }
14654
14655   if (sw_if_index == ~0)
14656     {
14657       errmsg ("Interface required but not specified\n");
14658       return -99;
14659     }
14660
14661   if (vrf_set == 0)
14662     {
14663       errmsg ("VRF ID required but not specified\n");
14664       return -99;
14665     }
14666
14667   if (tcp_out_vrf_id == 0
14668       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
14669     {
14670       errmsg
14671         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
14672       return -99;
14673     }
14674
14675   /* Construct the API message */
14676   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
14677      ip_source_and_port_range_check_interface_add_del);
14678
14679   mp->sw_if_index = ntohl (sw_if_index);
14680   mp->is_add = is_add;
14681   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
14682   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
14683   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
14684   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
14685
14686   /* send it... */
14687   S;
14688
14689   /* Wait for a reply... */
14690   W;
14691 }
14692
14693 static int
14694 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
14695 {
14696   unformat_input_t *i = vam->input;
14697   vl_api_ipsec_gre_add_del_tunnel_t *mp;
14698   f64 timeout;
14699   u32 local_sa_id = 0;
14700   u32 remote_sa_id = 0;
14701   ip4_address_t src_address;
14702   ip4_address_t dst_address;
14703   u8 is_add = 1;
14704
14705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14706     {
14707       if (unformat (i, "local_sa %d", &local_sa_id))
14708         ;
14709       else if (unformat (i, "remote_sa %d", &remote_sa_id))
14710         ;
14711       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
14712         ;
14713       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
14714         ;
14715       else if (unformat (i, "del"))
14716         is_add = 0;
14717       else
14718         {
14719           clib_warning ("parse error '%U'", format_unformat_error, i);
14720           return -99;
14721         }
14722     }
14723
14724   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
14725
14726   mp->local_sa_id = ntohl (local_sa_id);
14727   mp->remote_sa_id = ntohl (remote_sa_id);
14728   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
14729   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
14730   mp->is_add = is_add;
14731
14732   S;
14733   W;
14734   /* NOTREACHED */
14735   return 0;
14736 }
14737
14738 static void vl_api_ipsec_gre_tunnel_details_t_handler
14739   (vl_api_ipsec_gre_tunnel_details_t * mp)
14740 {
14741   vat_main_t *vam = &vat_main;
14742
14743   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
14744            ntohl (mp->sw_if_index),
14745            format_ip4_address, &mp->src_address,
14746            format_ip4_address, &mp->dst_address,
14747            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
14748 }
14749
14750 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
14751   (vl_api_ipsec_gre_tunnel_details_t * mp)
14752 {
14753   vat_main_t *vam = &vat_main;
14754   vat_json_node_t *node = NULL;
14755   struct in_addr ip4;
14756
14757   if (VAT_JSON_ARRAY != vam->json_tree.type)
14758     {
14759       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14760       vat_json_init_array (&vam->json_tree);
14761     }
14762   node = vat_json_array_add (&vam->json_tree);
14763
14764   vat_json_init_object (node);
14765   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14766   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
14767   vat_json_object_add_ip4 (node, "src_address", ip4);
14768   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
14769   vat_json_object_add_ip4 (node, "dst_address", ip4);
14770   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
14771   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
14772 }
14773
14774 static int
14775 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
14776 {
14777   unformat_input_t *i = vam->input;
14778   vl_api_ipsec_gre_tunnel_dump_t *mp;
14779   f64 timeout;
14780   u32 sw_if_index;
14781   u8 sw_if_index_set = 0;
14782
14783   /* Parse args required to build the message */
14784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14785     {
14786       if (unformat (i, "sw_if_index %d", &sw_if_index))
14787         sw_if_index_set = 1;
14788       else
14789         break;
14790     }
14791
14792   if (sw_if_index_set == 0)
14793     {
14794       sw_if_index = ~0;
14795     }
14796
14797   if (!vam->json_output)
14798     {
14799       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
14800                "sw_if_index", "src_address", "dst_address",
14801                "local_sa_id", "remote_sa_id");
14802     }
14803
14804   /* Get list of gre-tunnel interfaces */
14805   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
14806
14807   mp->sw_if_index = htonl (sw_if_index);
14808
14809   S;
14810
14811   /* Use a control ping for synchronization */
14812   {
14813     vl_api_control_ping_t *mp;
14814     M (CONTROL_PING, control_ping);
14815     S;
14816   }
14817   W;
14818 }
14819
14820 static int
14821 api_delete_subif (vat_main_t * vam)
14822 {
14823   unformat_input_t *i = vam->input;
14824   vl_api_delete_subif_t *mp;
14825   f64 timeout;
14826   u32 sw_if_index = ~0;
14827
14828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14829     {
14830       if (unformat (i, "sw_if_index %d", &sw_if_index))
14831         ;
14832       else
14833         break;
14834     }
14835
14836   if (sw_if_index == ~0)
14837     {
14838       errmsg ("missing sw_if_index\n");
14839       return -99;
14840     }
14841
14842   /* Construct the API message */
14843   M (DELETE_SUBIF, delete_subif);
14844   mp->sw_if_index = ntohl (sw_if_index);
14845
14846   S;
14847   W;
14848 }
14849
14850 static int
14851 q_or_quit (vat_main_t * vam)
14852 {
14853   longjmp (vam->jump_buf, 1);
14854   return 0;                     /* not so much */
14855 }
14856
14857 static int
14858 q (vat_main_t * vam)
14859 {
14860   return q_or_quit (vam);
14861 }
14862
14863 static int
14864 quit (vat_main_t * vam)
14865 {
14866   return q_or_quit (vam);
14867 }
14868
14869 static int
14870 comment (vat_main_t * vam)
14871 {
14872   return 0;
14873 }
14874
14875 static int
14876 cmd_cmp (void *a1, void *a2)
14877 {
14878   u8 **c1 = a1;
14879   u8 **c2 = a2;
14880
14881   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
14882 }
14883
14884 static int
14885 help (vat_main_t * vam)
14886 {
14887   u8 **cmds = 0;
14888   u8 *name = 0;
14889   hash_pair_t *p;
14890   unformat_input_t *i = vam->input;
14891   int j;
14892
14893   if (unformat (i, "%s", &name))
14894     {
14895       uword *hs;
14896
14897       vec_add1 (name, 0);
14898
14899       hs = hash_get_mem (vam->help_by_name, name);
14900       if (hs)
14901         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
14902       else
14903         fformat (vam->ofp, "No such msg / command '%s'\n", name);
14904       vec_free (name);
14905       return 0;
14906     }
14907
14908   fformat (vam->ofp, "Help is available for the following:\n");
14909
14910     /* *INDENT-OFF* */
14911     hash_foreach_pair (p, vam->function_by_name,
14912     ({
14913       vec_add1 (cmds, (u8 *)(p->key));
14914     }));
14915     /* *INDENT-ON* */
14916
14917   vec_sort_with_function (cmds, cmd_cmp);
14918
14919   for (j = 0; j < vec_len (cmds); j++)
14920     fformat (vam->ofp, "%s\n", cmds[j]);
14921
14922   vec_free (cmds);
14923   return 0;
14924 }
14925
14926 static int
14927 set (vat_main_t * vam)
14928 {
14929   u8 *name = 0, *value = 0;
14930   unformat_input_t *i = vam->input;
14931
14932   if (unformat (i, "%s", &name))
14933     {
14934       /* The input buffer is a vector, not a string. */
14935       value = vec_dup (i->buffer);
14936       vec_delete (value, i->index, 0);
14937       /* Almost certainly has a trailing newline */
14938       if (value[vec_len (value) - 1] == '\n')
14939         value[vec_len (value) - 1] = 0;
14940       /* Make sure it's a proper string, one way or the other */
14941       vec_add1 (value, 0);
14942       (void) clib_macro_set_value (&vam->macro_main,
14943                                    (char *) name, (char *) value);
14944     }
14945   else
14946     errmsg ("usage: set <name> <value>\n");
14947
14948   vec_free (name);
14949   vec_free (value);
14950   return 0;
14951 }
14952
14953 static int
14954 unset (vat_main_t * vam)
14955 {
14956   u8 *name = 0;
14957
14958   if (unformat (vam->input, "%s", &name))
14959     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
14960       errmsg ("unset: %s wasn't set\n", name);
14961   vec_free (name);
14962   return 0;
14963 }
14964
14965 typedef struct
14966 {
14967   u8 *name;
14968   u8 *value;
14969 } macro_sort_t;
14970
14971
14972 static int
14973 macro_sort_cmp (void *a1, void *a2)
14974 {
14975   macro_sort_t *s1 = a1;
14976   macro_sort_t *s2 = a2;
14977
14978   return strcmp ((char *) (s1->name), (char *) (s2->name));
14979 }
14980
14981 static int
14982 dump_macro_table (vat_main_t * vam)
14983 {
14984   macro_sort_t *sort_me = 0, *sm;
14985   int i;
14986   hash_pair_t *p;
14987
14988     /* *INDENT-OFF* */
14989     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
14990     ({
14991       vec_add2 (sort_me, sm, 1);
14992       sm->name = (u8 *)(p->key);
14993       sm->value = (u8 *) (p->value[0]);
14994     }));
14995     /* *INDENT-ON* */
14996
14997   vec_sort_with_function (sort_me, macro_sort_cmp);
14998
14999   if (vec_len (sort_me))
15000     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15001   else
15002     fformat (vam->ofp, "The macro table is empty...\n");
15003
15004   for (i = 0; i < vec_len (sort_me); i++)
15005     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15006   return 0;
15007 }
15008
15009 static int
15010 dump_node_table (vat_main_t * vam)
15011 {
15012   int i, j;
15013   vlib_node_t *node, *next_node;
15014
15015   if (vec_len (vam->graph_nodes) == 0)
15016     {
15017       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15018       return 0;
15019     }
15020
15021   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15022     {
15023       node = vam->graph_nodes[i];
15024       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15025       for (j = 0; j < vec_len (node->next_nodes); j++)
15026         {
15027           if (node->next_nodes[j] != ~0)
15028             {
15029               next_node = vam->graph_nodes[node->next_nodes[j]];
15030               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15031             }
15032         }
15033     }
15034   return 0;
15035 }
15036
15037 static int
15038 search_node_table (vat_main_t * vam)
15039 {
15040   unformat_input_t *line_input = vam->input;
15041   u8 *node_to_find;
15042   int j;
15043   vlib_node_t *node, *next_node;
15044   uword *p;
15045
15046   if (vam->graph_node_index_by_name == 0)
15047     {
15048       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15049       return 0;
15050     }
15051
15052   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15053     {
15054       if (unformat (line_input, "%s", &node_to_find))
15055         {
15056           vec_add1 (node_to_find, 0);
15057           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15058           if (p == 0)
15059             {
15060               fformat (vam->ofp, "%s not found...\n", node_to_find);
15061               goto out;
15062             }
15063           node = vam->graph_nodes[p[0]];
15064           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15065           for (j = 0; j < vec_len (node->next_nodes); j++)
15066             {
15067               if (node->next_nodes[j] != ~0)
15068                 {
15069                   next_node = vam->graph_nodes[node->next_nodes[j]];
15070                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15071                 }
15072             }
15073         }
15074
15075       else
15076         {
15077           clib_warning ("parse error '%U'", format_unformat_error,
15078                         line_input);
15079           return -99;
15080         }
15081
15082     out:
15083       vec_free (node_to_find);
15084
15085     }
15086
15087   return 0;
15088 }
15089
15090
15091 static int
15092 script (vat_main_t * vam)
15093 {
15094   u8 *s = 0;
15095   char *save_current_file;
15096   unformat_input_t save_input;
15097   jmp_buf save_jump_buf;
15098   u32 save_line_number;
15099
15100   FILE *new_fp, *save_ifp;
15101
15102   if (unformat (vam->input, "%s", &s))
15103     {
15104       new_fp = fopen ((char *) s, "r");
15105       if (new_fp == 0)
15106         {
15107           errmsg ("Couldn't open script file %s\n", s);
15108           vec_free (s);
15109           return -99;
15110         }
15111     }
15112   else
15113     {
15114       errmsg ("Missing script name\n");
15115       return -99;
15116     }
15117
15118   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15119   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15120   save_ifp = vam->ifp;
15121   save_line_number = vam->input_line_number;
15122   save_current_file = (char *) vam->current_file;
15123
15124   vam->input_line_number = 0;
15125   vam->ifp = new_fp;
15126   vam->current_file = s;
15127   do_one_file (vam);
15128
15129   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15130   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15131   vam->ifp = save_ifp;
15132   vam->input_line_number = save_line_number;
15133   vam->current_file = (u8 *) save_current_file;
15134   vec_free (s);
15135
15136   return 0;
15137 }
15138
15139 static int
15140 echo (vat_main_t * vam)
15141 {
15142   fformat (vam->ofp, "%v", vam->input->buffer);
15143   return 0;
15144 }
15145
15146 /* List of API message constructors, CLI names map to api_xxx */
15147 #define foreach_vpe_api_msg                                             \
15148 _(create_loopback,"[mac <mac-addr>]")                                   \
15149 _(sw_interface_dump,"")                                                 \
15150 _(sw_interface_set_flags,                                               \
15151   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15152 _(sw_interface_add_del_address,                                         \
15153   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15154 _(sw_interface_set_table,                                               \
15155   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15156 _(sw_interface_set_vpath,                                               \
15157   "<intfc> | sw_if_index <id> enable | disable")                        \
15158 _(sw_interface_set_l2_xconnect,                                         \
15159   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15160   "enable | disable")                                                   \
15161 _(sw_interface_set_l2_bridge,                                           \
15162   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15163   "[shg <split-horizon-group>] [bvi]\n"                                 \
15164   "enable | disable")                                                   \
15165 _(bridge_domain_add_del,                                                \
15166   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15167 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15168 _(l2fib_add_del,                                                        \
15169   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15170 _(l2_flags,                                                             \
15171   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15172 _(bridge_flags,                                                         \
15173   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15174 _(tap_connect,                                                          \
15175   "tapname <name> mac <mac-addr> | random-mac")                         \
15176 _(tap_modify,                                                           \
15177   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15178 _(tap_delete,                                                           \
15179   "<vpp-if-name> | sw_if_index <id>")                                   \
15180 _(sw_interface_tap_dump, "")                                            \
15181 _(ip_add_del_route,                                                     \
15182   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15183   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15184   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15185   "[multipath] [count <n>]")                                            \
15186 _(proxy_arp_add_del,                                                    \
15187   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15188 _(proxy_arp_intfc_enable_disable,                                       \
15189   "<intfc> | sw_if_index <id> enable | disable")                        \
15190 _(mpls_add_del_encap,                                                   \
15191   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15192 _(mpls_add_del_decap,                                                   \
15193   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15194 _(mpls_gre_add_del_tunnel,                                              \
15195   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15196   "adj <ip4-address>/<mask-width> [del]")                               \
15197 _(sw_interface_set_unnumbered,                                          \
15198   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15199 _(ip_neighbor_add_del,                                                  \
15200   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15201   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15202 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15203 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15204 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15205   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15206   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15207   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15208 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15209 _(reset_fib, "vrf <n> [ipv6]")                                          \
15210 _(dhcp_proxy_config,                                                    \
15211   "svr <v46-address> src <v46-address>\n"                               \
15212    "insert-cid <n> [del]")                                              \
15213 _(dhcp_proxy_config_2,                                                  \
15214   "svr <v46-address> src <v46-address>\n"                               \
15215    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15216 _(dhcp_proxy_set_vss,                                                   \
15217   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15218 _(dhcp_client_config,                                                   \
15219   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15220 _(set_ip_flow_hash,                                                     \
15221   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15222 _(sw_interface_ip6_enable_disable,                                      \
15223   "<intfc> | sw_if_index <id> enable | disable")                        \
15224 _(sw_interface_ip6_set_link_local_address,                              \
15225   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15226 _(sw_interface_ip6nd_ra_prefix,                                         \
15227   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15228   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15229   "[nolink] [isno]")                                                    \
15230 _(sw_interface_ip6nd_ra_config,                                         \
15231   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15232   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15233   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15234 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15235 _(l2_patch_add_del,                                                     \
15236   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15237   "enable | disable")                                                   \
15238 _(mpls_ethernet_add_del_tunnel,                                         \
15239   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15240   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15241 _(mpls_ethernet_add_del_tunnel_2,                                       \
15242   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15243   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15244 _(sr_tunnel_add_del,                                                    \
15245   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15246   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15247   "[policy <policy_name>]")                                             \
15248 _(sr_policy_add_del,                                                    \
15249   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15250 _(sr_multicast_map_add_del,                                             \
15251   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15252 _(classify_add_del_table,                                               \
15253   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15254   "[del] mask <mask-value>\n"                                           \
15255   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15256 _(classify_add_del_session,                                             \
15257   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15258   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15259   "  [l3 [ip4|ip6]]")                                                   \
15260 _(classify_set_interface_ip_table,                                      \
15261   "<intfc> | sw_if_index <nn> table <nn>")                              \
15262 _(classify_set_interface_l2_tables,                                     \
15263   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15264   "  [other-table <nn>]")                                               \
15265 _(get_node_index, "node <node-name")                                    \
15266 _(add_node_next, "node <node-name> next <next-node-name>")              \
15267 _(l2tpv3_create_tunnel,                                                 \
15268   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15269   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15270   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15271 _(l2tpv3_set_tunnel_cookies,                                            \
15272   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15273   "[new_remote_cookie <nn>]\n")                                         \
15274 _(l2tpv3_interface_enable_disable,                                      \
15275   "<intfc> | sw_if_index <nn> enable | disable")                        \
15276 _(l2tpv3_set_lookup_key,                                                \
15277   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15278 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15279 _(vxlan_add_del_tunnel,                                                 \
15280   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15281   " [decap-next l2|ip4|ip6] [del]")                                     \
15282 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15283 _(gre_add_del_tunnel,                                                   \
15284   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n")          \
15285 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15286 _(l2_fib_clear_table, "")                                               \
15287 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15288 _(l2_interface_vlan_tag_rewrite,                                        \
15289   "<intfc> | sw_if_index <nn> \n"                                       \
15290   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15291   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15292 _(create_vhost_user_if,                                                 \
15293         "socket <filename> [server] [renumber <dev_instance>] "         \
15294         "[mac <mac_address>]")                                          \
15295 _(modify_vhost_user_if,                                                 \
15296         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15297         "[server] [renumber <dev_instance>]")                           \
15298 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15299 _(sw_interface_vhost_user_dump, "")                                     \
15300 _(show_version, "")                                                     \
15301 _(vxlan_gpe_add_del_tunnel,                                             \
15302   "local <addr> remote <addr> vni <nn>\n"                               \
15303     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15304   "[next-ethernet] [next-nsh]\n")                                       \
15305 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15306 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15307 _(interface_name_renumber,                                              \
15308   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15309 _(input_acl_set_interface,                                              \
15310   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15311   "  [l2-table <nn>] [del]")                                            \
15312 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15313 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
15314 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15315 _(ip_dump, "ipv4 | ipv6")                                               \
15316 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15317 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15318   "  spid_id <n> ")                                                     \
15319 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15320   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15321   "  integ_alg <alg> integ_key <hex>")                                  \
15322 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15323   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15324   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15325   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15326 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15327 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15328 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15329   "(auth_data 0x<data> | auth_data <data>)")                            \
15330 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15331   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15332 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15333   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15334   "(local|remote)")                                                     \
15335 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15336 _(delete_loopback,"sw_if_index <nn>")                                   \
15337 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15338 _(map_add_domain,                                                       \
15339   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
15340   "ip6-src <ip6addr> "                                                  \
15341   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
15342 _(map_del_domain, "index <n>")                                          \
15343 _(map_add_del_rule,                                                     \
15344   "index <n> psid <n> dst <ip6addr> [del]")                             \
15345 _(map_domain_dump, "")                                                  \
15346 _(map_rule_dump, "index <map-domain>")                                  \
15347 _(want_interface_events,  "enable|disable")                             \
15348 _(want_stats,"enable|disable")                                          \
15349 _(get_first_msg_id, "client <name>")                                    \
15350 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15351 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15352   "fib-id <nn> [ip4][ip6][default]")                                    \
15353 _(get_node_graph, " ")                                                  \
15354 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15355 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
15356 _(ioam_disable, "")                                                \
15357 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
15358                             " sw_if_index <sw_if_index> p <priority> "  \
15359                             "w <weight>] [del]")                        \
15360 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
15361                         "iface <intf> | sw_if_index <sw_if_index> "     \
15362                         "p <priority> w <weight> [del]")                \
15363 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
15364                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
15365                           "locator-set <locator_name> [del]")           \
15366 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
15367   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
15368 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
15369 _(lisp_gpe_enable_disable, "enable|disable")                            \
15370 _(lisp_enable_disable, "enable|disable")                                \
15371 _(lisp_gpe_add_del_iface, "up|down")                                    \
15372 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
15373                                "[seid <seid>] "                         \
15374                                "rloc <locator> p <prio> "               \
15375                                "w <weight> [rloc <loc> ... ] "          \
15376                                "action <action> [del-all]")             \
15377 _(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid "     \
15378                           "<src-eid> rloc <locator> p <prio> w <weight>"\
15379                           "[rloc <loc> ... ] action <action>")          \
15380 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
15381 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
15382 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
15383 _(lisp_locator_set_dump, "[local | remote]")                            \
15384 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
15385 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
15386                        "[local] | [remote]")                            \
15387 _(lisp_eid_table_vni_dump, "")                                          \
15388 _(lisp_eid_table_map_dump, "l2|l3")                                     \
15389 _(lisp_gpe_tunnel_dump, "")                                             \
15390 _(lisp_map_resolver_dump, "")                                           \
15391 _(show_lisp_status, "")                                                 \
15392 _(lisp_get_map_request_itr_rlocs, "")                                   \
15393 _(show_lisp_pitr, "")                                                   \
15394 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15395 _(af_packet_delete, "name <host interface name>")                       \
15396 _(policer_add_del, "name <policer name> <params> [del]")                \
15397 _(policer_dump, "[name <policer name>]")                                \
15398 _(policer_classify_set_interface,                                       \
15399   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15400   "  [l2-table <nn>] [del]")                                            \
15401 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15402 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
15403     "[master|slave]")                                                   \
15404 _(netmap_delete, "name <interface name>")                               \
15405 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15406 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15407 _(mpls_fib_encap_dump, "")                                              \
15408 _(mpls_fib_decap_dump, "")                                              \
15409 _(classify_table_ids, "")                                               \
15410 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15411 _(classify_table_info, "table_id <nn>")                                 \
15412 _(classify_session_dump, "table_id <nn>")                               \
15413 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
15414     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
15415     "[template_interval <nn>] [udp_checksum]")                          \
15416 _(ipfix_exporter_dump, "")                                              \
15417 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
15418 _(ipfix_classify_stream_dump, "")                                       \
15419 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
15420 _(ipfix_classify_table_dump, "")                                        \
15421 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15422 _(pg_create_interface, "if_id <nn>")                                    \
15423 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15424 _(pg_enable_disable, "[stream <id>] disable")                           \
15425 _(ip_source_and_port_range_check_add_del,                               \
15426   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15427 _(ip_source_and_port_range_check_interface_add_del,                     \
15428   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15429   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
15430 _(ipsec_gre_add_del_tunnel,                                             \
15431   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
15432 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
15433 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")
15434
15435 /* List of command functions, CLI names map directly to functions */
15436 #define foreach_cli_function                                    \
15437 _(comment, "usage: comment <ignore-rest-of-line>")              \
15438 _(dump_interface_table, "usage: dump_interface_table")          \
15439 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15440 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15441 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15442 _(dump_stats_table, "usage: dump_stats_table")                  \
15443 _(dump_macro_table, "usage: dump_macro_table ")                 \
15444 _(dump_node_table, "usage: dump_node_table")                    \
15445 _(echo, "usage: echo <message>")                                \
15446 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15447 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
15448 _(help, "usage: help")                                          \
15449 _(q, "usage: quit")                                             \
15450 _(quit, "usage: quit")                                          \
15451 _(search_node_table, "usage: search_node_table <name>...")      \
15452 _(set, "usage: set <variable-name> <value>")                    \
15453 _(script, "usage: script <file-name>")                          \
15454 _(unset, "usage: unset <variable-name>")
15455
15456 #define _(N,n)                                  \
15457     static void vl_api_##n##_t_handler_uni      \
15458     (vl_api_##n##_t * mp)                       \
15459     {                                           \
15460         vat_main_t * vam = &vat_main;           \
15461         if (vam->json_output) {                 \
15462             vl_api_##n##_t_handler_json(mp);    \
15463         } else {                                \
15464             vl_api_##n##_t_handler(mp);         \
15465         }                                       \
15466     }
15467 foreach_vpe_api_reply_msg;
15468 #undef _
15469
15470 void
15471 vat_api_hookup (vat_main_t * vam)
15472 {
15473 #define _(N,n)                                                  \
15474     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15475                            vl_api_##n##_t_handler_uni,          \
15476                            vl_noop_handler,                     \
15477                            vl_api_##n##_t_endian,               \
15478                            vl_api_##n##_t_print,                \
15479                            sizeof(vl_api_##n##_t), 1);
15480   foreach_vpe_api_reply_msg;
15481 #undef _
15482
15483   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
15484
15485   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15486
15487   vam->function_by_name = hash_create_string (0, sizeof (uword));
15488
15489   vam->help_by_name = hash_create_string (0, sizeof (uword));
15490
15491   /* API messages we can send */
15492 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15493   foreach_vpe_api_msg;
15494 #undef _
15495
15496   /* Help strings */
15497 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15498   foreach_vpe_api_msg;
15499 #undef _
15500
15501   /* CLI functions */
15502 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15503   foreach_cli_function;
15504 #undef _
15505
15506   /* Help strings */
15507 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15508   foreach_cli_function;
15509 #undef _
15510 }
15511
15512 #undef vl_api_version
15513 #define vl_api_version(n,v) static u32 vpe_api_version = v;
15514 #include <vpp-api/vpe.api.h>
15515 #undef vl_api_version
15516
15517 void
15518 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
15519 {
15520   /*
15521    * Send the main API signature in slot 0. This bit of code must
15522    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
15523    */
15524   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
15525 }
15526
15527 /*
15528  * fd.io coding-style-patch-verification: ON
15529  *
15530  * Local Variables:
15531  * eval: (c-set-style "gnu")
15532  * End:
15533  */