VPP-358: Add IPv6 ND Event Notification and Termination
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/mpls-gre/mpls.h>
39 #if DPDK > 0
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #else
43 #include <inttypes.h>
44 #endif
45 #include <vnet/map/map.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52
53 #include "vat/json_format.h"
54
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248 #if DPDK > 0
249   u32 *r = va_arg (*args, u32 *);
250
251   if (0);
252 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
253   foreach_ipsec_policy_action
254 #undef _
255     else
256     return 0;
257   return 1;
258 #else
259   return 0;
260 #endif
261 }
262
263 uword
264 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
265 {
266 #if DPDK > 0
267   u32 *r = va_arg (*args, u32 *);
268
269   if (0);
270 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
271   foreach_ipsec_crypto_alg
272 #undef _
273     else
274     return 0;
275   return 1;
276 #else
277   return 0;
278 #endif
279 }
280
281 u8 *
282 format_ipsec_crypto_alg (u8 * s, va_list * args)
283 {
284 #if DPDK > 0
285   u32 i = va_arg (*args, u32);
286   u8 *t = 0;
287
288   switch (i)
289     {
290 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
291       foreach_ipsec_crypto_alg
292 #undef _
293     default:
294       return format (s, "unknown");
295     }
296   return format (s, "%s", t);
297 #else
298   return format (s, "Unimplemented");
299 #endif
300 }
301
302 uword
303 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
304 {
305 #if DPDK > 0
306   u32 *r = va_arg (*args, u32 *);
307
308   if (0);
309 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
310   foreach_ipsec_integ_alg
311 #undef _
312     else
313     return 0;
314   return 1;
315 #else
316   return 0;
317 #endif
318 }
319
320 u8 *
321 format_ipsec_integ_alg (u8 * s, va_list * args)
322 {
323 #if DPDK > 0
324   u32 i = va_arg (*args, u32);
325   u8 *t = 0;
326
327   switch (i)
328     {
329 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
330       foreach_ipsec_integ_alg
331 #undef _
332     default:
333       return format (s, "unknown");
334     }
335   return format (s, "%s", t);
336 #else
337   return format (s, "Unsupported");
338 #endif
339 }
340
341 uword
342 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
343 {
344 #if DPDK > 0
345   u32 *r = va_arg (*args, u32 *);
346
347   if (0);
348 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
349   foreach_ikev2_auth_method
350 #undef _
351     else
352     return 0;
353   return 1;
354 #else
355   return 0;
356 #endif
357 }
358
359 uword
360 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
361 {
362 #if DPDK > 0
363   u32 *r = va_arg (*args, u32 *);
364
365   if (0);
366 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
367   foreach_ikev2_id_type
368 #undef _
369     else
370     return 0;
371   return 1;
372 #else
373   return 0;
374 #endif
375 }
376
377 uword
378 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
379 {
380   u8 *r = va_arg (*args, u8 *);
381
382   if (unformat (input, "kbps"))
383     *r = SSE2_QOS_RATE_KBPS;
384   else if (unformat (input, "pps"))
385     *r = SSE2_QOS_RATE_PPS;
386   else
387     return 0;
388   return 1;
389 }
390
391 uword
392 unformat_policer_round_type (unformat_input_t * input, va_list * args)
393 {
394   u8 *r = va_arg (*args, u8 *);
395
396   if (unformat (input, "closest"))
397     *r = SSE2_QOS_ROUND_TO_CLOSEST;
398   else if (unformat (input, "up"))
399     *r = SSE2_QOS_ROUND_TO_UP;
400   else if (unformat (input, "down"))
401     *r = SSE2_QOS_ROUND_TO_DOWN;
402   else
403     return 0;
404   return 1;
405 }
406
407 uword
408 unformat_policer_type (unformat_input_t * input, va_list * args)
409 {
410   u8 *r = va_arg (*args, u8 *);
411
412   if (unformat (input, "1r2c"))
413     *r = SSE2_QOS_POLICER_TYPE_1R2C;
414   else if (unformat (input, "1r3c"))
415     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
416   else if (unformat (input, "2r3c-2698"))
417     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
418   else if (unformat (input, "2r3c-4115"))
419     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
420   else if (unformat (input, "2r3c-mef5cf1"))
421     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
422   else
423     return 0;
424   return 1;
425 }
426
427 uword
428 unformat_dscp (unformat_input_t * input, va_list * va)
429 {
430   u8 *r = va_arg (*va, u8 *);
431
432   if (0);
433 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
434   foreach_vnet_dscp
435 #undef _
436     else
437     return 0;
438   return 1;
439 }
440
441 uword
442 unformat_policer_action_type (unformat_input_t * input, va_list * va)
443 {
444   sse2_qos_pol_action_params_st *a
445     = va_arg (*va, sse2_qos_pol_action_params_st *);
446
447   if (unformat (input, "drop"))
448     a->action_type = SSE2_QOS_ACTION_DROP;
449   else if (unformat (input, "transmit"))
450     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
451   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
452     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
453   else
454     return 0;
455   return 1;
456 }
457
458 uword
459 unformat_classify_table_type (unformat_input_t * input, va_list * va)
460 {
461   u32 *r = va_arg (*va, u32 *);
462   u32 tid;
463
464   if (unformat (input, "ip4"))
465     tid = POLICER_CLASSIFY_TABLE_IP4;
466   else if (unformat (input, "ip6"))
467     tid = POLICER_CLASSIFY_TABLE_IP6;
468   else if (unformat (input, "l2"))
469     tid = POLICER_CLASSIFY_TABLE_L2;
470   else
471     return 0;
472
473   *r = tid;
474   return 1;
475 }
476
477 u8 *
478 format_ip4_address (u8 * s, va_list * args)
479 {
480   u8 *a = va_arg (*args, u8 *);
481   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
482 }
483
484 u8 *
485 format_ip6_address (u8 * s, va_list * args)
486 {
487   ip6_address_t *a = va_arg (*args, ip6_address_t *);
488   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
489
490   i_max_n_zero = ARRAY_LEN (a->as_u16);
491   max_n_zeros = 0;
492   i_first_zero = i_max_n_zero;
493   n_zeros = 0;
494   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
495     {
496       u32 is_zero = a->as_u16[i] == 0;
497       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
498         {
499           i_first_zero = i;
500           n_zeros = 0;
501         }
502       n_zeros += is_zero;
503       if ((!is_zero && n_zeros > max_n_zeros)
504           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
505         {
506           i_max_n_zero = i_first_zero;
507           max_n_zeros = n_zeros;
508           i_first_zero = ARRAY_LEN (a->as_u16);
509           n_zeros = 0;
510         }
511     }
512
513   last_double_colon = 0;
514   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
515     {
516       if (i == i_max_n_zero && max_n_zeros > 1)
517         {
518           s = format (s, "::");
519           i += max_n_zeros - 1;
520           last_double_colon = 1;
521         }
522       else
523         {
524           s = format (s, "%s%x",
525                       (last_double_colon || i == 0) ? "" : ":",
526                       clib_net_to_host_u16 (a->as_u16[i]));
527           last_double_colon = 0;
528         }
529     }
530
531   return s;
532 }
533
534 /* Format an IP46 address. */
535 u8 *
536 format_ip46_address (u8 * s, va_list * args)
537 {
538   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
539   ip46_type_t type = va_arg (*args, ip46_type_t);
540   int is_ip4 = 1;
541
542   switch (type)
543     {
544     case IP46_TYPE_ANY:
545       is_ip4 = ip46_address_is_ip4 (ip46);
546       break;
547     case IP46_TYPE_IP4:
548       is_ip4 = 1;
549       break;
550     case IP46_TYPE_IP6:
551       is_ip4 = 0;
552       break;
553     }
554
555   return is_ip4 ?
556     format (s, "%U", format_ip4_address, &ip46->ip4) :
557     format (s, "%U", format_ip6_address, &ip46->ip6);
558 }
559
560 u8 *
561 format_ethernet_address (u8 * s, va_list * args)
562 {
563   u8 *a = va_arg (*args, u8 *);
564
565   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
566                  a[0], a[1], a[2], a[3], a[4], a[5]);
567 }
568
569 void
570 increment_v4_address (ip4_address_t * a)
571 {
572   u32 v;
573
574   v = ntohl (a->as_u32) + 1;
575   a->as_u32 = ntohl (v);
576 }
577
578 void
579 increment_v6_address (ip6_address_t * a)
580 {
581   u64 v0, v1;
582
583   v0 = clib_net_to_host_u64 (a->as_u64[0]);
584   v1 = clib_net_to_host_u64 (a->as_u64[1]);
585
586   v1 += 1;
587   if (v1 == 0)
588     v0 += 1;
589   a->as_u64[0] = clib_net_to_host_u64 (v0);
590   a->as_u64[1] = clib_net_to_host_u64 (v1);
591 }
592
593 void
594 increment_mac_address (u64 * mac)
595 {
596   u64 tmp = *mac;
597
598   tmp = clib_net_to_host_u64 (tmp);
599   tmp += 1 << 16;               /* skip unused (least significant) octets */
600   tmp = clib_host_to_net_u64 (tmp);
601   *mac = tmp;
602 }
603
604 static void vl_api_create_loopback_reply_t_handler
605   (vl_api_create_loopback_reply_t * mp)
606 {
607   vat_main_t *vam = &vat_main;
608   i32 retval = ntohl (mp->retval);
609
610   vam->retval = retval;
611   vam->regenerate_interface_table = 1;
612   vam->sw_if_index = ntohl (mp->sw_if_index);
613   vam->result_ready = 1;
614 }
615
616 static void vl_api_create_loopback_reply_t_handler_json
617   (vl_api_create_loopback_reply_t * mp)
618 {
619   vat_main_t *vam = &vat_main;
620   vat_json_node_t node;
621
622   vat_json_init_object (&node);
623   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
624   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
625
626   vat_json_print (vam->ofp, &node);
627   vat_json_free (&node);
628   vam->retval = ntohl (mp->retval);
629   vam->result_ready = 1;
630 }
631
632 static void vl_api_af_packet_create_reply_t_handler
633   (vl_api_af_packet_create_reply_t * mp)
634 {
635   vat_main_t *vam = &vat_main;
636   i32 retval = ntohl (mp->retval);
637
638   vam->retval = retval;
639   vam->regenerate_interface_table = 1;
640   vam->sw_if_index = ntohl (mp->sw_if_index);
641   vam->result_ready = 1;
642 }
643
644 static void vl_api_af_packet_create_reply_t_handler_json
645   (vl_api_af_packet_create_reply_t * mp)
646 {
647   vat_main_t *vam = &vat_main;
648   vat_json_node_t node;
649
650   vat_json_init_object (&node);
651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
652   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
653
654   vat_json_print (vam->ofp, &node);
655   vat_json_free (&node);
656
657   vam->retval = ntohl (mp->retval);
658   vam->result_ready = 1;
659 }
660
661 static void vl_api_create_vlan_subif_reply_t_handler
662   (vl_api_create_vlan_subif_reply_t * mp)
663 {
664   vat_main_t *vam = &vat_main;
665   i32 retval = ntohl (mp->retval);
666
667   vam->retval = retval;
668   vam->regenerate_interface_table = 1;
669   vam->sw_if_index = ntohl (mp->sw_if_index);
670   vam->result_ready = 1;
671 }
672
673 static void vl_api_create_vlan_subif_reply_t_handler_json
674   (vl_api_create_vlan_subif_reply_t * mp)
675 {
676   vat_main_t *vam = &vat_main;
677   vat_json_node_t node;
678
679   vat_json_init_object (&node);
680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
681   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
682
683   vat_json_print (vam->ofp, &node);
684   vat_json_free (&node);
685
686   vam->retval = ntohl (mp->retval);
687   vam->result_ready = 1;
688 }
689
690 static void vl_api_create_subif_reply_t_handler
691   (vl_api_create_subif_reply_t * mp)
692 {
693   vat_main_t *vam = &vat_main;
694   i32 retval = ntohl (mp->retval);
695
696   vam->retval = retval;
697   vam->regenerate_interface_table = 1;
698   vam->sw_if_index = ntohl (mp->sw_if_index);
699   vam->result_ready = 1;
700 }
701
702 static void vl_api_create_subif_reply_t_handler_json
703   (vl_api_create_subif_reply_t * mp)
704 {
705   vat_main_t *vam = &vat_main;
706   vat_json_node_t node;
707
708   vat_json_init_object (&node);
709   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
710   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
711
712   vat_json_print (vam->ofp, &node);
713   vat_json_free (&node);
714
715   vam->retval = ntohl (mp->retval);
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   i32 retval = ntohl (mp->retval);
724
725   vam->retval = retval;
726   vam->regenerate_interface_table = 1;
727   vam->result_ready = 1;
728 }
729
730 static void vl_api_interface_name_renumber_reply_t_handler_json
731   (vl_api_interface_name_renumber_reply_t * mp)
732 {
733   vat_main_t *vam = &vat_main;
734   vat_json_node_t node;
735
736   vat_json_init_object (&node);
737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
738
739   vat_json_print (vam->ofp, &node);
740   vat_json_free (&node);
741
742   vam->retval = ntohl (mp->retval);
743   vam->result_ready = 1;
744 }
745
746 /*
747  * Special-case: build the interface table, maintain
748  * the next loopback sw_if_index vbl.
749  */
750 static void vl_api_sw_interface_details_t_handler
751   (vl_api_sw_interface_details_t * mp)
752 {
753   vat_main_t *vam = &vat_main;
754   u8 *s = format (0, "%s%c", mp->interface_name, 0);
755
756   hash_set_mem (vam->sw_if_index_by_interface_name, s,
757                 ntohl (mp->sw_if_index));
758
759   /* In sub interface case, fill the sub interface table entry */
760   if (mp->sw_if_index != mp->sup_sw_if_index)
761     {
762       sw_interface_subif_t *sub = NULL;
763
764       vec_add2 (vam->sw_if_subif_table, sub, 1);
765
766       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
767       strncpy ((char *) sub->interface_name, (char *) s,
768                vec_len (sub->interface_name));
769       sub->sw_if_index = ntohl (mp->sw_if_index);
770       sub->sub_id = ntohl (mp->sub_id);
771
772       sub->sub_dot1ad = mp->sub_dot1ad;
773       sub->sub_number_of_tags = mp->sub_number_of_tags;
774       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
775       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
776       sub->sub_exact_match = mp->sub_exact_match;
777       sub->sub_default = mp->sub_default;
778       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
779       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
780
781       /* vlan tag rewrite */
782       sub->vtr_op = ntohl (mp->vtr_op);
783       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
784       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
785       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
786     }
787 }
788
789 static void vl_api_sw_interface_details_t_handler_json
790   (vl_api_sw_interface_details_t * mp)
791 {
792   vat_main_t *vam = &vat_main;
793   vat_json_node_t *node = NULL;
794
795   if (VAT_JSON_ARRAY != vam->json_tree.type)
796     {
797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
798       vat_json_init_array (&vam->json_tree);
799     }
800   node = vat_json_array_add (&vam->json_tree);
801
802   vat_json_init_object (node);
803   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
804   vat_json_object_add_uint (node, "sup_sw_if_index",
805                             ntohl (mp->sup_sw_if_index));
806   vat_json_object_add_uint (node, "l2_address_length",
807                             ntohl (mp->l2_address_length));
808   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
809                              sizeof (mp->l2_address));
810   vat_json_object_add_string_copy (node, "interface_name",
811                                    mp->interface_name);
812   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
813   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
814   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
815   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
816   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
817   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
818   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
819   vat_json_object_add_uint (node, "sub_number_of_tags",
820                             mp->sub_number_of_tags);
821   vat_json_object_add_uint (node, "sub_outer_vlan_id",
822                             ntohs (mp->sub_outer_vlan_id));
823   vat_json_object_add_uint (node, "sub_inner_vlan_id",
824                             ntohs (mp->sub_inner_vlan_id));
825   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
826   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
827   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
828                             mp->sub_outer_vlan_id_any);
829   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
830                             mp->sub_inner_vlan_id_any);
831   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
832   vat_json_object_add_uint (node, "vtr_push_dot1q",
833                             ntohl (mp->vtr_push_dot1q));
834   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
835   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   vat_main_t *vam = &vat_main;
842   if (vam->interface_event_display)
843     errmsg ("interface flags: sw_if_index %d %s %s\n",
844             ntohl (mp->sw_if_index),
845             mp->admin_up_down ? "admin-up" : "admin-down",
846             mp->link_up_down ? "link-up" : "link-down");
847 }
848
849 static void vl_api_sw_interface_set_flags_t_handler_json
850   (vl_api_sw_interface_set_flags_t * mp)
851 {
852   /* JSON output not supported */
853 }
854
855 static void
856 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->shmem_result = (u8 *) mp->reply_in_shmem;
863   vam->result_ready = 1;
864 }
865
866 static void
867 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
868 {
869   vat_main_t *vam = &vat_main;
870   vat_json_node_t node;
871   api_main_t *am = &api_main;
872   void *oldheap;
873   u8 *reply;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "reply_in_shmem",
878                             ntohl (mp->reply_in_shmem));
879   /* Toss the shared-memory original... */
880   pthread_mutex_lock (&am->vlib_rp->mutex);
881   oldheap = svm_push_data_heap (am->vlib_rp);
882
883   reply = (u8 *) (mp->reply_in_shmem);
884   vec_free (reply);
885
886   svm_pop_heap (oldheap);
887   pthread_mutex_unlock (&am->vlib_rp->mutex);
888
889   vat_json_print (vam->ofp, &node);
890   vat_json_free (&node);
891
892   vam->retval = ntohl (mp->retval);
893   vam->result_ready = 1;
894 }
895
896 static void
897 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   i32 retval = ntohl (mp->retval);
901
902   vam->retval = retval;
903   vam->cmd_reply = mp->reply;
904   vam->result_ready = 1;
905 }
906
907 static void
908 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
909 {
910   vat_main_t *vam = &vat_main;
911   vat_json_node_t node;
912
913   vat_json_init_object (&node);
914   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
915   vat_json_object_add_string_copy (&node, "reply", mp->reply);
916
917   vat_json_print (vam->ofp, &node);
918   vat_json_free (&node);
919
920   vam->retval = ntohl (mp->retval);
921   vam->result_ready = 1;
922 }
923
924 static void vl_api_classify_add_del_table_reply_t_handler
925   (vl_api_classify_add_del_table_reply_t * mp)
926 {
927   vat_main_t *vam = &vat_main;
928   i32 retval = ntohl (mp->retval);
929   if (vam->async_mode)
930     {
931       vam->async_errors += (retval < 0);
932     }
933   else
934     {
935       vam->retval = retval;
936       if (retval == 0 &&
937           ((mp->new_table_index != 0xFFFFFFFF) ||
938            (mp->skip_n_vectors != 0xFFFFFFFF) ||
939            (mp->match_n_vectors != 0xFFFFFFFF)))
940         /*
941          * Note: this is just barely thread-safe, depends on
942          * the main thread spinning waiting for an answer...
943          */
944         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
945                 ntohl (mp->new_table_index),
946                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
947       vam->result_ready = 1;
948     }
949 }
950
951 static void vl_api_classify_add_del_table_reply_t_handler_json
952   (vl_api_classify_add_del_table_reply_t * mp)
953 {
954   vat_main_t *vam = &vat_main;
955   vat_json_node_t node;
956
957   vat_json_init_object (&node);
958   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
959   vat_json_object_add_uint (&node, "new_table_index",
960                             ntohl (mp->new_table_index));
961   vat_json_object_add_uint (&node, "skip_n_vectors",
962                             ntohl (mp->skip_n_vectors));
963   vat_json_object_add_uint (&node, "match_n_vectors",
964                             ntohl (mp->match_n_vectors));
965
966   vat_json_print (vam->ofp, &node);
967   vat_json_free (&node);
968
969   vam->retval = ntohl (mp->retval);
970   vam->result_ready = 1;
971 }
972
973 static void vl_api_get_node_index_reply_t_handler
974   (vl_api_get_node_index_reply_t * mp)
975 {
976   vat_main_t *vam = &vat_main;
977   i32 retval = ntohl (mp->retval);
978   if (vam->async_mode)
979     {
980       vam->async_errors += (retval < 0);
981     }
982   else
983     {
984       vam->retval = retval;
985       if (retval == 0)
986         errmsg ("node index %d\n", ntohl (mp->node_index));
987       vam->result_ready = 1;
988     }
989 }
990
991 static void vl_api_get_node_index_reply_t_handler_json
992   (vl_api_get_node_index_reply_t * mp)
993 {
994   vat_main_t *vam = &vat_main;
995   vat_json_node_t node;
996
997   vat_json_init_object (&node);
998   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
999   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1000
1001   vat_json_print (vam->ofp, &node);
1002   vat_json_free (&node);
1003
1004   vam->retval = ntohl (mp->retval);
1005   vam->result_ready = 1;
1006 }
1007
1008 static void vl_api_get_next_index_reply_t_handler
1009   (vl_api_get_next_index_reply_t * mp)
1010 {
1011   vat_main_t *vam = &vat_main;
1012   i32 retval = ntohl (mp->retval);
1013   if (vam->async_mode)
1014     {
1015       vam->async_errors += (retval < 0);
1016     }
1017   else
1018     {
1019       vam->retval = retval;
1020       if (retval == 0)
1021         errmsg ("next node index %d\n", ntohl (mp->next_index));
1022       vam->result_ready = 1;
1023     }
1024 }
1025
1026 static void vl_api_get_next_index_reply_t_handler_json
1027   (vl_api_get_next_index_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   vat_json_node_t node;
1031
1032   vat_json_init_object (&node);
1033   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1034   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1035
1036   vat_json_print (vam->ofp, &node);
1037   vat_json_free (&node);
1038
1039   vam->retval = ntohl (mp->retval);
1040   vam->result_ready = 1;
1041 }
1042
1043 static void vl_api_add_node_next_reply_t_handler
1044   (vl_api_add_node_next_reply_t * mp)
1045 {
1046   vat_main_t *vam = &vat_main;
1047   i32 retval = ntohl (mp->retval);
1048   if (vam->async_mode)
1049     {
1050       vam->async_errors += (retval < 0);
1051     }
1052   else
1053     {
1054       vam->retval = retval;
1055       if (retval == 0)
1056         errmsg ("next index %d\n", ntohl (mp->next_index));
1057       vam->result_ready = 1;
1058     }
1059 }
1060
1061 static void vl_api_add_node_next_reply_t_handler_json
1062   (vl_api_add_node_next_reply_t * mp)
1063 {
1064   vat_main_t *vam = &vat_main;
1065   vat_json_node_t node;
1066
1067   vat_json_init_object (&node);
1068   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1069   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1070
1071   vat_json_print (vam->ofp, &node);
1072   vat_json_free (&node);
1073
1074   vam->retval = ntohl (mp->retval);
1075   vam->result_ready = 1;
1076 }
1077
1078 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
1079   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1080 {
1081   vat_main_t *vam = &vat_main;
1082   i32 retval = ntohl (mp->retval);
1083   u32 sw_if_index = ntohl (mp->tunnel_sw_if_index);
1084
1085   if (retval >= 0 && sw_if_index != (u32) ~ 0)
1086     {
1087       errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1088     }
1089   vam->retval = retval;
1090   vam->result_ready = 1;
1091 }
1092
1093 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1094   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1095 {
1096   vat_main_t *vam = &vat_main;
1097   vat_json_node_t node;
1098
1099   vat_json_init_object (&node);
1100   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1101   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1102                             ntohl (mp->tunnel_sw_if_index));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111
1112 static void vl_api_show_version_reply_t_handler
1113   (vl_api_show_version_reply_t * mp)
1114 {
1115   vat_main_t *vam = &vat_main;
1116   i32 retval = ntohl (mp->retval);
1117
1118   if (retval >= 0)
1119     {
1120       errmsg ("        program: %s\n", mp->program);
1121       errmsg ("        version: %s\n", mp->version);
1122       errmsg ("     build date: %s\n", mp->build_date);
1123       errmsg ("build directory: %s\n", mp->build_directory);
1124     }
1125   vam->retval = retval;
1126   vam->result_ready = 1;
1127 }
1128
1129 static void vl_api_show_version_reply_t_handler_json
1130   (vl_api_show_version_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_string_copy (&node, "program", mp->program);
1138   vat_json_object_add_string_copy (&node, "version", mp->version);
1139   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1140   vat_json_object_add_string_copy (&node, "build_directory",
1141                                    mp->build_directory);
1142
1143   vat_json_print (vam->ofp, &node);
1144   vat_json_free (&node);
1145
1146   vam->retval = ntohl (mp->retval);
1147   vam->result_ready = 1;
1148 }
1149
1150 static void
1151 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1152 {
1153   vat_main_t *vam = &vat_main;
1154   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1155           mp->mac_ip ? "mac/ip binding" : "address resolution",
1156           format_ip4_address, &mp->address,
1157           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1158 }
1159
1160 static void
1161 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1162 {
1163   /* JSON output not supported */
1164 }
1165
1166 static void
1167 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1168 {
1169   vat_main_t *vam = &vat_main;
1170   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1171           mp->mac_ip ? "mac/ip binding" : "address resolution",
1172           format_ip6_address, mp->address,
1173           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1174 }
1175
1176 static void
1177 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1178 {
1179   /* JSON output not supported */
1180 }
1181
1182 /*
1183  * Special-case: build the bridge domain table, maintain
1184  * the next bd id vbl.
1185  */
1186 static void vl_api_bridge_domain_details_t_handler
1187   (vl_api_bridge_domain_details_t * mp)
1188 {
1189   vat_main_t *vam = &vat_main;
1190   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1191
1192   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1193            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1194
1195   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1196            ntohl (mp->bd_id), mp->learn, mp->forward,
1197            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1198
1199   if (n_sw_ifs)
1200     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1201              "Interface Name");
1202 }
1203
1204 static void vl_api_bridge_domain_details_t_handler_json
1205   (vl_api_bridge_domain_details_t * mp)
1206 {
1207   vat_main_t *vam = &vat_main;
1208   vat_json_node_t *node, *array = NULL;
1209
1210   if (VAT_JSON_ARRAY != vam->json_tree.type)
1211     {
1212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1213       vat_json_init_array (&vam->json_tree);
1214     }
1215   node = vat_json_array_add (&vam->json_tree);
1216
1217   vat_json_init_object (node);
1218   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1219   vat_json_object_add_uint (node, "flood", mp->flood);
1220   vat_json_object_add_uint (node, "forward", mp->forward);
1221   vat_json_object_add_uint (node, "learn", mp->learn);
1222   vat_json_object_add_uint (node, "bvi_sw_if_index",
1223                             ntohl (mp->bvi_sw_if_index));
1224   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1225   array = vat_json_object_add (node, "sw_if");
1226   vat_json_init_array (array);
1227 }
1228
1229 /*
1230  * Special-case: build the bridge domain sw if table.
1231  */
1232 static void vl_api_bridge_domain_sw_if_details_t_handler
1233   (vl_api_bridge_domain_sw_if_details_t * mp)
1234 {
1235   vat_main_t *vam = &vat_main;
1236   hash_pair_t *p;
1237   u8 *sw_if_name = 0;
1238   u32 sw_if_index;
1239
1240   sw_if_index = ntohl (mp->sw_if_index);
1241   /* *INDENT-OFF* */
1242   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1243   ({
1244     if ((u32) p->value[0] == sw_if_index)
1245       {
1246         sw_if_name = (u8 *)(p->key);
1247         break;
1248       }
1249   }));
1250   /* *INDENT-ON* */
1251
1252   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1253            mp->shg, sw_if_name ? (char *) sw_if_name :
1254            "sw_if_index not found!");
1255 }
1256
1257 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1258   (vl_api_bridge_domain_sw_if_details_t * mp)
1259 {
1260   vat_main_t *vam = &vat_main;
1261   vat_json_node_t *node = NULL;
1262   uword last_index = 0;
1263
1264   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1265   ASSERT (vec_len (vam->json_tree.array) >= 1);
1266   last_index = vec_len (vam->json_tree.array) - 1;
1267   node = &vam->json_tree.array[last_index];
1268   node = vat_json_object_get_element (node, "sw_if");
1269   ASSERT (NULL != node);
1270   node = vat_json_array_add (node);
1271
1272   vat_json_init_object (node);
1273   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1274   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1275   vat_json_object_add_uint (node, "shg", mp->shg);
1276 }
1277
1278 static void vl_api_control_ping_reply_t_handler
1279   (vl_api_control_ping_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   i32 retval = ntohl (mp->retval);
1283   if (vam->async_mode)
1284     {
1285       vam->async_errors += (retval < 0);
1286     }
1287   else
1288     {
1289       vam->retval = retval;
1290       vam->result_ready = 1;
1291     }
1292 }
1293
1294 static void vl_api_control_ping_reply_t_handler_json
1295   (vl_api_control_ping_reply_t * mp)
1296 {
1297   vat_main_t *vam = &vat_main;
1298   i32 retval = ntohl (mp->retval);
1299
1300   if (VAT_JSON_NONE != vam->json_tree.type)
1301     {
1302       vat_json_print (vam->ofp, &vam->json_tree);
1303       vat_json_free (&vam->json_tree);
1304       vam->json_tree.type = VAT_JSON_NONE;
1305     }
1306   else
1307     {
1308       /* just print [] */
1309       vat_json_init_array (&vam->json_tree);
1310       vat_json_print (vam->ofp, &vam->json_tree);
1311       vam->json_tree.type = VAT_JSON_NONE;
1312     }
1313
1314   vam->retval = retval;
1315   vam->result_ready = 1;
1316 }
1317
1318 static void vl_api_noprint_control_ping_reply_t_handler
1319   (vl_api_noprint_control_ping_reply_t * mp)
1320 {
1321   vat_main_t *vam = &vat_main;
1322   i32 retval = ntohl (mp->retval);
1323   if (vam->async_mode)
1324     {
1325       vam->async_errors += (retval < 0);
1326     }
1327   else
1328     {
1329       vam->retval = retval;
1330       vam->result_ready = 1;
1331     }
1332 }
1333
1334 static void vl_api_noprint_control_ping_reply_t_handler_json
1335   (vl_api_noprint_control_ping_reply_t * mp)
1336 {
1337   vat_main_t *vam = &vat_main;
1338   i32 retval = ntohl (mp->retval);
1339
1340   if (vam->noprint_msg)
1341     {
1342       vam->retval = retval;
1343       vam->result_ready = 1;
1344       return;
1345     }
1346
1347   if (VAT_JSON_NONE != vam->json_tree.type)
1348     {
1349       vat_json_print (vam->ofp, &vam->json_tree);
1350       vat_json_free (&vam->json_tree);
1351       vam->json_tree.type = VAT_JSON_NONE;
1352     }
1353   else
1354     {
1355       /* just print [] */
1356       vat_json_init_array (&vam->json_tree);
1357       vat_json_print (vam->ofp, &vam->json_tree);
1358       vam->json_tree.type = VAT_JSON_NONE;
1359     }
1360
1361   vam->retval = retval;
1362   vam->result_ready = 1;
1363 }
1364
1365 static void
1366 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1367 {
1368   vat_main_t *vam = &vat_main;
1369   i32 retval = ntohl (mp->retval);
1370   if (vam->async_mode)
1371     {
1372       vam->async_errors += (retval < 0);
1373     }
1374   else
1375     {
1376       vam->retval = retval;
1377       vam->result_ready = 1;
1378     }
1379 }
1380
1381 static void vl_api_l2_flags_reply_t_handler_json
1382   (vl_api_l2_flags_reply_t * mp)
1383 {
1384   vat_main_t *vam = &vat_main;
1385   vat_json_node_t node;
1386
1387   vat_json_init_object (&node);
1388   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1389   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1390                             ntohl (mp->resulting_feature_bitmap));
1391
1392   vat_json_print (vam->ofp, &node);
1393   vat_json_free (&node);
1394
1395   vam->retval = ntohl (mp->retval);
1396   vam->result_ready = 1;
1397 }
1398
1399 static void vl_api_bridge_flags_reply_t_handler
1400   (vl_api_bridge_flags_reply_t * mp)
1401 {
1402   vat_main_t *vam = &vat_main;
1403   i32 retval = ntohl (mp->retval);
1404   if (vam->async_mode)
1405     {
1406       vam->async_errors += (retval < 0);
1407     }
1408   else
1409     {
1410       vam->retval = retval;
1411       vam->result_ready = 1;
1412     }
1413 }
1414
1415 static void vl_api_bridge_flags_reply_t_handler_json
1416   (vl_api_bridge_flags_reply_t * mp)
1417 {
1418   vat_main_t *vam = &vat_main;
1419   vat_json_node_t node;
1420
1421   vat_json_init_object (&node);
1422   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1423   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1424                             ntohl (mp->resulting_feature_bitmap));
1425
1426   vat_json_print (vam->ofp, &node);
1427   vat_json_free (&node);
1428
1429   vam->retval = ntohl (mp->retval);
1430   vam->result_ready = 1;
1431 }
1432
1433 static void vl_api_tap_connect_reply_t_handler
1434   (vl_api_tap_connect_reply_t * mp)
1435 {
1436   vat_main_t *vam = &vat_main;
1437   i32 retval = ntohl (mp->retval);
1438   if (vam->async_mode)
1439     {
1440       vam->async_errors += (retval < 0);
1441     }
1442   else
1443     {
1444       vam->retval = retval;
1445       vam->sw_if_index = ntohl (mp->sw_if_index);
1446       vam->result_ready = 1;
1447     }
1448
1449 }
1450
1451 static void vl_api_tap_connect_reply_t_handler_json
1452   (vl_api_tap_connect_reply_t * mp)
1453 {
1454   vat_main_t *vam = &vat_main;
1455   vat_json_node_t node;
1456
1457   vat_json_init_object (&node);
1458   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1459   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1460
1461   vat_json_print (vam->ofp, &node);
1462   vat_json_free (&node);
1463
1464   vam->retval = ntohl (mp->retval);
1465   vam->result_ready = 1;
1466
1467 }
1468
1469 static void
1470 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1471 {
1472   vat_main_t *vam = &vat_main;
1473   i32 retval = ntohl (mp->retval);
1474   if (vam->async_mode)
1475     {
1476       vam->async_errors += (retval < 0);
1477     }
1478   else
1479     {
1480       vam->retval = retval;
1481       vam->sw_if_index = ntohl (mp->sw_if_index);
1482       vam->result_ready = 1;
1483     }
1484 }
1485
1486 static void vl_api_tap_modify_reply_t_handler_json
1487   (vl_api_tap_modify_reply_t * mp)
1488 {
1489   vat_main_t *vam = &vat_main;
1490   vat_json_node_t node;
1491
1492   vat_json_init_object (&node);
1493   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1494   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1495
1496   vat_json_print (vam->ofp, &node);
1497   vat_json_free (&node);
1498
1499   vam->retval = ntohl (mp->retval);
1500   vam->result_ready = 1;
1501 }
1502
1503 static void
1504 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1505 {
1506   vat_main_t *vam = &vat_main;
1507   i32 retval = ntohl (mp->retval);
1508   if (vam->async_mode)
1509     {
1510       vam->async_errors += (retval < 0);
1511     }
1512   else
1513     {
1514       vam->retval = retval;
1515       vam->result_ready = 1;
1516     }
1517 }
1518
1519 static void vl_api_tap_delete_reply_t_handler_json
1520   (vl_api_tap_delete_reply_t * mp)
1521 {
1522   vat_main_t *vam = &vat_main;
1523   vat_json_node_t node;
1524
1525   vat_json_init_object (&node);
1526   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1527
1528   vat_json_print (vam->ofp, &node);
1529   vat_json_free (&node);
1530
1531   vam->retval = ntohl (mp->retval);
1532   vam->result_ready = 1;
1533 }
1534
1535 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1536   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1537 {
1538   vat_main_t *vam = &vat_main;
1539   i32 retval = ntohl (mp->retval);
1540   if (vam->async_mode)
1541     {
1542       vam->async_errors += (retval < 0);
1543     }
1544   else
1545     {
1546       vam->retval = retval;
1547       vam->result_ready = 1;
1548     }
1549 }
1550
1551 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1552   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1553 {
1554   vat_main_t *vam = &vat_main;
1555   vat_json_node_t node;
1556
1557   vat_json_init_object (&node);
1558   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1559   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1560                             ntohl (mp->tunnel_sw_if_index));
1561
1562   vat_json_print (vam->ofp, &node);
1563   vat_json_free (&node);
1564
1565   vam->retval = ntohl (mp->retval);
1566   vam->result_ready = 1;
1567 }
1568
1569 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1570   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1571 {
1572   vat_main_t *vam = &vat_main;
1573   i32 retval = ntohl (mp->retval);
1574   if (vam->async_mode)
1575     {
1576       vam->async_errors += (retval < 0);
1577     }
1578   else
1579     {
1580       vam->retval = retval;
1581       vam->sw_if_index = ntohl (mp->sw_if_index);
1582       vam->result_ready = 1;
1583     }
1584 }
1585
1586 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1587   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1588 {
1589   vat_main_t *vam = &vat_main;
1590   vat_json_node_t node;
1591
1592   vat_json_init_object (&node);
1593   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1594   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1595
1596   vat_json_print (vam->ofp, &node);
1597   vat_json_free (&node);
1598
1599   vam->retval = ntohl (mp->retval);
1600   vam->result_ready = 1;
1601 }
1602
1603
1604 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1605   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1606 {
1607   vat_main_t *vam = &vat_main;
1608   i32 retval = ntohl (mp->retval);
1609   if (vam->async_mode)
1610     {
1611       vam->async_errors += (retval < 0);
1612     }
1613   else
1614     {
1615       vam->retval = retval;
1616       vam->result_ready = 1;
1617     }
1618 }
1619
1620 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1621   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1622 {
1623   vat_main_t *vam = &vat_main;
1624   vat_json_node_t node;
1625
1626   vat_json_init_object (&node);
1627   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1628   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1629
1630   vat_json_print (vam->ofp, &node);
1631   vat_json_free (&node);
1632
1633   vam->retval = ntohl (mp->retval);
1634   vam->result_ready = 1;
1635 }
1636
1637 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1638   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1639 {
1640   vat_main_t *vam = &vat_main;
1641   i32 retval = ntohl (mp->retval);
1642   if (vam->async_mode)
1643     {
1644       vam->async_errors += (retval < 0);
1645     }
1646   else
1647     {
1648       vam->retval = retval;
1649       vam->sw_if_index = ntohl (mp->sw_if_index);
1650       vam->result_ready = 1;
1651     }
1652 }
1653
1654 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1655   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1656 {
1657   vat_main_t *vam = &vat_main;
1658   vat_json_node_t node;
1659
1660   vat_json_init_object (&node);
1661   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1662   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1663
1664   vat_json_print (vam->ofp, &node);
1665   vat_json_free (&node);
1666
1667   vam->retval = ntohl (mp->retval);
1668   vam->result_ready = 1;
1669 }
1670
1671 static void vl_api_gre_add_del_tunnel_reply_t_handler
1672   (vl_api_gre_add_del_tunnel_reply_t * mp)
1673 {
1674   vat_main_t *vam = &vat_main;
1675   i32 retval = ntohl (mp->retval);
1676   if (vam->async_mode)
1677     {
1678       vam->async_errors += (retval < 0);
1679     }
1680   else
1681     {
1682       vam->retval = retval;
1683       vam->sw_if_index = ntohl (mp->sw_if_index);
1684       vam->result_ready = 1;
1685     }
1686 }
1687
1688 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1689   (vl_api_gre_add_del_tunnel_reply_t * mp)
1690 {
1691   vat_main_t *vam = &vat_main;
1692   vat_json_node_t node;
1693
1694   vat_json_init_object (&node);
1695   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1696   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1697
1698   vat_json_print (vam->ofp, &node);
1699   vat_json_free (&node);
1700
1701   vam->retval = ntohl (mp->retval);
1702   vam->result_ready = 1;
1703 }
1704
1705 static void vl_api_create_vhost_user_if_reply_t_handler
1706   (vl_api_create_vhost_user_if_reply_t * mp)
1707 {
1708   vat_main_t *vam = &vat_main;
1709   i32 retval = ntohl (mp->retval);
1710   if (vam->async_mode)
1711     {
1712       vam->async_errors += (retval < 0);
1713     }
1714   else
1715     {
1716       vam->retval = retval;
1717       vam->sw_if_index = ntohl (mp->sw_if_index);
1718       vam->result_ready = 1;
1719     }
1720 }
1721
1722 static void vl_api_create_vhost_user_if_reply_t_handler_json
1723   (vl_api_create_vhost_user_if_reply_t * mp)
1724 {
1725   vat_main_t *vam = &vat_main;
1726   vat_json_node_t node;
1727
1728   vat_json_init_object (&node);
1729   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1730   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1731
1732   vat_json_print (vam->ofp, &node);
1733   vat_json_free (&node);
1734
1735   vam->retval = ntohl (mp->retval);
1736   vam->result_ready = 1;
1737 }
1738
1739 static void vl_api_ip_address_details_t_handler
1740   (vl_api_ip_address_details_t * mp)
1741 {
1742   vat_main_t *vam = &vat_main;
1743   static ip_address_details_t empty_ip_address_details = { {0} };
1744   ip_address_details_t *address = NULL;
1745   ip_details_t *current_ip_details = NULL;
1746   ip_details_t *details = NULL;
1747
1748   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1749
1750   if (!details || vam->current_sw_if_index >= vec_len (details)
1751       || !details[vam->current_sw_if_index].present)
1752     {
1753       errmsg ("ip address details arrived but not stored\n");
1754       errmsg ("ip_dump should be called first\n");
1755       return;
1756     }
1757
1758   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1759
1760 #define addresses (current_ip_details->addr)
1761
1762   vec_validate_init_empty (addresses, vec_len (addresses),
1763                            empty_ip_address_details);
1764
1765   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1766
1767   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1768   address->prefix_length = mp->prefix_length;
1769 #undef addresses
1770 }
1771
1772 static void vl_api_ip_address_details_t_handler_json
1773   (vl_api_ip_address_details_t * mp)
1774 {
1775   vat_main_t *vam = &vat_main;
1776   vat_json_node_t *node = NULL;
1777   struct in6_addr ip6;
1778   struct in_addr ip4;
1779
1780   if (VAT_JSON_ARRAY != vam->json_tree.type)
1781     {
1782       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1783       vat_json_init_array (&vam->json_tree);
1784     }
1785   node = vat_json_array_add (&vam->json_tree);
1786
1787   vat_json_init_object (node);
1788   if (vam->is_ipv6)
1789     {
1790       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1791       vat_json_object_add_ip6 (node, "ip", ip6);
1792     }
1793   else
1794     {
1795       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1796       vat_json_object_add_ip4 (node, "ip", ip4);
1797     }
1798   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1799 }
1800
1801 static void
1802 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1803 {
1804   vat_main_t *vam = &vat_main;
1805   static ip_details_t empty_ip_details = { 0 };
1806   ip_details_t *ip = NULL;
1807   u32 sw_if_index = ~0;
1808
1809   sw_if_index = ntohl (mp->sw_if_index);
1810
1811   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1812                            sw_if_index, empty_ip_details);
1813
1814   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1815                          sw_if_index);
1816
1817   ip->present = 1;
1818 }
1819
1820 static void
1821 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1822 {
1823   vat_main_t *vam = &vat_main;
1824
1825   if (VAT_JSON_ARRAY != vam->json_tree.type)
1826     {
1827       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1828       vat_json_init_array (&vam->json_tree);
1829     }
1830   vat_json_array_add_uint (&vam->json_tree,
1831                            clib_net_to_host_u32 (mp->sw_if_index));
1832 }
1833
1834 static void vl_api_map_domain_details_t_handler_json
1835   (vl_api_map_domain_details_t * mp)
1836 {
1837   vat_json_node_t *node = NULL;
1838   vat_main_t *vam = &vat_main;
1839   struct in6_addr ip6;
1840   struct in_addr ip4;
1841
1842   if (VAT_JSON_ARRAY != vam->json_tree.type)
1843     {
1844       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1845       vat_json_init_array (&vam->json_tree);
1846     }
1847
1848   node = vat_json_array_add (&vam->json_tree);
1849   vat_json_init_object (node);
1850
1851   vat_json_object_add_uint (node, "domain_index",
1852                             clib_net_to_host_u32 (mp->domain_index));
1853   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1854   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1855   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1856   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1857   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1858   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1859   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1860   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1861   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1862   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1863   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1864   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1865   vat_json_object_add_uint (node, "flags", mp->flags);
1866   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1867   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1868 }
1869
1870 static void vl_api_map_domain_details_t_handler
1871   (vl_api_map_domain_details_t * mp)
1872 {
1873   vat_main_t *vam = &vat_main;
1874
1875   if (mp->is_translation)
1876     {
1877       fformat (vam->ofp,
1878                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1879                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1880                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1881                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1882                clib_net_to_host_u32 (mp->domain_index));
1883     }
1884   else
1885     {
1886       fformat (vam->ofp,
1887                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1888                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1889                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1890                format_ip6_address, mp->ip6_src,
1891                clib_net_to_host_u32 (mp->domain_index));
1892     }
1893   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1894            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1895            mp->is_translation ? "map-t" : "");
1896 }
1897
1898 static void vl_api_map_rule_details_t_handler_json
1899   (vl_api_map_rule_details_t * mp)
1900 {
1901   struct in6_addr ip6;
1902   vat_json_node_t *node = NULL;
1903   vat_main_t *vam = &vat_main;
1904
1905   if (VAT_JSON_ARRAY != vam->json_tree.type)
1906     {
1907       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1908       vat_json_init_array (&vam->json_tree);
1909     }
1910
1911   node = vat_json_array_add (&vam->json_tree);
1912   vat_json_init_object (node);
1913
1914   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1915   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1916   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1917 }
1918
1919 static void
1920 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1921 {
1922   vat_main_t *vam = &vat_main;
1923   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1924            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1925 }
1926
1927 static void
1928 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1929 {
1930   vat_main_t *vam = &vat_main;
1931   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1932           "router_addr %U host_mac %U\n",
1933           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1934           format_ip4_address, &mp->host_address,
1935           format_ip4_address, &mp->router_address,
1936           format_ethernet_address, mp->host_mac);
1937 }
1938
1939 static void vl_api_dhcp_compl_event_t_handler_json
1940   (vl_api_dhcp_compl_event_t * mp)
1941 {
1942   /* JSON output not supported */
1943 }
1944
1945 static void
1946 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1947                               u32 counter)
1948 {
1949   vat_main_t *vam = &vat_main;
1950   static u64 default_counter = 0;
1951
1952   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1953                            NULL);
1954   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1955                            sw_if_index, default_counter);
1956   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1957 }
1958
1959 static void
1960 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1961                                 interface_counter_t counter)
1962 {
1963   vat_main_t *vam = &vat_main;
1964   static interface_counter_t default_counter = { 0, };
1965
1966   vec_validate_init_empty (vam->combined_interface_counters,
1967                            vnet_counter_type, NULL);
1968   vec_validate_init_empty (vam->combined_interface_counters
1969                            [vnet_counter_type], sw_if_index, default_counter);
1970   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1971 }
1972
1973 static void vl_api_vnet_interface_counters_t_handler
1974   (vl_api_vnet_interface_counters_t * mp)
1975 {
1976   /* not supported */
1977 }
1978
1979 static void vl_api_vnet_interface_counters_t_handler_json
1980   (vl_api_vnet_interface_counters_t * mp)
1981 {
1982   interface_counter_t counter;
1983   vlib_counter_t *v;
1984   u64 *v_packets;
1985   u64 packets;
1986   u32 count;
1987   u32 first_sw_if_index;
1988   int i;
1989
1990   count = ntohl (mp->count);
1991   first_sw_if_index = ntohl (mp->first_sw_if_index);
1992
1993   if (!mp->is_combined)
1994     {
1995       v_packets = (u64 *) & mp->data;
1996       for (i = 0; i < count; i++)
1997         {
1998           packets =
1999             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2000           set_simple_interface_counter (mp->vnet_counter_type,
2001                                         first_sw_if_index + i, packets);
2002           v_packets++;
2003         }
2004     }
2005   else
2006     {
2007       v = (vlib_counter_t *) & mp->data;
2008       for (i = 0; i < count; i++)
2009         {
2010           counter.packets =
2011             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2012           counter.bytes =
2013             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2014           set_combined_interface_counter (mp->vnet_counter_type,
2015                                           first_sw_if_index + i, counter);
2016           v++;
2017         }
2018     }
2019 }
2020
2021 static u32
2022 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2023 {
2024   vat_main_t *vam = &vat_main;
2025   u32 i;
2026
2027   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2028     {
2029       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2030         {
2031           return i;
2032         }
2033     }
2034   return ~0;
2035 }
2036
2037 static u32
2038 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2039 {
2040   vat_main_t *vam = &vat_main;
2041   u32 i;
2042
2043   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2044     {
2045       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2046         {
2047           return i;
2048         }
2049     }
2050   return ~0;
2051 }
2052
2053 static void vl_api_vnet_ip4_fib_counters_t_handler
2054   (vl_api_vnet_ip4_fib_counters_t * mp)
2055 {
2056   /* not supported */
2057 }
2058
2059 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2060   (vl_api_vnet_ip4_fib_counters_t * mp)
2061 {
2062   vat_main_t *vam = &vat_main;
2063   vl_api_ip4_fib_counter_t *v;
2064   ip4_fib_counter_t *counter;
2065   struct in_addr ip4;
2066   u32 vrf_id;
2067   u32 vrf_index;
2068   u32 count;
2069   int i;
2070
2071   vrf_id = ntohl (mp->vrf_id);
2072   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2073   if (~0 == vrf_index)
2074     {
2075       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2076       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2077       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2078       vec_validate (vam->ip4_fib_counters, vrf_index);
2079       vam->ip4_fib_counters[vrf_index] = NULL;
2080     }
2081
2082   vec_free (vam->ip4_fib_counters[vrf_index]);
2083   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2084   count = ntohl (mp->count);
2085   for (i = 0; i < count; i++)
2086     {
2087       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2088       counter = &vam->ip4_fib_counters[vrf_index][i];
2089       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2090       counter->address = ip4;
2091       counter->address_length = v->address_length;
2092       counter->packets = clib_net_to_host_u64 (v->packets);
2093       counter->bytes = clib_net_to_host_u64 (v->bytes);
2094       v++;
2095     }
2096 }
2097
2098 static void vl_api_vnet_ip6_fib_counters_t_handler
2099   (vl_api_vnet_ip6_fib_counters_t * mp)
2100 {
2101   /* not supported */
2102 }
2103
2104 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2105   (vl_api_vnet_ip6_fib_counters_t * mp)
2106 {
2107   vat_main_t *vam = &vat_main;
2108   vl_api_ip6_fib_counter_t *v;
2109   ip6_fib_counter_t *counter;
2110   struct in6_addr ip6;
2111   u32 vrf_id;
2112   u32 vrf_index;
2113   u32 count;
2114   int i;
2115
2116   vrf_id = ntohl (mp->vrf_id);
2117   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2118   if (~0 == vrf_index)
2119     {
2120       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2121       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2122       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2123       vec_validate (vam->ip6_fib_counters, vrf_index);
2124       vam->ip6_fib_counters[vrf_index] = NULL;
2125     }
2126
2127   vec_free (vam->ip6_fib_counters[vrf_index]);
2128   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2129   count = ntohl (mp->count);
2130   for (i = 0; i < count; i++)
2131     {
2132       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2133       counter = &vam->ip6_fib_counters[vrf_index][i];
2134       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2135       counter->address = ip6;
2136       counter->address_length = v->address_length;
2137       counter->packets = clib_net_to_host_u64 (v->packets);
2138       counter->bytes = clib_net_to_host_u64 (v->bytes);
2139       v++;
2140     }
2141 }
2142
2143 static void vl_api_get_first_msg_id_reply_t_handler
2144   (vl_api_get_first_msg_id_reply_t * mp)
2145 {
2146   vat_main_t *vam = &vat_main;
2147   i32 retval = ntohl (mp->retval);
2148
2149   if (vam->async_mode)
2150     {
2151       vam->async_errors += (retval < 0);
2152     }
2153   else
2154     {
2155       vam->retval = retval;
2156       vam->result_ready = 1;
2157     }
2158   if (retval >= 0)
2159     {
2160       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2161     }
2162 }
2163
2164 static void vl_api_get_first_msg_id_reply_t_handler_json
2165   (vl_api_get_first_msg_id_reply_t * mp)
2166 {
2167   vat_main_t *vam = &vat_main;
2168   vat_json_node_t node;
2169
2170   vat_json_init_object (&node);
2171   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2172   vat_json_object_add_uint (&node, "first_msg_id",
2173                             (uint) ntohs (mp->first_msg_id));
2174
2175   vat_json_print (vam->ofp, &node);
2176   vat_json_free (&node);
2177
2178   vam->retval = ntohl (mp->retval);
2179   vam->result_ready = 1;
2180 }
2181
2182 static void vl_api_get_node_graph_reply_t_handler
2183   (vl_api_get_node_graph_reply_t * mp)
2184 {
2185   vat_main_t *vam = &vat_main;
2186   api_main_t *am = &api_main;
2187   i32 retval = ntohl (mp->retval);
2188   u8 *pvt_copy, *reply;
2189   void *oldheap;
2190   vlib_node_t *node;
2191   int i;
2192
2193   if (vam->async_mode)
2194     {
2195       vam->async_errors += (retval < 0);
2196     }
2197   else
2198     {
2199       vam->retval = retval;
2200       vam->result_ready = 1;
2201     }
2202
2203   /* "Should never happen..." */
2204   if (retval != 0)
2205     return;
2206
2207   reply = (u8 *) (mp->reply_in_shmem);
2208   pvt_copy = vec_dup (reply);
2209
2210   /* Toss the shared-memory original... */
2211   pthread_mutex_lock (&am->vlib_rp->mutex);
2212   oldheap = svm_push_data_heap (am->vlib_rp);
2213
2214   vec_free (reply);
2215
2216   svm_pop_heap (oldheap);
2217   pthread_mutex_unlock (&am->vlib_rp->mutex);
2218
2219   if (vam->graph_nodes)
2220     {
2221       hash_free (vam->graph_node_index_by_name);
2222
2223       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2224         {
2225           node = vam->graph_nodes[i];
2226           vec_free (node->name);
2227           vec_free (node->next_nodes);
2228           vec_free (node);
2229         }
2230       vec_free (vam->graph_nodes);
2231     }
2232
2233   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2234   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2235   vec_free (pvt_copy);
2236
2237   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2238     {
2239       node = vam->graph_nodes[i];
2240       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2241     }
2242 }
2243
2244 static void vl_api_get_node_graph_reply_t_handler_json
2245   (vl_api_get_node_graph_reply_t * mp)
2246 {
2247   vat_main_t *vam = &vat_main;
2248   api_main_t *am = &api_main;
2249   void *oldheap;
2250   vat_json_node_t node;
2251   u8 *reply;
2252
2253   /* $$$$ make this real? */
2254   vat_json_init_object (&node);
2255   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2256   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2257
2258   reply = (u8 *) (mp->reply_in_shmem);
2259
2260   /* Toss the shared-memory original... */
2261   pthread_mutex_lock (&am->vlib_rp->mutex);
2262   oldheap = svm_push_data_heap (am->vlib_rp);
2263
2264   vec_free (reply);
2265
2266   svm_pop_heap (oldheap);
2267   pthread_mutex_unlock (&am->vlib_rp->mutex);
2268
2269   vat_json_print (vam->ofp, &node);
2270   vat_json_free (&node);
2271
2272   vam->retval = ntohl (mp->retval);
2273   vam->result_ready = 1;
2274 }
2275
2276 static void
2277 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2278 {
2279   vat_main_t *vam = &vat_main;
2280   locator_msg_t loc;
2281   u8 *tmp_str = 0;
2282
2283   memset (&loc, 0, sizeof (loc));
2284   if (vam->noprint_msg)
2285     {
2286       loc.local = mp->local;
2287       loc.priority = mp->priority;
2288       loc.weight = mp->weight;
2289       if (loc.local)
2290         {
2291           loc.sw_if_index = ntohl (mp->sw_if_index);
2292         }
2293       else
2294         {
2295           loc.is_ipv6 = mp->is_ipv6;
2296           clib_memcpy (loc.ip_address, mp->ip_address,
2297                        sizeof (loc.ip_address));
2298         }
2299       vec_add1 (vam->locator_msg, loc);
2300     }
2301   else
2302     {
2303       if (mp->local)
2304         {
2305           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
2306                             ntohl (mp->sw_if_index),
2307                             mp->priority, mp->weight);
2308         }
2309       else
2310         {
2311           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
2312                             mp->is_ipv6 ? format_ip6_address :
2313                             format_ip4_address,
2314                             mp->ip_address, mp->priority, mp->weight);
2315         }
2316
2317       fformat (vam->ofp, "%s", tmp_str);
2318
2319       vec_free (tmp_str);
2320     }
2321 }
2322
2323 static void
2324 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2325                                             mp)
2326 {
2327   vat_main_t *vam = &vat_main;
2328   vat_json_node_t *node = NULL;
2329   locator_msg_t loc;
2330   struct in6_addr ip6;
2331   struct in_addr ip4;
2332
2333   memset (&loc, 0, sizeof (loc));
2334   if (vam->noprint_msg)
2335     {
2336       loc.local = mp->local;
2337       loc.priority = mp->priority;
2338       loc.weight = mp->weight;
2339       if (loc.local)
2340         {
2341           loc.sw_if_index = ntohl (mp->sw_if_index);
2342         }
2343       else
2344         {
2345           loc.is_ipv6 = mp->is_ipv6;
2346           clib_memcpy (loc.ip_address, mp->ip_address,
2347                        sizeof (loc.ip_address));
2348         }
2349       vec_add1 (vam->locator_msg, loc);
2350       return;
2351     }
2352
2353   if (VAT_JSON_ARRAY != vam->json_tree.type)
2354     {
2355       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2356       vat_json_init_array (&vam->json_tree);
2357     }
2358   node = vat_json_array_add (&vam->json_tree);
2359
2360   vat_json_init_object (node);
2361
2362   if (mp->local)
2363     {
2364       vat_json_object_add_uint (node, "locator_index",
2365                                 ntohl (mp->sw_if_index));
2366     }
2367   else
2368     {
2369       if (mp->is_ipv6)
2370         {
2371           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2372           vat_json_object_add_ip6 (node, "locator", ip6);
2373         }
2374       else
2375         {
2376           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2377           vat_json_object_add_ip4 (node, "locator", ip4);
2378         }
2379     }
2380   vat_json_object_add_uint (node, "priority", mp->priority);
2381   vat_json_object_add_uint (node, "weight", mp->weight);
2382 }
2383
2384 static void
2385 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2386                                            mp)
2387 {
2388   vat_main_t *vam = &vat_main;
2389   locator_set_msg_t ls;
2390
2391   ls.locator_set_index = ntohl (mp->locator_set_index);
2392   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2393   vec_add1 (vam->locator_set_msg, ls);
2394 }
2395
2396 static void
2397   vl_api_lisp_locator_set_details_t_handler_json
2398   (vl_api_lisp_locator_set_details_t * mp)
2399 {
2400   vat_main_t *vam = &vat_main;
2401   locator_set_msg_t ls;
2402
2403   ls.locator_set_index = ntohl (mp->locator_set_index);
2404   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2405   vec_add1 (vam->locator_set_msg, ls);
2406 }
2407
2408 static void
2409 add_lisp_eid_table_entry (vat_main_t * vam,
2410                           vl_api_lisp_eid_table_details_t * mp)
2411 {
2412   eid_table_t eid_table;
2413
2414   memset (&eid_table, 0, sizeof (eid_table));
2415   eid_table.is_local = mp->is_local;
2416   eid_table.locator_set_index = clib_net_to_host_u32 (mp->locator_set_index);
2417   eid_table.eid_type = mp->eid_type;
2418   eid_table.vni = clib_net_to_host_u32 (mp->vni);
2419   eid_table.eid_prefix_len = mp->eid_prefix_len;
2420   eid_table.ttl = clib_net_to_host_u32 (mp->ttl);
2421   eid_table.action = mp->action;
2422   eid_table.authoritative = mp->authoritative;
2423   clib_memcpy (eid_table.eid, mp->eid, sizeof (eid_table.eid));
2424   vec_add1 (vam->eid_tables, eid_table);
2425 }
2426
2427 static void
2428 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2429 {
2430   vat_main_t *vam = &vat_main;
2431   add_lisp_eid_table_entry (vam, mp);
2432 }
2433
2434 static void
2435 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2436                                               * mp)
2437 {
2438   vat_main_t *vam = &vat_main;
2439   add_lisp_eid_table_entry (vam, mp);
2440 }
2441
2442 static void
2443   vl_api_lisp_eid_table_map_details_t_handler
2444   (vl_api_lisp_eid_table_map_details_t * mp)
2445 {
2446   vat_main_t *vam = &vat_main;
2447
2448   u8 *line = format (0, "%=10d%=10d",
2449                      clib_net_to_host_u32 (mp->vni),
2450                      clib_net_to_host_u32 (mp->dp_table));
2451   fformat (vam->ofp, "%v\n", line);
2452   vec_free (line);
2453 }
2454
2455 static void
2456   vl_api_lisp_eid_table_map_details_t_handler_json
2457   (vl_api_lisp_eid_table_map_details_t * mp)
2458 {
2459   vat_main_t *vam = &vat_main;
2460   vat_json_node_t *node = NULL;
2461
2462   if (VAT_JSON_ARRAY != vam->json_tree.type)
2463     {
2464       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2465       vat_json_init_array (&vam->json_tree);
2466     }
2467   node = vat_json_array_add (&vam->json_tree);
2468   vat_json_init_object (node);
2469   vat_json_object_add_uint (node, "dp_table",
2470                             clib_net_to_host_u32 (mp->dp_table));
2471   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2472 }
2473
2474 static void
2475   vl_api_lisp_eid_table_vni_details_t_handler
2476   (vl_api_lisp_eid_table_vni_details_t * mp)
2477 {
2478   vat_main_t *vam = &vat_main;
2479
2480   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2481   fformat (vam->ofp, "%v\n", line);
2482   vec_free (line);
2483 }
2484
2485 static void
2486   vl_api_lisp_eid_table_vni_details_t_handler_json
2487   (vl_api_lisp_eid_table_vni_details_t * mp)
2488 {
2489   vat_main_t *vam = &vat_main;
2490   vat_json_node_t *node = NULL;
2491
2492   if (VAT_JSON_ARRAY != vam->json_tree.type)
2493     {
2494       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2495       vat_json_init_array (&vam->json_tree);
2496     }
2497   node = vat_json_array_add (&vam->json_tree);
2498   vat_json_init_object (node);
2499   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2500 }
2501
2502 static u8 *
2503 format_decap_next (u8 * s, va_list * args)
2504 {
2505   u32 next_index = va_arg (*args, u32);
2506
2507   switch (next_index)
2508     {
2509     case LISP_GPE_INPUT_NEXT_DROP:
2510       return format (s, "drop");
2511     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2512       return format (s, "ip4");
2513     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2514       return format (s, "ip6");
2515     default:
2516       return format (s, "unknown %d", next_index);
2517     }
2518   return s;
2519 }
2520
2521 static void
2522 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2523                                           mp)
2524 {
2525   vat_main_t *vam = &vat_main;
2526   u8 *iid_str;
2527   u8 *flag_str = NULL;
2528
2529   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2530
2531 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2532   foreach_lisp_gpe_flag_bit;
2533 #undef _
2534
2535   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2536            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2537            mp->tunnels,
2538            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2539            mp->source_ip,
2540            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2541            mp->destination_ip,
2542            ntohl (mp->encap_fib_id),
2543            ntohl (mp->decap_fib_id),
2544            format_decap_next, ntohl (mp->dcap_next),
2545            mp->ver_res >> 6,
2546            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2547
2548   vec_free (iid_str);
2549 }
2550
2551 static void
2552   vl_api_lisp_gpe_tunnel_details_t_handler_json
2553   (vl_api_lisp_gpe_tunnel_details_t * mp)
2554 {
2555   vat_main_t *vam = &vat_main;
2556   vat_json_node_t *node = NULL;
2557   struct in6_addr ip6;
2558   struct in_addr ip4;
2559   u8 *next_decap_str;
2560
2561   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2562
2563   if (VAT_JSON_ARRAY != vam->json_tree.type)
2564     {
2565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2566       vat_json_init_array (&vam->json_tree);
2567     }
2568   node = vat_json_array_add (&vam->json_tree);
2569
2570   vat_json_init_object (node);
2571   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2572   if (mp->is_ipv6)
2573     {
2574       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2575       vat_json_object_add_ip6 (node, "source address", ip6);
2576       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2577       vat_json_object_add_ip6 (node, "destination address", ip6);
2578     }
2579   else
2580     {
2581       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2582       vat_json_object_add_ip4 (node, "source address", ip4);
2583       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2584       vat_json_object_add_ip4 (node, "destination address", ip4);
2585     }
2586   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2587   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2588   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2589   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2590   vat_json_object_add_uint (node, "flags", mp->flags);
2591   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2592   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2593   vat_json_object_add_uint (node, "res", mp->res);
2594   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2595
2596   vec_free (next_decap_str);
2597 }
2598
2599 static void
2600 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2601                                             * mp)
2602 {
2603   vat_main_t *vam = &vat_main;
2604
2605   fformat (vam->ofp, "%=20U\n",
2606            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2607            mp->ip_address);
2608 }
2609
2610 static void
2611   vl_api_lisp_map_resolver_details_t_handler_json
2612   (vl_api_lisp_map_resolver_details_t * mp)
2613 {
2614   vat_main_t *vam = &vat_main;
2615   vat_json_node_t *node = NULL;
2616   struct in6_addr ip6;
2617   struct in_addr ip4;
2618
2619   if (VAT_JSON_ARRAY != vam->json_tree.type)
2620     {
2621       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2622       vat_json_init_array (&vam->json_tree);
2623     }
2624   node = vat_json_array_add (&vam->json_tree);
2625
2626   vat_json_init_object (node);
2627   if (mp->is_ipv6)
2628     {
2629       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2630       vat_json_object_add_ip6 (node, "map resolver", ip6);
2631     }
2632   else
2633     {
2634       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2635       vat_json_object_add_ip4 (node, "map resolver", ip4);
2636     }
2637 }
2638
2639 static void
2640   vl_api_show_lisp_status_reply_t_handler
2641   (vl_api_show_lisp_status_reply_t * mp)
2642 {
2643   vat_main_t *vam = &vat_main;
2644   i32 retval = ntohl (mp->retval);
2645
2646   if (0 <= retval)
2647     {
2648       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2649                mp->feature_status ? "enabled" : "disabled",
2650                mp->gpe_status ? "enabled" : "disabled");
2651     }
2652
2653   vam->retval = retval;
2654   vam->result_ready = 1;
2655 }
2656
2657 static void
2658   vl_api_show_lisp_status_reply_t_handler_json
2659   (vl_api_show_lisp_status_reply_t * mp)
2660 {
2661   vat_main_t *vam = &vat_main;
2662   vat_json_node_t node;
2663   u8 *gpe_status = NULL;
2664   u8 *feature_status = NULL;
2665
2666   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2667   feature_status = format (0, "%s",
2668                            mp->feature_status ? "enabled" : "disabled");
2669   vec_add1 (gpe_status, 0);
2670   vec_add1 (feature_status, 0);
2671
2672   vat_json_init_object (&node);
2673   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2674   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2675
2676   vec_free (gpe_status);
2677   vec_free (feature_status);
2678
2679   vat_json_print (vam->ofp, &node);
2680   vat_json_free (&node);
2681
2682   vam->retval = ntohl (mp->retval);
2683   vam->result_ready = 1;
2684 }
2685
2686 static void
2687   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2688   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2689 {
2690   vat_main_t *vam = &vat_main;
2691   i32 retval = ntohl (mp->retval);
2692
2693   if (retval >= 0)
2694     {
2695       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2696     }
2697
2698   vam->retval = retval;
2699   vam->result_ready = 1;
2700 }
2701
2702 static void
2703   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2704   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   vat_json_node_t *node = NULL;
2708
2709   if (VAT_JSON_ARRAY != vam->json_tree.type)
2710     {
2711       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2712       vat_json_init_array (&vam->json_tree);
2713     }
2714   node = vat_json_array_add (&vam->json_tree);
2715
2716   vat_json_init_object (node);
2717   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2718
2719   vat_json_print (vam->ofp, node);
2720   vat_json_free (node);
2721
2722   vam->retval = ntohl (mp->retval);
2723   vam->result_ready = 1;
2724 }
2725
2726 static void
2727 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2728 {
2729   vat_main_t *vam = &vat_main;
2730   i32 retval = ntohl (mp->retval);
2731
2732   if (0 <= retval)
2733     {
2734       fformat (vam->ofp, "%-20s%-16s\n",
2735                mp->status ? "enabled" : "disabled",
2736                mp->status ? (char *) mp->locator_set_name : "");
2737     }
2738
2739   vam->retval = retval;
2740   vam->result_ready = 1;
2741 }
2742
2743 static void
2744 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2745                                             mp)
2746 {
2747   vat_main_t *vam = &vat_main;
2748   vat_json_node_t node;
2749   u8 *status = 0;
2750
2751   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2752   vec_add1 (status, 0);
2753
2754   vat_json_init_object (&node);
2755   vat_json_object_add_string_copy (&node, "status", status);
2756   if (mp->status)
2757     {
2758       vat_json_object_add_string_copy (&node, "locator_set",
2759                                        mp->locator_set_name);
2760     }
2761
2762   vec_free (status);
2763
2764   vat_json_print (vam->ofp, &node);
2765   vat_json_free (&node);
2766
2767   vam->retval = ntohl (mp->retval);
2768   vam->result_ready = 1;
2769 }
2770
2771 static u8 *
2772 format_policer_type (u8 * s, va_list * va)
2773 {
2774   u32 i = va_arg (*va, u32);
2775
2776   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2777     s = format (s, "1r2c");
2778   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2779     s = format (s, "1r3c");
2780   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2781     s = format (s, "2r3c-2698");
2782   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2783     s = format (s, "2r3c-4115");
2784   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2785     s = format (s, "2r3c-mef5cf1");
2786   else
2787     s = format (s, "ILLEGAL");
2788   return s;
2789 }
2790
2791 static u8 *
2792 format_policer_rate_type (u8 * s, va_list * va)
2793 {
2794   u32 i = va_arg (*va, u32);
2795
2796   if (i == SSE2_QOS_RATE_KBPS)
2797     s = format (s, "kbps");
2798   else if (i == SSE2_QOS_RATE_PPS)
2799     s = format (s, "pps");
2800   else
2801     s = format (s, "ILLEGAL");
2802   return s;
2803 }
2804
2805 static u8 *
2806 format_policer_round_type (u8 * s, va_list * va)
2807 {
2808   u32 i = va_arg (*va, u32);
2809
2810   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2811     s = format (s, "closest");
2812   else if (i == SSE2_QOS_ROUND_TO_UP)
2813     s = format (s, "up");
2814   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2815     s = format (s, "down");
2816   else
2817     s = format (s, "ILLEGAL");
2818   return s;
2819 }
2820
2821 static u8 *
2822 format_policer_action_type (u8 * s, va_list * va)
2823 {
2824   u32 i = va_arg (*va, u32);
2825
2826   if (i == SSE2_QOS_ACTION_DROP)
2827     s = format (s, "drop");
2828   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2829     s = format (s, "transmit");
2830   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2831     s = format (s, "mark-and-transmit");
2832   else
2833     s = format (s, "ILLEGAL");
2834   return s;
2835 }
2836
2837 static u8 *
2838 format_dscp (u8 * s, va_list * va)
2839 {
2840   u32 i = va_arg (*va, u32);
2841   char *t = 0;
2842
2843   switch (i)
2844     {
2845 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2846       foreach_vnet_dscp
2847 #undef _
2848     default:
2849       return format (s, "ILLEGAL");
2850     }
2851   s = format (s, "%s", t);
2852   return s;
2853 }
2854
2855 static void
2856 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2857 {
2858   vat_main_t *vam = &vat_main;
2859   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2860
2861   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2862     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2863   else
2864     conform_dscp_str = format (0, "");
2865
2866   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2867     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2868   else
2869     exceed_dscp_str = format (0, "");
2870
2871   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2872     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2873   else
2874     violate_dscp_str = format (0, "");
2875
2876   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2877            "rate type %U, round type %U, %s rate, %s color-aware, "
2878            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2879            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2880            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2881            mp->name,
2882            format_policer_type, mp->type,
2883            ntohl (mp->cir),
2884            ntohl (mp->eir),
2885            clib_net_to_host_u64 (mp->cb),
2886            clib_net_to_host_u64 (mp->eb),
2887            format_policer_rate_type, mp->rate_type,
2888            format_policer_round_type, mp->round_type,
2889            mp->single_rate ? "single" : "dual",
2890            mp->color_aware ? "is" : "not",
2891            ntohl (mp->cir_tokens_per_period),
2892            ntohl (mp->pir_tokens_per_period),
2893            ntohl (mp->scale),
2894            ntohl (mp->current_limit),
2895            ntohl (mp->current_bucket),
2896            ntohl (mp->extended_limit),
2897            ntohl (mp->extended_bucket),
2898            clib_net_to_host_u64 (mp->last_update_time),
2899            format_policer_action_type, mp->conform_action_type,
2900            conform_dscp_str,
2901            format_policer_action_type, mp->exceed_action_type,
2902            exceed_dscp_str,
2903            format_policer_action_type, mp->violate_action_type,
2904            violate_dscp_str);
2905
2906   vec_free (conform_dscp_str);
2907   vec_free (exceed_dscp_str);
2908   vec_free (violate_dscp_str);
2909 }
2910
2911 static void vl_api_policer_details_t_handler_json
2912   (vl_api_policer_details_t * mp)
2913 {
2914   vat_main_t *vam = &vat_main;
2915   vat_json_node_t *node;
2916   u8 *rate_type_str, *round_type_str, *type_str;
2917   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2918
2919   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2920   round_type_str =
2921     format (0, "%U", format_policer_round_type, mp->round_type);
2922   type_str = format (0, "%U", format_policer_type, mp->type);
2923   conform_action_str = format (0, "%U", format_policer_action_type,
2924                                mp->conform_action_type);
2925   exceed_action_str = format (0, "%U", format_policer_action_type,
2926                               mp->exceed_action_type);
2927   violate_action_str = format (0, "%U", format_policer_action_type,
2928                                mp->violate_action_type);
2929
2930   if (VAT_JSON_ARRAY != vam->json_tree.type)
2931     {
2932       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2933       vat_json_init_array (&vam->json_tree);
2934     }
2935   node = vat_json_array_add (&vam->json_tree);
2936
2937   vat_json_init_object (node);
2938   vat_json_object_add_string_copy (node, "name", mp->name);
2939   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2940   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2941   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
2942   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
2943   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2944   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2945   vat_json_object_add_string_copy (node, "type", type_str);
2946   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2947   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2948   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2949   vat_json_object_add_uint (node, "cir_tokens_per_period",
2950                             ntohl (mp->cir_tokens_per_period));
2951   vat_json_object_add_uint (node, "eir_tokens_per_period",
2952                             ntohl (mp->pir_tokens_per_period));
2953   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2954   vat_json_object_add_uint (node, "current_bucket",
2955                             ntohl (mp->current_bucket));
2956   vat_json_object_add_uint (node, "extended_limit",
2957                             ntohl (mp->extended_limit));
2958   vat_json_object_add_uint (node, "extended_bucket",
2959                             ntohl (mp->extended_bucket));
2960   vat_json_object_add_uint (node, "last_update_time",
2961                             ntohl (mp->last_update_time));
2962   vat_json_object_add_string_copy (node, "conform_action",
2963                                    conform_action_str);
2964   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2965     {
2966       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2967       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2968       vec_free (dscp_str);
2969     }
2970   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
2971   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2972     {
2973       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2974       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2975       vec_free (dscp_str);
2976     }
2977   vat_json_object_add_string_copy (node, "violate_action",
2978                                    violate_action_str);
2979   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2980     {
2981       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2982       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2983       vec_free (dscp_str);
2984     }
2985
2986   vec_free (rate_type_str);
2987   vec_free (round_type_str);
2988   vec_free (type_str);
2989   vec_free (conform_action_str);
2990   vec_free (exceed_action_str);
2991   vec_free (violate_action_str);
2992 }
2993
2994 static void
2995 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2996                                            mp)
2997 {
2998   vat_main_t *vam = &vat_main;
2999   int i, count = ntohl (mp->count);
3000
3001   if (count > 0)
3002     fformat (vam->ofp, "classify table ids (%d) : ", count);
3003   for (i = 0; i < count; i++)
3004     {
3005       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3006       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3007     }
3008   vam->retval = ntohl (mp->retval);
3009   vam->result_ready = 1;
3010 }
3011
3012 static void
3013   vl_api_classify_table_ids_reply_t_handler_json
3014   (vl_api_classify_table_ids_reply_t * mp)
3015 {
3016   vat_main_t *vam = &vat_main;
3017   int i, count = ntohl (mp->count);
3018
3019   if (count > 0)
3020     {
3021       vat_json_node_t node;
3022
3023       vat_json_init_object (&node);
3024       for (i = 0; i < count; i++)
3025         {
3026           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3027         }
3028       vat_json_print (vam->ofp, &node);
3029       vat_json_free (&node);
3030     }
3031   vam->retval = ntohl (mp->retval);
3032   vam->result_ready = 1;
3033 }
3034
3035 static void
3036   vl_api_classify_table_by_interface_reply_t_handler
3037   (vl_api_classify_table_by_interface_reply_t * mp)
3038 {
3039   vat_main_t *vam = &vat_main;
3040   u32 table_id;
3041
3042   table_id = ntohl (mp->l2_table_id);
3043   if (table_id != ~0)
3044     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3045   else
3046     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3047   table_id = ntohl (mp->ip4_table_id);
3048   if (table_id != ~0)
3049     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3050   else
3051     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3052   table_id = ntohl (mp->ip6_table_id);
3053   if (table_id != ~0)
3054     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3055   else
3056     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3057   vam->retval = ntohl (mp->retval);
3058   vam->result_ready = 1;
3059 }
3060
3061 static void
3062   vl_api_classify_table_by_interface_reply_t_handler_json
3063   (vl_api_classify_table_by_interface_reply_t * mp)
3064 {
3065   vat_main_t *vam = &vat_main;
3066   vat_json_node_t node;
3067
3068   vat_json_init_object (&node);
3069
3070   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3071   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3072   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3073
3074   vat_json_print (vam->ofp, &node);
3075   vat_json_free (&node);
3076
3077   vam->retval = ntohl (mp->retval);
3078   vam->result_ready = 1;
3079 }
3080
3081 static void vl_api_policer_add_del_reply_t_handler
3082   (vl_api_policer_add_del_reply_t * mp)
3083 {
3084   vat_main_t *vam = &vat_main;
3085   i32 retval = ntohl (mp->retval);
3086   if (vam->async_mode)
3087     {
3088       vam->async_errors += (retval < 0);
3089     }
3090   else
3091     {
3092       vam->retval = retval;
3093       vam->result_ready = 1;
3094       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3095         /*
3096          * Note: this is just barely thread-safe, depends on
3097          * the main thread spinning waiting for an answer...
3098          */
3099         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3100     }
3101 }
3102
3103 static void vl_api_policer_add_del_reply_t_handler_json
3104   (vl_api_policer_add_del_reply_t * mp)
3105 {
3106   vat_main_t *vam = &vat_main;
3107   vat_json_node_t node;
3108
3109   vat_json_init_object (&node);
3110   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3111   vat_json_object_add_uint (&node, "policer_index",
3112                             ntohl (mp->policer_index));
3113
3114   vat_json_print (vam->ofp, &node);
3115   vat_json_free (&node);
3116
3117   vam->retval = ntohl (mp->retval);
3118   vam->result_ready = 1;
3119 }
3120
3121 /* Format hex dump. */
3122 u8 *
3123 format_hex_bytes (u8 * s, va_list * va)
3124 {
3125   u8 *bytes = va_arg (*va, u8 *);
3126   int n_bytes = va_arg (*va, int);
3127   uword i;
3128
3129   /* Print short or long form depending on byte count. */
3130   uword short_form = n_bytes <= 32;
3131   uword indent = format_get_indent (s);
3132
3133   if (n_bytes == 0)
3134     return s;
3135
3136   for (i = 0; i < n_bytes; i++)
3137     {
3138       if (!short_form && (i % 32) == 0)
3139         s = format (s, "%08x: ", i);
3140       s = format (s, "%02x", bytes[i]);
3141       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3142         s = format (s, "\n%U", format_white_space, indent);
3143     }
3144
3145   return s;
3146 }
3147
3148 static void
3149 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3150                                             * mp)
3151 {
3152   vat_main_t *vam = &vat_main;
3153   i32 retval = ntohl (mp->retval);
3154   if (retval == 0)
3155     {
3156       fformat (vam->ofp, "classify table info :\n");
3157       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3158                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3159                ntohl (mp->miss_next_index));
3160       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3161                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3162                ntohl (mp->match_n_vectors));
3163       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3164                ntohl (mp->mask_length));
3165     }
3166   vam->retval = retval;
3167   vam->result_ready = 1;
3168 }
3169
3170 static void
3171   vl_api_classify_table_info_reply_t_handler_json
3172   (vl_api_classify_table_info_reply_t * mp)
3173 {
3174   vat_main_t *vam = &vat_main;
3175   vat_json_node_t node;
3176
3177   i32 retval = ntohl (mp->retval);
3178   if (retval == 0)
3179     {
3180       vat_json_init_object (&node);
3181
3182       vat_json_object_add_int (&node, "sessions",
3183                                ntohl (mp->active_sessions));
3184       vat_json_object_add_int (&node, "nexttbl",
3185                                ntohl (mp->next_table_index));
3186       vat_json_object_add_int (&node, "nextnode",
3187                                ntohl (mp->miss_next_index));
3188       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3189       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3190       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3191       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3192                       ntohl (mp->mask_length), 0);
3193       vat_json_object_add_string_copy (&node, "mask", s);
3194
3195       vat_json_print (vam->ofp, &node);
3196       vat_json_free (&node);
3197     }
3198   vam->retval = ntohl (mp->retval);
3199   vam->result_ready = 1;
3200 }
3201
3202 static void
3203 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3204                                            mp)
3205 {
3206   vat_main_t *vam = &vat_main;
3207
3208   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3209            ntohl (mp->hit_next_index), ntohl (mp->advance),
3210            ntohl (mp->opaque_index));
3211   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3212            ntohl (mp->match_length));
3213 }
3214
3215 static void
3216   vl_api_classify_session_details_t_handler_json
3217   (vl_api_classify_session_details_t * mp)
3218 {
3219   vat_main_t *vam = &vat_main;
3220   vat_json_node_t *node = NULL;
3221
3222   if (VAT_JSON_ARRAY != vam->json_tree.type)
3223     {
3224       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3225       vat_json_init_array (&vam->json_tree);
3226     }
3227   node = vat_json_array_add (&vam->json_tree);
3228
3229   vat_json_init_object (node);
3230   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3231   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3232   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3233   u8 *s =
3234     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3235             0);
3236   vat_json_object_add_string_copy (node, "match", s);
3237 }
3238
3239 static void vl_api_pg_create_interface_reply_t_handler
3240   (vl_api_pg_create_interface_reply_t * mp)
3241 {
3242   vat_main_t *vam = &vat_main;
3243
3244   vam->retval = ntohl (mp->retval);
3245   vam->result_ready = 1;
3246 }
3247
3248 static void vl_api_pg_create_interface_reply_t_handler_json
3249   (vl_api_pg_create_interface_reply_t * mp)
3250 {
3251   vat_main_t *vam = &vat_main;
3252   vat_json_node_t node;
3253
3254   i32 retval = ntohl (mp->retval);
3255   if (retval == 0)
3256     {
3257       vat_json_init_object (&node);
3258
3259       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3260
3261       vat_json_print (vam->ofp, &node);
3262       vat_json_free (&node);
3263     }
3264   vam->retval = ntohl (mp->retval);
3265   vam->result_ready = 1;
3266 }
3267
3268 static void vl_api_policer_classify_details_t_handler
3269   (vl_api_policer_classify_details_t * mp)
3270 {
3271   vat_main_t *vam = &vat_main;
3272
3273   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3274            ntohl (mp->table_index));
3275 }
3276
3277 static void vl_api_policer_classify_details_t_handler_json
3278   (vl_api_policer_classify_details_t * mp)
3279 {
3280   vat_main_t *vam = &vat_main;
3281   vat_json_node_t *node;
3282
3283   if (VAT_JSON_ARRAY != vam->json_tree.type)
3284     {
3285       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3286       vat_json_init_array (&vam->json_tree);
3287     }
3288   node = vat_json_array_add (&vam->json_tree);
3289
3290   vat_json_init_object (node);
3291   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3292   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3293 }
3294
3295 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3296   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3297 {
3298   vat_main_t *vam = &vat_main;
3299   i32 retval = ntohl (mp->retval);
3300   if (vam->async_mode)
3301     {
3302       vam->async_errors += (retval < 0);
3303     }
3304   else
3305     {
3306       vam->retval = retval;
3307       vam->sw_if_index = ntohl (mp->sw_if_index);
3308       vam->result_ready = 1;
3309     }
3310 }
3311
3312 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3313   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3314 {
3315   vat_main_t *vam = &vat_main;
3316   vat_json_node_t node;
3317
3318   vat_json_init_object (&node);
3319   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3320   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3321
3322   vat_json_print (vam->ofp, &node);
3323   vat_json_free (&node);
3324
3325   vam->retval = ntohl (mp->retval);
3326   vam->result_ready = 1;
3327 }
3328
3329 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3330 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3331 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3332 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3333
3334 /*
3335  * Generate boilerplate reply handlers, which
3336  * dig the return value out of the xxx_reply_t API message,
3337  * stick it into vam->retval, and set vam->result_ready
3338  *
3339  * Could also do this by pointing N message decode slots at
3340  * a single function, but that could break in subtle ways.
3341  */
3342
3343 #define foreach_standard_reply_retval_handler           \
3344 _(sw_interface_set_flags_reply)                         \
3345 _(sw_interface_add_del_address_reply)                   \
3346 _(sw_interface_set_table_reply)                         \
3347 _(sw_interface_set_vpath_reply)                         \
3348 _(sw_interface_set_l2_bridge_reply)                     \
3349 _(bridge_domain_add_del_reply)                          \
3350 _(sw_interface_set_l2_xconnect_reply)                   \
3351 _(l2fib_add_del_reply)                                  \
3352 _(ip_add_del_route_reply)                               \
3353 _(proxy_arp_add_del_reply)                              \
3354 _(proxy_arp_intfc_enable_disable_reply)                 \
3355 _(mpls_add_del_encap_reply)                             \
3356 _(mpls_add_del_decap_reply)                             \
3357 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3358 _(sw_interface_set_unnumbered_reply)                    \
3359 _(ip_neighbor_add_del_reply)                            \
3360 _(reset_vrf_reply)                                      \
3361 _(oam_add_del_reply)                                    \
3362 _(reset_fib_reply)                                      \
3363 _(dhcp_proxy_config_reply)                              \
3364 _(dhcp_proxy_config_2_reply)                            \
3365 _(dhcp_proxy_set_vss_reply)                             \
3366 _(dhcp_client_config_reply)                             \
3367 _(set_ip_flow_hash_reply)                               \
3368 _(sw_interface_ip6_enable_disable_reply)                \
3369 _(sw_interface_ip6_set_link_local_address_reply)        \
3370 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3371 _(sw_interface_ip6nd_ra_config_reply)                   \
3372 _(set_arp_neighbor_limit_reply)                         \
3373 _(l2_patch_add_del_reply)                               \
3374 _(sr_tunnel_add_del_reply)                              \
3375 _(sr_policy_add_del_reply)                              \
3376 _(sr_multicast_map_add_del_reply)                       \
3377 _(classify_add_del_session_reply)                       \
3378 _(classify_set_interface_ip_table_reply)                \
3379 _(classify_set_interface_l2_tables_reply)               \
3380 _(l2tpv3_set_tunnel_cookies_reply)                      \
3381 _(l2tpv3_interface_enable_disable_reply)                \
3382 _(l2tpv3_set_lookup_key_reply)                          \
3383 _(l2_fib_clear_table_reply)                             \
3384 _(l2_interface_efp_filter_reply)                        \
3385 _(l2_interface_vlan_tag_rewrite_reply)                  \
3386 _(modify_vhost_user_if_reply)                           \
3387 _(delete_vhost_user_if_reply)                           \
3388 _(want_ip4_arp_events_reply)                            \
3389 _(want_ip6_nd_events_reply)                             \
3390 _(input_acl_set_interface_reply)                        \
3391 _(ipsec_spd_add_del_reply)                              \
3392 _(ipsec_interface_add_del_spd_reply)                    \
3393 _(ipsec_spd_add_del_entry_reply)                        \
3394 _(ipsec_sad_add_del_entry_reply)                        \
3395 _(ipsec_sa_set_key_reply)                               \
3396 _(ikev2_profile_add_del_reply)                          \
3397 _(ikev2_profile_set_auth_reply)                         \
3398 _(ikev2_profile_set_id_reply)                           \
3399 _(ikev2_profile_set_ts_reply)                           \
3400 _(ikev2_set_local_key_reply)                            \
3401 _(delete_loopback_reply)                                \
3402 _(bd_ip_mac_add_del_reply)                              \
3403 _(map_del_domain_reply)                                 \
3404 _(map_add_del_rule_reply)                               \
3405 _(want_interface_events_reply)                          \
3406 _(want_stats_reply)                                     \
3407 _(cop_interface_enable_disable_reply)                   \
3408 _(cop_whitelist_enable_disable_reply)                   \
3409 _(sw_interface_clear_stats_reply)                       \
3410 _(trace_profile_add_reply)                              \
3411 _(trace_profile_apply_reply)                            \
3412 _(trace_profile_del_reply)                              \
3413 _(lisp_add_del_locator_reply)                           \
3414 _(lisp_add_del_local_eid_reply)                         \
3415 _(lisp_add_del_remote_mapping_reply)                    \
3416 _(lisp_add_del_adjacency_reply)                         \
3417 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3418 _(lisp_add_del_map_resolver_reply)                      \
3419 _(lisp_gpe_enable_disable_reply)                        \
3420 _(lisp_gpe_add_del_iface_reply)                         \
3421 _(lisp_enable_disable_reply)                            \
3422 _(lisp_pitr_set_locator_set_reply)                      \
3423 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3424 _(lisp_eid_table_add_del_map_reply)                     \
3425 _(vxlan_gpe_add_del_tunnel_reply)                       \
3426 _(af_packet_delete_reply)                               \
3427 _(policer_classify_set_interface_reply)                 \
3428 _(netmap_create_reply)                                  \
3429 _(netmap_delete_reply)                                  \
3430 _(ipfix_enable_reply)                                   \
3431 _(pg_capture_reply)                                     \
3432 _(pg_enable_disable_reply)                              \
3433 _(ip_source_and_port_range_check_add_del_reply)         \
3434 _(ip_source_and_port_range_check_interface_add_del_reply)\
3435 _(delete_subif_reply)
3436
3437 #define _(n)                                    \
3438     static void vl_api_##n##_t_handler          \
3439     (vl_api_##n##_t * mp)                       \
3440     {                                           \
3441         vat_main_t * vam = &vat_main;           \
3442         i32 retval = ntohl(mp->retval);         \
3443         if (vam->async_mode) {                  \
3444             vam->async_errors += (retval < 0);  \
3445         } else {                                \
3446             vam->retval = retval;               \
3447             vam->result_ready = 1;              \
3448         }                                       \
3449     }
3450 foreach_standard_reply_retval_handler;
3451 #undef _
3452
3453 #define _(n)                                    \
3454     static void vl_api_##n##_t_handler_json     \
3455     (vl_api_##n##_t * mp)                       \
3456     {                                           \
3457         vat_main_t * vam = &vat_main;           \
3458         vat_json_node_t node;                   \
3459         vat_json_init_object(&node);            \
3460         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3461         vat_json_print(vam->ofp, &node);        \
3462         vam->retval = ntohl(mp->retval);        \
3463         vam->result_ready = 1;                  \
3464     }
3465 foreach_standard_reply_retval_handler;
3466 #undef _
3467
3468 /*
3469  * Table of message reply handlers, must include boilerplate handlers
3470  * we just generated
3471  */
3472
3473 #define foreach_vpe_api_reply_msg                                       \
3474 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3475 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3476 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3477 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3478 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3479 _(NOPRINT_CONTROL_PING_REPLY, noprint_control_ping_reply)               \
3480 _(CLI_REPLY, cli_reply)                                                 \
3481 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3482 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3483   sw_interface_add_del_address_reply)                                   \
3484 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3485 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3486 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3487   sw_interface_set_l2_xconnect_reply)                                   \
3488 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3489   sw_interface_set_l2_bridge_reply)                                     \
3490 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3491 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3492 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3493 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3494 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3495 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3496 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3497 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3498 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3499 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3500 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3501 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3502 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3503   proxy_arp_intfc_enable_disable_reply)                                 \
3504 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3505 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3506 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3507 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3508   mpls_ethernet_add_del_tunnel_reply)                                   \
3509 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3510   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3511 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3512   sw_interface_set_unnumbered_reply)                                    \
3513 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3514 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3515 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3516 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3517 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3518 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3519 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3520 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3521 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3522 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3523 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3524 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3525   sw_interface_ip6_enable_disable_reply)                                \
3526 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3527   sw_interface_ip6_set_link_local_address_reply)                        \
3528 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3529   sw_interface_ip6nd_ra_prefix_reply)                                   \
3530 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3531   sw_interface_ip6nd_ra_config_reply)                                   \
3532 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3533 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3534 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3535 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3536 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3537 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3538 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3539 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3540 classify_set_interface_ip_table_reply)                                  \
3541 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3542   classify_set_interface_l2_tables_reply)                               \
3543 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3544 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3545 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3546 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3547 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3548   l2tpv3_interface_enable_disable_reply)                                \
3549 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3550 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3551 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3552 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3553 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3554 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3555 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3556 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3557 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3558 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3559 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3560 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3561 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3562 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3563 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3564 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3565 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3566 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3567 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3568 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3569 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3570 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3571 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3572 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3573 _(IP_DETAILS, ip_details)                                               \
3574 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3575 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3576 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3577 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3578 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3579 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3580 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3581 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3582 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3583 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3584 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3585 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3586 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3587 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3588 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3589 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3590 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3591 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3592 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3593 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3594 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3595 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3596 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3597 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3598 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3599 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3600 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3601 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3602 _(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply)                   \
3603 _(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply)               \
3604 _(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply)                     \
3605 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3606 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3607 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3608 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3609 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3610 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3611 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3612 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3613 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3614 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3615 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3616 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3617 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3618 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3619 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3620 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3621 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3622 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3623 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3624 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3625 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3626   lisp_add_del_map_request_itr_rlocs_reply)                             \
3627 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3628   lisp_get_map_request_itr_rlocs_reply)                                 \
3629 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3630 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3631 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3632 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3633 _(POLICER_DETAILS, policer_details)                                     \
3634 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3635 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3636 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3637 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3638 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3639 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3640 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3641 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3642 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3643 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3644 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3645 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3646 _(IPFIX_ENABLE_REPLY, ipfix_enable_reply)                               \
3647 _(IPFIX_DETAILS, ipfix_details)                                         \
3648 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3649 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3650 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3651 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3652 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3653  ip_source_and_port_range_check_add_del_reply)                          \
3654 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3655  ip_source_and_port_range_check_interface_add_del_reply)                \
3656 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3657 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3658 _(DELETE_SUBIF_REPLY, delete_subif_reply)
3659
3660 /* M: construct, but don't yet send a message */
3661
3662 #define M(T,t)                                  \
3663 do {                                            \
3664     vam->result_ready = 0;                      \
3665     mp = vl_msg_api_alloc(sizeof(*mp));         \
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 #define M2(T,t,n)                               \
3672 do {                                            \
3673     vam->result_ready = 0;                      \
3674     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3675     memset (mp, 0, sizeof (*mp));               \
3676     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3677     mp->client_index = vam->my_client_index;    \
3678 } while(0);
3679
3680
3681 /* S: send a message */
3682 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3683
3684 /* W: wait for results, with timeout */
3685 #define W                                       \
3686 do {                                            \
3687     timeout = vat_time_now (vam) + 1.0;         \
3688                                                 \
3689     while (vat_time_now (vam) < timeout) {      \
3690         if (vam->result_ready == 1) {           \
3691             return (vam->retval);               \
3692         }                                       \
3693     }                                           \
3694     return -99;                                 \
3695 } while(0);
3696
3697 /* W2: wait for results, with timeout */
3698 #define W2(body)                                \
3699 do {                                            \
3700     timeout = vat_time_now (vam) + 1.0;         \
3701                                                 \
3702     while (vat_time_now (vam) < timeout) {      \
3703         if (vam->result_ready == 1) {           \
3704           (body);                               \
3705           return (vam->retval);                 \
3706         }                                       \
3707     }                                           \
3708     return -99;                                 \
3709 } while(0);
3710
3711 /* W_L: wait for results, with timeout */
3712 #define W_L(body)                               \
3713 do {                                            \
3714     timeout = vat_time_now (vam) + 1.0;         \
3715                                                 \
3716     while (vat_time_now (vam) < timeout) {      \
3717         if (vam->result_ready == 1) {           \
3718           (body);                               \
3719           return (vam->retval);                 \
3720         }                                       \
3721     }                                           \
3722     vam->noprint_msg = 0;     \
3723     return -99;                                 \
3724 } while(0);
3725
3726 typedef struct
3727 {
3728   u8 *name;
3729   u32 value;
3730 } name_sort_t;
3731
3732
3733 #define STR_VTR_OP_CASE(op)     \
3734     case L2_VTR_ ## op:         \
3735         return "" # op;
3736
3737 static const char *
3738 str_vtr_op (u32 vtr_op)
3739 {
3740   switch (vtr_op)
3741     {
3742       STR_VTR_OP_CASE (DISABLED);
3743       STR_VTR_OP_CASE (PUSH_1);
3744       STR_VTR_OP_CASE (PUSH_2);
3745       STR_VTR_OP_CASE (POP_1);
3746       STR_VTR_OP_CASE (POP_2);
3747       STR_VTR_OP_CASE (TRANSLATE_1_1);
3748       STR_VTR_OP_CASE (TRANSLATE_1_2);
3749       STR_VTR_OP_CASE (TRANSLATE_2_1);
3750       STR_VTR_OP_CASE (TRANSLATE_2_2);
3751     }
3752
3753   return "UNKNOWN";
3754 }
3755
3756 static int
3757 dump_sub_interface_table (vat_main_t * vam)
3758 {
3759   const sw_interface_subif_t *sub = NULL;
3760
3761   if (vam->json_output)
3762     {
3763       clib_warning
3764         ("JSON output supported only for VPE API calls and dump_stats_table");
3765       return -99;
3766     }
3767
3768   fformat (vam->ofp,
3769            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3770            "Interface", "sw_if_index",
3771            "sub id", "dot1ad", "tags", "outer id",
3772            "inner id", "exact", "default", "outer any", "inner any");
3773
3774   vec_foreach (sub, vam->sw_if_subif_table)
3775   {
3776     fformat (vam->ofp,
3777              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3778              sub->interface_name,
3779              sub->sw_if_index,
3780              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3781              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3782              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3783              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3784     if (sub->vtr_op != L2_VTR_DISABLED)
3785       {
3786         fformat (vam->ofp,
3787                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3788                  "tag1: %d tag2: %d ]\n",
3789                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3790                  sub->vtr_tag1, sub->vtr_tag2);
3791       }
3792   }
3793
3794   return 0;
3795 }
3796
3797 static int
3798 name_sort_cmp (void *a1, void *a2)
3799 {
3800   name_sort_t *n1 = a1;
3801   name_sort_t *n2 = a2;
3802
3803   return strcmp ((char *) n1->name, (char *) n2->name);
3804 }
3805
3806 static int
3807 dump_interface_table (vat_main_t * vam)
3808 {
3809   hash_pair_t *p;
3810   name_sort_t *nses = 0, *ns;
3811
3812   if (vam->json_output)
3813     {
3814       clib_warning
3815         ("JSON output supported only for VPE API calls and dump_stats_table");
3816       return -99;
3817     }
3818
3819   /* *INDENT-OFF* */
3820   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3821   ({
3822     vec_add2 (nses, ns, 1);
3823     ns->name = (u8 *)(p->key);
3824     ns->value = (u32) p->value[0];
3825   }));
3826   /* *INDENT-ON* */
3827
3828   vec_sort_with_function (nses, name_sort_cmp);
3829
3830   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3831   vec_foreach (ns, nses)
3832   {
3833     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3834   }
3835   vec_free (nses);
3836   return 0;
3837 }
3838
3839 static int
3840 dump_ip_table (vat_main_t * vam, int is_ipv6)
3841 {
3842   const ip_details_t *det = NULL;
3843   const ip_address_details_t *address = NULL;
3844   u32 i = ~0;
3845
3846   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3847
3848   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3849   {
3850     i++;
3851     if (!det->present)
3852       {
3853         continue;
3854       }
3855     fformat (vam->ofp, "%-12d\n", i);
3856     fformat (vam->ofp,
3857              "            %-30s%-13s\n", "Address", "Prefix length");
3858     if (!det->addr)
3859       {
3860         continue;
3861       }
3862     vec_foreach (address, det->addr)
3863     {
3864       fformat (vam->ofp,
3865                "            %-30U%-13d\n",
3866                is_ipv6 ? format_ip6_address : format_ip4_address,
3867                address->ip, address->prefix_length);
3868     }
3869   }
3870
3871   return 0;
3872 }
3873
3874 static int
3875 dump_ipv4_table (vat_main_t * vam)
3876 {
3877   if (vam->json_output)
3878     {
3879       clib_warning
3880         ("JSON output supported only for VPE API calls and dump_stats_table");
3881       return -99;
3882     }
3883
3884   return dump_ip_table (vam, 0);
3885 }
3886
3887 static int
3888 dump_ipv6_table (vat_main_t * vam)
3889 {
3890   if (vam->json_output)
3891     {
3892       clib_warning
3893         ("JSON output supported only for VPE API calls and dump_stats_table");
3894       return -99;
3895     }
3896
3897   return dump_ip_table (vam, 1);
3898 }
3899
3900 static char *
3901 counter_type_to_str (u8 counter_type, u8 is_combined)
3902 {
3903   if (!is_combined)
3904     {
3905       switch (counter_type)
3906         {
3907         case VNET_INTERFACE_COUNTER_DROP:
3908           return "drop";
3909         case VNET_INTERFACE_COUNTER_PUNT:
3910           return "punt";
3911         case VNET_INTERFACE_COUNTER_IP4:
3912           return "ip4";
3913         case VNET_INTERFACE_COUNTER_IP6:
3914           return "ip6";
3915         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3916           return "rx-no-buf";
3917         case VNET_INTERFACE_COUNTER_RX_MISS:
3918           return "rx-miss";
3919         case VNET_INTERFACE_COUNTER_RX_ERROR:
3920           return "rx-error";
3921         case VNET_INTERFACE_COUNTER_TX_ERROR:
3922           return "tx-error";
3923         default:
3924           return "INVALID-COUNTER-TYPE";
3925         }
3926     }
3927   else
3928     {
3929       switch (counter_type)
3930         {
3931         case VNET_INTERFACE_COUNTER_RX:
3932           return "rx";
3933         case VNET_INTERFACE_COUNTER_TX:
3934           return "tx";
3935         default:
3936           return "INVALID-COUNTER-TYPE";
3937         }
3938     }
3939 }
3940
3941 static int
3942 dump_stats_table (vat_main_t * vam)
3943 {
3944   vat_json_node_t node;
3945   vat_json_node_t *msg_array;
3946   vat_json_node_t *msg;
3947   vat_json_node_t *counter_array;
3948   vat_json_node_t *counter;
3949   interface_counter_t c;
3950   u64 packets;
3951   ip4_fib_counter_t *c4;
3952   ip6_fib_counter_t *c6;
3953   int i, j;
3954
3955   if (!vam->json_output)
3956     {
3957       clib_warning ("dump_stats_table supported only in JSON format");
3958       return -99;
3959     }
3960
3961   vat_json_init_object (&node);
3962
3963   /* interface counters */
3964   msg_array = vat_json_object_add (&node, "interface_counters");
3965   vat_json_init_array (msg_array);
3966   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
3967     {
3968       msg = vat_json_array_add (msg_array);
3969       vat_json_init_object (msg);
3970       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3971                                        (u8 *) counter_type_to_str (i, 0));
3972       vat_json_object_add_int (msg, "is_combined", 0);
3973       counter_array = vat_json_object_add (msg, "data");
3974       vat_json_init_array (counter_array);
3975       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
3976         {
3977           packets = vam->simple_interface_counters[i][j];
3978           vat_json_array_add_uint (counter_array, packets);
3979         }
3980     }
3981   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
3982     {
3983       msg = vat_json_array_add (msg_array);
3984       vat_json_init_object (msg);
3985       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3986                                        (u8 *) counter_type_to_str (i, 1));
3987       vat_json_object_add_int (msg, "is_combined", 1);
3988       counter_array = vat_json_object_add (msg, "data");
3989       vat_json_init_array (counter_array);
3990       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
3991         {
3992           c = vam->combined_interface_counters[i][j];
3993           counter = vat_json_array_add (counter_array);
3994           vat_json_init_object (counter);
3995           vat_json_object_add_uint (counter, "packets", c.packets);
3996           vat_json_object_add_uint (counter, "bytes", c.bytes);
3997         }
3998     }
3999
4000   /* ip4 fib counters */
4001   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4002   vat_json_init_array (msg_array);
4003   for (i = 0; i < vec_len (vam->ip4_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->ip4_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->ip4_fib_counters[i]); j++)
4012         {
4013           counter = vat_json_array_add (counter_array);
4014           vat_json_init_object (counter);
4015           c4 = &vam->ip4_fib_counters[i][j];
4016           vat_json_object_add_ip4 (counter, "address", c4->address);
4017           vat_json_object_add_uint (counter, "address_length",
4018                                     c4->address_length);
4019           vat_json_object_add_uint (counter, "packets", c4->packets);
4020           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4021         }
4022     }
4023
4024   /* ip6 fib counters */
4025   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4026   vat_json_init_array (msg_array);
4027   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4028     {
4029       msg = vat_json_array_add (msg_array);
4030       vat_json_init_object (msg);
4031       vat_json_object_add_uint (msg, "vrf_id",
4032                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4033       counter_array = vat_json_object_add (msg, "c");
4034       vat_json_init_array (counter_array);
4035       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4036         {
4037           counter = vat_json_array_add (counter_array);
4038           vat_json_init_object (counter);
4039           c6 = &vam->ip6_fib_counters[i][j];
4040           vat_json_object_add_ip6 (counter, "address", c6->address);
4041           vat_json_object_add_uint (counter, "address_length",
4042                                     c6->address_length);
4043           vat_json_object_add_uint (counter, "packets", c6->packets);
4044           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4045         }
4046     }
4047
4048   vat_json_print (vam->ofp, &node);
4049   vat_json_free (&node);
4050
4051   return 0;
4052 }
4053
4054 int
4055 exec (vat_main_t * vam)
4056 {
4057   api_main_t *am = &api_main;
4058   vl_api_cli_request_t *mp;
4059   f64 timeout;
4060   void *oldheap;
4061   u8 *cmd = 0;
4062   unformat_input_t *i = vam->input;
4063
4064   if (vec_len (i->buffer) == 0)
4065     return -1;
4066
4067   if (vam->exec_mode == 0 && unformat (i, "mode"))
4068     {
4069       vam->exec_mode = 1;
4070       return 0;
4071     }
4072   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4073     {
4074       vam->exec_mode = 0;
4075       return 0;
4076     }
4077
4078
4079   M (CLI_REQUEST, cli_request);
4080
4081   /*
4082    * Copy cmd into shared memory.
4083    * In order for the CLI command to work, it
4084    * must be a vector ending in \n, not a C-string ending
4085    * in \n\0.
4086    */
4087   pthread_mutex_lock (&am->vlib_rp->mutex);
4088   oldheap = svm_push_data_heap (am->vlib_rp);
4089
4090   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4091   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4092
4093   svm_pop_heap (oldheap);
4094   pthread_mutex_unlock (&am->vlib_rp->mutex);
4095
4096   mp->cmd_in_shmem = (u64) cmd;
4097   S;
4098   timeout = vat_time_now (vam) + 10.0;
4099
4100   while (vat_time_now (vam) < timeout)
4101     {
4102       if (vam->result_ready == 1)
4103         {
4104           u8 *free_me;
4105           if (vam->shmem_result != NULL)
4106             fformat (vam->ofp, "%s", vam->shmem_result);
4107           pthread_mutex_lock (&am->vlib_rp->mutex);
4108           oldheap = svm_push_data_heap (am->vlib_rp);
4109
4110           free_me = (u8 *) vam->shmem_result;
4111           vec_free (free_me);
4112
4113           svm_pop_heap (oldheap);
4114           pthread_mutex_unlock (&am->vlib_rp->mutex);
4115           return 0;
4116         }
4117     }
4118   return -99;
4119 }
4120
4121 /*
4122  * Future replacement of exec() that passes CLI buffers directly in
4123  * the API messages instead of an additional shared memory area.
4124  */
4125 static int
4126 exec_inband (vat_main_t * vam)
4127 {
4128   vl_api_cli_inband_t *mp;
4129   f64 timeout;
4130   unformat_input_t *i = vam->input;
4131
4132   if (vec_len (i->buffer) == 0)
4133     return -1;
4134
4135   if (vam->exec_mode == 0 && unformat (i, "mode"))
4136     {
4137       vam->exec_mode = 1;
4138       return 0;
4139     }
4140   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4141     {
4142       vam->exec_mode = 0;
4143       return 0;
4144     }
4145
4146   /*
4147    * In order for the CLI command to work, it
4148    * must be a vector ending in \n, not a C-string ending
4149    * in \n\0.
4150    */
4151   u32 len = vec_len (vam->input->buffer);
4152   M2 (CLI_INBAND, cli_inband, len);
4153   clib_memcpy (mp->cmd, vam->input->buffer, len);
4154   mp->length = htonl (len);
4155
4156   S;
4157   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4158 }
4159
4160 static int
4161 api_create_loopback (vat_main_t * vam)
4162 {
4163   unformat_input_t *i = vam->input;
4164   vl_api_create_loopback_t *mp;
4165   f64 timeout;
4166   u8 mac_address[6];
4167   u8 mac_set = 0;
4168
4169   memset (mac_address, 0, sizeof (mac_address));
4170
4171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4172     {
4173       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4174         mac_set = 1;
4175       else
4176         break;
4177     }
4178
4179   /* Construct the API message */
4180   M (CREATE_LOOPBACK, create_loopback);
4181   if (mac_set)
4182     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4183
4184   S;
4185   W;
4186 }
4187
4188 static int
4189 api_delete_loopback (vat_main_t * vam)
4190 {
4191   unformat_input_t *i = vam->input;
4192   vl_api_delete_loopback_t *mp;
4193   f64 timeout;
4194   u32 sw_if_index = ~0;
4195
4196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4197     {
4198       if (unformat (i, "sw_if_index %d", &sw_if_index))
4199         ;
4200       else
4201         break;
4202     }
4203
4204   if (sw_if_index == ~0)
4205     {
4206       errmsg ("missing sw_if_index\n");
4207       return -99;
4208     }
4209
4210   /* Construct the API message */
4211   M (DELETE_LOOPBACK, delete_loopback);
4212   mp->sw_if_index = ntohl (sw_if_index);
4213
4214   S;
4215   W;
4216 }
4217
4218 static int
4219 api_want_stats (vat_main_t * vam)
4220 {
4221   unformat_input_t *i = vam->input;
4222   vl_api_want_stats_t *mp;
4223   f64 timeout;
4224   int enable = -1;
4225
4226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4227     {
4228       if (unformat (i, "enable"))
4229         enable = 1;
4230       else if (unformat (i, "disable"))
4231         enable = 0;
4232       else
4233         break;
4234     }
4235
4236   if (enable == -1)
4237     {
4238       errmsg ("missing enable|disable\n");
4239       return -99;
4240     }
4241
4242   M (WANT_STATS, want_stats);
4243   mp->enable_disable = enable;
4244
4245   S;
4246   W;
4247 }
4248
4249 static int
4250 api_want_interface_events (vat_main_t * vam)
4251 {
4252   unformat_input_t *i = vam->input;
4253   vl_api_want_interface_events_t *mp;
4254   f64 timeout;
4255   int enable = -1;
4256
4257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4258     {
4259       if (unformat (i, "enable"))
4260         enable = 1;
4261       else if (unformat (i, "disable"))
4262         enable = 0;
4263       else
4264         break;
4265     }
4266
4267   if (enable == -1)
4268     {
4269       errmsg ("missing enable|disable\n");
4270       return -99;
4271     }
4272
4273   M (WANT_INTERFACE_EVENTS, want_interface_events);
4274   mp->enable_disable = enable;
4275
4276   vam->interface_event_display = enable;
4277
4278   S;
4279   W;
4280 }
4281
4282
4283 /* Note: non-static, called once to set up the initial intfc table */
4284 int
4285 api_sw_interface_dump (vat_main_t * vam)
4286 {
4287   vl_api_sw_interface_dump_t *mp;
4288   f64 timeout;
4289   hash_pair_t *p;
4290   name_sort_t *nses = 0, *ns;
4291   sw_interface_subif_t *sub = NULL;
4292
4293   /* Toss the old name table */
4294   /* *INDENT-OFF* */
4295   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4296   ({
4297     vec_add2 (nses, ns, 1);
4298     ns->name = (u8 *)(p->key);
4299     ns->value = (u32) p->value[0];
4300   }));
4301   /* *INDENT-ON* */
4302
4303   hash_free (vam->sw_if_index_by_interface_name);
4304
4305   vec_foreach (ns, nses) vec_free (ns->name);
4306
4307   vec_free (nses);
4308
4309   vec_foreach (sub, vam->sw_if_subif_table)
4310   {
4311     vec_free (sub->interface_name);
4312   }
4313   vec_free (vam->sw_if_subif_table);
4314
4315   /* recreate the interface name hash table */
4316   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4317
4318   /* Get list of ethernets */
4319   M (SW_INTERFACE_DUMP, sw_interface_dump);
4320   mp->name_filter_valid = 1;
4321   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4322   S;
4323
4324   /* and local / loopback interfaces */
4325   M (SW_INTERFACE_DUMP, sw_interface_dump);
4326   mp->name_filter_valid = 1;
4327   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4328   S;
4329
4330
4331   /* and vxlan-gpe tunnel interfaces */
4332   M (SW_INTERFACE_DUMP, sw_interface_dump);
4333   mp->name_filter_valid = 1;
4334   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4335            sizeof (mp->name_filter) - 1);
4336   S;
4337
4338   /* and vxlan tunnel interfaces */
4339   M (SW_INTERFACE_DUMP, sw_interface_dump);
4340   mp->name_filter_valid = 1;
4341   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4342   S;
4343
4344   /* and host (af_packet) interfaces */
4345   M (SW_INTERFACE_DUMP, sw_interface_dump);
4346   mp->name_filter_valid = 1;
4347   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4348   S;
4349
4350   /* and l2tpv3 tunnel interfaces */
4351   M (SW_INTERFACE_DUMP, sw_interface_dump);
4352   mp->name_filter_valid = 1;
4353   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4354            sizeof (mp->name_filter) - 1);
4355   S;
4356
4357   /* and GRE tunnel interfaces */
4358   M (SW_INTERFACE_DUMP, sw_interface_dump);
4359   mp->name_filter_valid = 1;
4360   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4361   S;
4362
4363   /* Use a control ping for synchronization */
4364   {
4365     vl_api_control_ping_t *mp;
4366     M (CONTROL_PING, control_ping);
4367     S;
4368   }
4369   W;
4370 }
4371
4372 static int
4373 api_sw_interface_set_flags (vat_main_t * vam)
4374 {
4375   unformat_input_t *i = vam->input;
4376   vl_api_sw_interface_set_flags_t *mp;
4377   f64 timeout;
4378   u32 sw_if_index;
4379   u8 sw_if_index_set = 0;
4380   u8 admin_up = 0, link_up = 0;
4381
4382   /* Parse args required to build the message */
4383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4384     {
4385       if (unformat (i, "admin-up"))
4386         admin_up = 1;
4387       else if (unformat (i, "admin-down"))
4388         admin_up = 0;
4389       else if (unformat (i, "link-up"))
4390         link_up = 1;
4391       else if (unformat (i, "link-down"))
4392         link_up = 0;
4393       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4394         sw_if_index_set = 1;
4395       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4396         sw_if_index_set = 1;
4397       else
4398         break;
4399     }
4400
4401   if (sw_if_index_set == 0)
4402     {
4403       errmsg ("missing interface name or sw_if_index\n");
4404       return -99;
4405     }
4406
4407   /* Construct the API message */
4408   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4409   mp->sw_if_index = ntohl (sw_if_index);
4410   mp->admin_up_down = admin_up;
4411   mp->link_up_down = link_up;
4412
4413   /* send it... */
4414   S;
4415
4416   /* Wait for a reply, return the good/bad news... */
4417   W;
4418 }
4419
4420 static int
4421 api_sw_interface_clear_stats (vat_main_t * vam)
4422 {
4423   unformat_input_t *i = vam->input;
4424   vl_api_sw_interface_clear_stats_t *mp;
4425   f64 timeout;
4426   u32 sw_if_index;
4427   u8 sw_if_index_set = 0;
4428
4429   /* Parse args required to build the message */
4430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4431     {
4432       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4433         sw_if_index_set = 1;
4434       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4435         sw_if_index_set = 1;
4436       else
4437         break;
4438     }
4439
4440   /* Construct the API message */
4441   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4442
4443   if (sw_if_index_set == 1)
4444     mp->sw_if_index = ntohl (sw_if_index);
4445   else
4446     mp->sw_if_index = ~0;
4447
4448   /* send it... */
4449   S;
4450
4451   /* Wait for a reply, return the good/bad news... */
4452   W;
4453 }
4454
4455 static int
4456 api_sw_interface_add_del_address (vat_main_t * vam)
4457 {
4458   unformat_input_t *i = vam->input;
4459   vl_api_sw_interface_add_del_address_t *mp;
4460   f64 timeout;
4461   u32 sw_if_index;
4462   u8 sw_if_index_set = 0;
4463   u8 is_add = 1, del_all = 0;
4464   u32 address_length = 0;
4465   u8 v4_address_set = 0;
4466   u8 v6_address_set = 0;
4467   ip4_address_t v4address;
4468   ip6_address_t v6address;
4469
4470   /* Parse args required to build the message */
4471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4472     {
4473       if (unformat (i, "del-all"))
4474         del_all = 1;
4475       else if (unformat (i, "del"))
4476         is_add = 0;
4477       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4478         sw_if_index_set = 1;
4479       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4480         sw_if_index_set = 1;
4481       else if (unformat (i, "%U/%d",
4482                          unformat_ip4_address, &v4address, &address_length))
4483         v4_address_set = 1;
4484       else if (unformat (i, "%U/%d",
4485                          unformat_ip6_address, &v6address, &address_length))
4486         v6_address_set = 1;
4487       else
4488         break;
4489     }
4490
4491   if (sw_if_index_set == 0)
4492     {
4493       errmsg ("missing interface name or sw_if_index\n");
4494       return -99;
4495     }
4496   if (v4_address_set && v6_address_set)
4497     {
4498       errmsg ("both v4 and v6 addresses set\n");
4499       return -99;
4500     }
4501   if (!v4_address_set && !v6_address_set && !del_all)
4502     {
4503       errmsg ("no addresses set\n");
4504       return -99;
4505     }
4506
4507   /* Construct the API message */
4508   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4509
4510   mp->sw_if_index = ntohl (sw_if_index);
4511   mp->is_add = is_add;
4512   mp->del_all = del_all;
4513   if (v6_address_set)
4514     {
4515       mp->is_ipv6 = 1;
4516       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4517     }
4518   else
4519     {
4520       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4521     }
4522   mp->address_length = address_length;
4523
4524   /* send it... */
4525   S;
4526
4527   /* Wait for a reply, return good/bad news  */
4528   W;
4529 }
4530
4531 static int
4532 api_sw_interface_set_table (vat_main_t * vam)
4533 {
4534   unformat_input_t *i = vam->input;
4535   vl_api_sw_interface_set_table_t *mp;
4536   f64 timeout;
4537   u32 sw_if_index, vrf_id = 0;
4538   u8 sw_if_index_set = 0;
4539   u8 is_ipv6 = 0;
4540
4541   /* Parse args required to build the message */
4542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4543     {
4544       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4545         sw_if_index_set = 1;
4546       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4547         sw_if_index_set = 1;
4548       else if (unformat (i, "vrf %d", &vrf_id))
4549         ;
4550       else if (unformat (i, "ipv6"))
4551         is_ipv6 = 1;
4552       else
4553         break;
4554     }
4555
4556   if (sw_if_index_set == 0)
4557     {
4558       errmsg ("missing interface name or sw_if_index\n");
4559       return -99;
4560     }
4561
4562   /* Construct the API message */
4563   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4564
4565   mp->sw_if_index = ntohl (sw_if_index);
4566   mp->is_ipv6 = is_ipv6;
4567   mp->vrf_id = ntohl (vrf_id);
4568
4569   /* send it... */
4570   S;
4571
4572   /* Wait for a reply... */
4573   W;
4574 }
4575
4576 static int
4577 api_sw_interface_set_vpath (vat_main_t * vam)
4578 {
4579   unformat_input_t *i = vam->input;
4580   vl_api_sw_interface_set_vpath_t *mp;
4581   f64 timeout;
4582   u32 sw_if_index = 0;
4583   u8 sw_if_index_set = 0;
4584   u8 is_enable = 0;
4585
4586   /* Parse args required to build the message */
4587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4588     {
4589       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4590         sw_if_index_set = 1;
4591       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4592         sw_if_index_set = 1;
4593       else if (unformat (i, "enable"))
4594         is_enable = 1;
4595       else if (unformat (i, "disable"))
4596         is_enable = 0;
4597       else
4598         break;
4599     }
4600
4601   if (sw_if_index_set == 0)
4602     {
4603       errmsg ("missing interface name or sw_if_index\n");
4604       return -99;
4605     }
4606
4607   /* Construct the API message */
4608   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4609
4610   mp->sw_if_index = ntohl (sw_if_index);
4611   mp->enable = is_enable;
4612
4613   /* send it... */
4614   S;
4615
4616   /* Wait for a reply... */
4617   W;
4618 }
4619
4620 static int
4621 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4622 {
4623   unformat_input_t *i = vam->input;
4624   vl_api_sw_interface_set_l2_xconnect_t *mp;
4625   f64 timeout;
4626   u32 rx_sw_if_index;
4627   u8 rx_sw_if_index_set = 0;
4628   u32 tx_sw_if_index;
4629   u8 tx_sw_if_index_set = 0;
4630   u8 enable = 1;
4631
4632   /* Parse args required to build the message */
4633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4634     {
4635       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4636         rx_sw_if_index_set = 1;
4637       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4638         tx_sw_if_index_set = 1;
4639       else if (unformat (i, "rx"))
4640         {
4641           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4642             {
4643               if (unformat (i, "%U", unformat_sw_if_index, vam,
4644                             &rx_sw_if_index))
4645                 rx_sw_if_index_set = 1;
4646             }
4647           else
4648             break;
4649         }
4650       else if (unformat (i, "tx"))
4651         {
4652           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4653             {
4654               if (unformat (i, "%U", unformat_sw_if_index, vam,
4655                             &tx_sw_if_index))
4656                 tx_sw_if_index_set = 1;
4657             }
4658           else
4659             break;
4660         }
4661       else if (unformat (i, "enable"))
4662         enable = 1;
4663       else if (unformat (i, "disable"))
4664         enable = 0;
4665       else
4666         break;
4667     }
4668
4669   if (rx_sw_if_index_set == 0)
4670     {
4671       errmsg ("missing rx interface name or rx_sw_if_index\n");
4672       return -99;
4673     }
4674
4675   if (enable && (tx_sw_if_index_set == 0))
4676     {
4677       errmsg ("missing tx interface name or tx_sw_if_index\n");
4678       return -99;
4679     }
4680
4681   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4682
4683   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4684   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4685   mp->enable = enable;
4686
4687   S;
4688   W;
4689   /* NOTREACHED */
4690   return 0;
4691 }
4692
4693 static int
4694 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4695 {
4696   unformat_input_t *i = vam->input;
4697   vl_api_sw_interface_set_l2_bridge_t *mp;
4698   f64 timeout;
4699   u32 rx_sw_if_index;
4700   u8 rx_sw_if_index_set = 0;
4701   u32 bd_id;
4702   u8 bd_id_set = 0;
4703   u8 bvi = 0;
4704   u32 shg = 0;
4705   u8 enable = 1;
4706
4707   /* Parse args required to build the message */
4708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4709     {
4710       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4711         rx_sw_if_index_set = 1;
4712       else if (unformat (i, "bd_id %d", &bd_id))
4713         bd_id_set = 1;
4714       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
4715         rx_sw_if_index_set = 1;
4716       else if (unformat (i, "shg %d", &shg))
4717         ;
4718       else if (unformat (i, "bvi"))
4719         bvi = 1;
4720       else if (unformat (i, "enable"))
4721         enable = 1;
4722       else if (unformat (i, "disable"))
4723         enable = 0;
4724       else
4725         break;
4726     }
4727
4728   if (rx_sw_if_index_set == 0)
4729     {
4730       errmsg ("missing rx interface name or sw_if_index\n");
4731       return -99;
4732     }
4733
4734   if (enable && (bd_id_set == 0))
4735     {
4736       errmsg ("missing bridge domain\n");
4737       return -99;
4738     }
4739
4740   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
4741
4742   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4743   mp->bd_id = ntohl (bd_id);
4744   mp->shg = (u8) shg;
4745   mp->bvi = bvi;
4746   mp->enable = enable;
4747
4748   S;
4749   W;
4750   /* NOTREACHED */
4751   return 0;
4752 }
4753
4754 static int
4755 api_bridge_domain_dump (vat_main_t * vam)
4756 {
4757   unformat_input_t *i = vam->input;
4758   vl_api_bridge_domain_dump_t *mp;
4759   f64 timeout;
4760   u32 bd_id = ~0;
4761
4762   /* Parse args required to build the message */
4763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4764     {
4765       if (unformat (i, "bd_id %d", &bd_id))
4766         ;
4767       else
4768         break;
4769     }
4770
4771   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
4772   mp->bd_id = ntohl (bd_id);
4773   S;
4774
4775   /* Use a control ping for synchronization */
4776   {
4777     vl_api_control_ping_t *mp;
4778     M (CONTROL_PING, control_ping);
4779     S;
4780   }
4781
4782   W;
4783   /* NOTREACHED */
4784   return 0;
4785 }
4786
4787 static int
4788 api_bridge_domain_add_del (vat_main_t * vam)
4789 {
4790   unformat_input_t *i = vam->input;
4791   vl_api_bridge_domain_add_del_t *mp;
4792   f64 timeout;
4793   u32 bd_id = ~0;
4794   u8 is_add = 1;
4795   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4796
4797   /* Parse args required to build the message */
4798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4799     {
4800       if (unformat (i, "bd_id %d", &bd_id))
4801         ;
4802       else if (unformat (i, "flood %d", &flood))
4803         ;
4804       else if (unformat (i, "uu-flood %d", &uu_flood))
4805         ;
4806       else if (unformat (i, "forward %d", &forward))
4807         ;
4808       else if (unformat (i, "learn %d", &learn))
4809         ;
4810       else if (unformat (i, "arp-term %d", &arp_term))
4811         ;
4812       else if (unformat (i, "del"))
4813         {
4814           is_add = 0;
4815           flood = uu_flood = forward = learn = 0;
4816         }
4817       else
4818         break;
4819     }
4820
4821   if (bd_id == ~0)
4822     {
4823       errmsg ("missing bridge domain\n");
4824       return -99;
4825     }
4826
4827   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
4828
4829   mp->bd_id = ntohl (bd_id);
4830   mp->flood = flood;
4831   mp->uu_flood = uu_flood;
4832   mp->forward = forward;
4833   mp->learn = learn;
4834   mp->arp_term = arp_term;
4835   mp->is_add = is_add;
4836
4837   S;
4838   W;
4839   /* NOTREACHED */
4840   return 0;
4841 }
4842
4843 static int
4844 api_l2fib_add_del (vat_main_t * vam)
4845 {
4846   unformat_input_t *i = vam->input;
4847   vl_api_l2fib_add_del_t *mp;
4848   f64 timeout;
4849   u64 mac = 0;
4850   u8 mac_set = 0;
4851   u32 bd_id;
4852   u8 bd_id_set = 0;
4853   u32 sw_if_index;
4854   u8 sw_if_index_set = 0;
4855   u8 is_add = 1;
4856   u8 static_mac = 0;
4857   u8 filter_mac = 0;
4858   u8 bvi_mac = 0;
4859   int count = 1;
4860   f64 before = 0;
4861   int j;
4862
4863   /* Parse args required to build the message */
4864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4865     {
4866       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
4867         mac_set = 1;
4868       else if (unformat (i, "bd_id %d", &bd_id))
4869         bd_id_set = 1;
4870       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4871         sw_if_index_set = 1;
4872       else if (unformat (i, "sw_if"))
4873         {
4874           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4875             {
4876               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4877                 sw_if_index_set = 1;
4878             }
4879           else
4880             break;
4881         }
4882       else if (unformat (i, "static"))
4883         static_mac = 1;
4884       else if (unformat (i, "filter"))
4885         {
4886           filter_mac = 1;
4887           static_mac = 1;
4888         }
4889       else if (unformat (i, "bvi"))
4890         {
4891           bvi_mac = 1;
4892           static_mac = 1;
4893         }
4894       else if (unformat (i, "del"))
4895         is_add = 0;
4896       else if (unformat (i, "count %d", &count))
4897         ;
4898       else
4899         break;
4900     }
4901
4902   if (mac_set == 0)
4903     {
4904       errmsg ("missing mac address\n");
4905       return -99;
4906     }
4907
4908   if (bd_id_set == 0)
4909     {
4910       errmsg ("missing bridge domain\n");
4911       return -99;
4912     }
4913
4914   if (is_add && (sw_if_index_set == 0))
4915     {
4916       errmsg ("missing interface name or sw_if_index\n");
4917       return -99;
4918     }
4919
4920   if (count > 1)
4921     {
4922       /* Turn on async mode */
4923       vam->async_mode = 1;
4924       vam->async_errors = 0;
4925       before = vat_time_now (vam);
4926     }
4927
4928   for (j = 0; j < count; j++)
4929     {
4930       M (L2FIB_ADD_DEL, l2fib_add_del);
4931
4932       mp->mac = mac;
4933       mp->bd_id = ntohl (bd_id);
4934       mp->is_add = is_add;
4935
4936       if (is_add)
4937         {
4938           mp->sw_if_index = ntohl (sw_if_index);
4939           mp->static_mac = static_mac;
4940           mp->filter_mac = filter_mac;
4941           mp->bvi_mac = bvi_mac;
4942         }
4943       increment_mac_address (&mac);
4944       /* send it... */
4945       S;
4946     }
4947
4948   if (count > 1)
4949     {
4950       vl_api_control_ping_t *mp;
4951       f64 after;
4952
4953       /* Shut off async mode */
4954       vam->async_mode = 0;
4955
4956       M (CONTROL_PING, control_ping);
4957       S;
4958
4959       timeout = vat_time_now (vam) + 1.0;
4960       while (vat_time_now (vam) < timeout)
4961         if (vam->result_ready == 1)
4962           goto out;
4963       vam->retval = -99;
4964
4965     out:
4966       if (vam->retval == -99)
4967         errmsg ("timeout\n");
4968
4969       if (vam->async_errors > 0)
4970         {
4971           errmsg ("%d asynchronous errors\n", vam->async_errors);
4972           vam->retval = -98;
4973         }
4974       vam->async_errors = 0;
4975       after = vat_time_now (vam);
4976
4977       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4978                count, after - before, count / (after - before));
4979     }
4980   else
4981     {
4982       /* Wait for a reply... */
4983       W;
4984     }
4985   /* Return the good/bad news */
4986   return (vam->retval);
4987 }
4988
4989 static int
4990 api_l2_flags (vat_main_t * vam)
4991 {
4992   unformat_input_t *i = vam->input;
4993   vl_api_l2_flags_t *mp;
4994   f64 timeout;
4995   u32 sw_if_index;
4996   u32 feature_bitmap = 0;
4997   u8 sw_if_index_set = 0;
4998
4999   /* Parse args required to build the message */
5000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5001     {
5002       if (unformat (i, "sw_if_index %d", &sw_if_index))
5003         sw_if_index_set = 1;
5004       else if (unformat (i, "sw_if"))
5005         {
5006           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5007             {
5008               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5009                 sw_if_index_set = 1;
5010             }
5011           else
5012             break;
5013         }
5014       else if (unformat (i, "learn"))
5015         feature_bitmap |= L2INPUT_FEAT_LEARN;
5016       else if (unformat (i, "forward"))
5017         feature_bitmap |= L2INPUT_FEAT_FWD;
5018       else if (unformat (i, "flood"))
5019         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5020       else if (unformat (i, "uu-flood"))
5021         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5022       else
5023         break;
5024     }
5025
5026   if (sw_if_index_set == 0)
5027     {
5028       errmsg ("missing interface name or sw_if_index\n");
5029       return -99;
5030     }
5031
5032   M (L2_FLAGS, l2_flags);
5033
5034   mp->sw_if_index = ntohl (sw_if_index);
5035   mp->feature_bitmap = ntohl (feature_bitmap);
5036
5037   S;
5038   W;
5039   /* NOTREACHED */
5040   return 0;
5041 }
5042
5043 static int
5044 api_bridge_flags (vat_main_t * vam)
5045 {
5046   unformat_input_t *i = vam->input;
5047   vl_api_bridge_flags_t *mp;
5048   f64 timeout;
5049   u32 bd_id;
5050   u8 bd_id_set = 0;
5051   u8 is_set = 1;
5052   u32 flags = 0;
5053
5054   /* Parse args required to build the message */
5055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5056     {
5057       if (unformat (i, "bd_id %d", &bd_id))
5058         bd_id_set = 1;
5059       else if (unformat (i, "learn"))
5060         flags |= L2_LEARN;
5061       else if (unformat (i, "forward"))
5062         flags |= L2_FWD;
5063       else if (unformat (i, "flood"))
5064         flags |= L2_FLOOD;
5065       else if (unformat (i, "uu-flood"))
5066         flags |= L2_UU_FLOOD;
5067       else if (unformat (i, "arp-term"))
5068         flags |= L2_ARP_TERM;
5069       else if (unformat (i, "off"))
5070         is_set = 0;
5071       else if (unformat (i, "disable"))
5072         is_set = 0;
5073       else
5074         break;
5075     }
5076
5077   if (bd_id_set == 0)
5078     {
5079       errmsg ("missing bridge domain\n");
5080       return -99;
5081     }
5082
5083   M (BRIDGE_FLAGS, bridge_flags);
5084
5085   mp->bd_id = ntohl (bd_id);
5086   mp->feature_bitmap = ntohl (flags);
5087   mp->is_set = is_set;
5088
5089   S;
5090   W;
5091   /* NOTREACHED */
5092   return 0;
5093 }
5094
5095 static int
5096 api_bd_ip_mac_add_del (vat_main_t * vam)
5097 {
5098   unformat_input_t *i = vam->input;
5099   vl_api_bd_ip_mac_add_del_t *mp;
5100   f64 timeout;
5101   u32 bd_id;
5102   u8 is_ipv6 = 0;
5103   u8 is_add = 1;
5104   u8 bd_id_set = 0;
5105   u8 ip_set = 0;
5106   u8 mac_set = 0;
5107   ip4_address_t v4addr;
5108   ip6_address_t v6addr;
5109   u8 macaddr[6];
5110
5111
5112   /* Parse args required to build the message */
5113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5114     {
5115       if (unformat (i, "bd_id %d", &bd_id))
5116         {
5117           bd_id_set++;
5118         }
5119       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5120         {
5121           ip_set++;
5122         }
5123       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5124         {
5125           ip_set++;
5126           is_ipv6++;
5127         }
5128       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5129         {
5130           mac_set++;
5131         }
5132       else if (unformat (i, "del"))
5133         is_add = 0;
5134       else
5135         break;
5136     }
5137
5138   if (bd_id_set == 0)
5139     {
5140       errmsg ("missing bridge domain\n");
5141       return -99;
5142     }
5143   else if (ip_set == 0)
5144     {
5145       errmsg ("missing IP address\n");
5146       return -99;
5147     }
5148   else if (mac_set == 0)
5149     {
5150       errmsg ("missing MAC address\n");
5151       return -99;
5152     }
5153
5154   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5155
5156   mp->bd_id = ntohl (bd_id);
5157   mp->is_ipv6 = is_ipv6;
5158   mp->is_add = is_add;
5159   if (is_ipv6)
5160     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5161   else
5162     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5163   clib_memcpy (mp->mac_address, macaddr, 6);
5164   S;
5165   W;
5166   /* NOTREACHED */
5167   return 0;
5168 }
5169
5170 static int
5171 api_tap_connect (vat_main_t * vam)
5172 {
5173   unformat_input_t *i = vam->input;
5174   vl_api_tap_connect_t *mp;
5175   f64 timeout;
5176   u8 mac_address[6];
5177   u8 random_mac = 1;
5178   u8 name_set = 0;
5179   u8 *tap_name;
5180
5181   memset (mac_address, 0, sizeof (mac_address));
5182
5183   /* Parse args required to build the message */
5184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5185     {
5186       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5187         {
5188           random_mac = 0;
5189         }
5190       else if (unformat (i, "random-mac"))
5191         random_mac = 1;
5192       else if (unformat (i, "tapname %s", &tap_name))
5193         name_set = 1;
5194       else
5195         break;
5196     }
5197
5198   if (name_set == 0)
5199     {
5200       errmsg ("missing tap name\n");
5201       return -99;
5202     }
5203   if (vec_len (tap_name) > 63)
5204     {
5205       errmsg ("tap name too long\n");
5206     }
5207   vec_add1 (tap_name, 0);
5208
5209   /* Construct the API message */
5210   M (TAP_CONNECT, tap_connect);
5211
5212   mp->use_random_mac = random_mac;
5213   clib_memcpy (mp->mac_address, mac_address, 6);
5214   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5215   vec_free (tap_name);
5216
5217   /* send it... */
5218   S;
5219
5220   /* Wait for a reply... */
5221   W;
5222 }
5223
5224 static int
5225 api_tap_modify (vat_main_t * vam)
5226 {
5227   unformat_input_t *i = vam->input;
5228   vl_api_tap_modify_t *mp;
5229   f64 timeout;
5230   u8 mac_address[6];
5231   u8 random_mac = 1;
5232   u8 name_set = 0;
5233   u8 *tap_name;
5234   u32 sw_if_index = ~0;
5235   u8 sw_if_index_set = 0;
5236
5237   memset (mac_address, 0, sizeof (mac_address));
5238
5239   /* Parse args required to build the message */
5240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5241     {
5242       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5243         sw_if_index_set = 1;
5244       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5245         sw_if_index_set = 1;
5246       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5247         {
5248           random_mac = 0;
5249         }
5250       else if (unformat (i, "random-mac"))
5251         random_mac = 1;
5252       else if (unformat (i, "tapname %s", &tap_name))
5253         name_set = 1;
5254       else
5255         break;
5256     }
5257
5258   if (sw_if_index_set == 0)
5259     {
5260       errmsg ("missing vpp interface name");
5261       return -99;
5262     }
5263   if (name_set == 0)
5264     {
5265       errmsg ("missing tap name\n");
5266       return -99;
5267     }
5268   if (vec_len (tap_name) > 63)
5269     {
5270       errmsg ("tap name too long\n");
5271     }
5272   vec_add1 (tap_name, 0);
5273
5274   /* Construct the API message */
5275   M (TAP_MODIFY, tap_modify);
5276
5277   mp->use_random_mac = random_mac;
5278   mp->sw_if_index = ntohl (sw_if_index);
5279   clib_memcpy (mp->mac_address, mac_address, 6);
5280   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5281   vec_free (tap_name);
5282
5283   /* send it... */
5284   S;
5285
5286   /* Wait for a reply... */
5287   W;
5288 }
5289
5290 static int
5291 api_tap_delete (vat_main_t * vam)
5292 {
5293   unformat_input_t *i = vam->input;
5294   vl_api_tap_delete_t *mp;
5295   f64 timeout;
5296   u32 sw_if_index = ~0;
5297   u8 sw_if_index_set = 0;
5298
5299   /* Parse args required to build the message */
5300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5301     {
5302       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5303         sw_if_index_set = 1;
5304       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5305         sw_if_index_set = 1;
5306       else
5307         break;
5308     }
5309
5310   if (sw_if_index_set == 0)
5311     {
5312       errmsg ("missing vpp interface name");
5313       return -99;
5314     }
5315
5316   /* Construct the API message */
5317   M (TAP_DELETE, tap_delete);
5318
5319   mp->sw_if_index = ntohl (sw_if_index);
5320
5321   /* send it... */
5322   S;
5323
5324   /* Wait for a reply... */
5325   W;
5326 }
5327
5328 static int
5329 api_ip_add_del_route (vat_main_t * vam)
5330 {
5331   unformat_input_t *i = vam->input;
5332   vl_api_ip_add_del_route_t *mp;
5333   f64 timeout;
5334   u32 sw_if_index = ~0, vrf_id = 0;
5335   u8 sw_if_index_set = 0;
5336   u8 is_ipv6 = 0;
5337   u8 is_local = 0, is_drop = 0;
5338   u8 create_vrf_if_needed = 0;
5339   u8 is_add = 1;
5340   u8 next_hop_weight = 1;
5341   u8 not_last = 0;
5342   u8 is_multipath = 0;
5343   u8 address_set = 0;
5344   u8 address_length_set = 0;
5345   u32 lookup_in_vrf = 0;
5346   u32 resolve_attempts = 0;
5347   u32 dst_address_length = 0;
5348   u8 next_hop_set = 0;
5349   ip4_address_t v4_dst_address, v4_next_hop_address;
5350   ip6_address_t v6_dst_address, v6_next_hop_address;
5351   int count = 1;
5352   int j;
5353   f64 before = 0;
5354   u32 random_add_del = 0;
5355   u32 *random_vector = 0;
5356   uword *random_hash;
5357   u32 random_seed = 0xdeaddabe;
5358   u32 classify_table_index = ~0;
5359   u8 is_classify = 0;
5360
5361   /* Parse args required to build the message */
5362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5363     {
5364       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5365         sw_if_index_set = 1;
5366       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5367         sw_if_index_set = 1;
5368       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5369         {
5370           address_set = 1;
5371           is_ipv6 = 0;
5372         }
5373       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5374         {
5375           address_set = 1;
5376           is_ipv6 = 1;
5377         }
5378       else if (unformat (i, "/%d", &dst_address_length))
5379         {
5380           address_length_set = 1;
5381         }
5382
5383       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5384                                          &v4_next_hop_address))
5385         {
5386           next_hop_set = 1;
5387         }
5388       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5389                                          &v6_next_hop_address))
5390         {
5391           next_hop_set = 1;
5392         }
5393       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5394         ;
5395       else if (unformat (i, "weight %d", &next_hop_weight))
5396         ;
5397       else if (unformat (i, "drop"))
5398         {
5399           is_drop = 1;
5400         }
5401       else if (unformat (i, "local"))
5402         {
5403           is_local = 1;
5404         }
5405       else if (unformat (i, "classify %d", &classify_table_index))
5406         {
5407           is_classify = 1;
5408         }
5409       else if (unformat (i, "del"))
5410         is_add = 0;
5411       else if (unformat (i, "add"))
5412         is_add = 1;
5413       else if (unformat (i, "not-last"))
5414         not_last = 1;
5415       else if (unformat (i, "multipath"))
5416         is_multipath = 1;
5417       else if (unformat (i, "vrf %d", &vrf_id))
5418         ;
5419       else if (unformat (i, "create-vrf"))
5420         create_vrf_if_needed = 1;
5421       else if (unformat (i, "count %d", &count))
5422         ;
5423       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5424         ;
5425       else if (unformat (i, "random"))
5426         random_add_del = 1;
5427       else if (unformat (i, "seed %d", &random_seed))
5428         ;
5429       else
5430         {
5431           clib_warning ("parse error '%U'", format_unformat_error, i);
5432           return -99;
5433         }
5434     }
5435
5436   if (resolve_attempts > 0 && sw_if_index_set == 0)
5437     {
5438       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5439       return -99;
5440     }
5441
5442   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5443     {
5444       errmsg ("next hop / local / drop / classify not set\n");
5445       return -99;
5446     }
5447
5448   if (address_set == 0)
5449     {
5450       errmsg ("missing addresses\n");
5451       return -99;
5452     }
5453
5454   if (address_length_set == 0)
5455     {
5456       errmsg ("missing address length\n");
5457       return -99;
5458     }
5459
5460   /* Generate a pile of unique, random routes */
5461   if (random_add_del)
5462     {
5463       u32 this_random_address;
5464       random_hash = hash_create (count, sizeof (uword));
5465
5466       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5467       for (j = 0; j <= count; j++)
5468         {
5469           do
5470             {
5471               this_random_address = random_u32 (&random_seed);
5472               this_random_address =
5473                 clib_host_to_net_u32 (this_random_address);
5474             }
5475           while (hash_get (random_hash, this_random_address));
5476           vec_add1 (random_vector, this_random_address);
5477           hash_set (random_hash, this_random_address, 1);
5478         }
5479       hash_free (random_hash);
5480       v4_dst_address.as_u32 = random_vector[0];
5481     }
5482
5483   if (count > 1)
5484     {
5485       /* Turn on async mode */
5486       vam->async_mode = 1;
5487       vam->async_errors = 0;
5488       before = vat_time_now (vam);
5489     }
5490
5491   for (j = 0; j < count; j++)
5492     {
5493       /* Construct the API message */
5494       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5495
5496       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5497       mp->vrf_id = ntohl (vrf_id);
5498       if (resolve_attempts > 0)
5499         {
5500           mp->resolve_attempts = ntohl (resolve_attempts);
5501           mp->resolve_if_needed = 1;
5502         }
5503       mp->create_vrf_if_needed = create_vrf_if_needed;
5504
5505       mp->is_add = is_add;
5506       mp->is_drop = is_drop;
5507       mp->is_ipv6 = is_ipv6;
5508       mp->is_local = is_local;
5509       mp->is_classify = is_classify;
5510       mp->is_multipath = is_multipath;
5511       mp->not_last = not_last;
5512       mp->next_hop_weight = next_hop_weight;
5513       mp->dst_address_length = dst_address_length;
5514       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5515       mp->classify_table_index = ntohl (classify_table_index);
5516
5517       if (is_ipv6)
5518         {
5519           clib_memcpy (mp->dst_address, &v6_dst_address,
5520                        sizeof (v6_dst_address));
5521           if (next_hop_set)
5522             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5523                          sizeof (v6_next_hop_address));
5524           increment_v6_address (&v6_dst_address);
5525         }
5526       else
5527         {
5528           clib_memcpy (mp->dst_address, &v4_dst_address,
5529                        sizeof (v4_dst_address));
5530           if (next_hop_set)
5531             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5532                          sizeof (v4_next_hop_address));
5533           if (random_add_del)
5534             v4_dst_address.as_u32 = random_vector[j + 1];
5535           else
5536             increment_v4_address (&v4_dst_address);
5537         }
5538       /* send it... */
5539       S;
5540     }
5541
5542   /* When testing multiple add/del ops, use a control-ping to sync */
5543   if (count > 1)
5544     {
5545       vl_api_control_ping_t *mp;
5546       f64 after;
5547
5548       /* Shut off async mode */
5549       vam->async_mode = 0;
5550
5551       M (CONTROL_PING, control_ping);
5552       S;
5553
5554       timeout = vat_time_now (vam) + 1.0;
5555       while (vat_time_now (vam) < timeout)
5556         if (vam->result_ready == 1)
5557           goto out;
5558       vam->retval = -99;
5559
5560     out:
5561       if (vam->retval == -99)
5562         errmsg ("timeout\n");
5563
5564       if (vam->async_errors > 0)
5565         {
5566           errmsg ("%d asynchronous errors\n", vam->async_errors);
5567           vam->retval = -98;
5568         }
5569       vam->async_errors = 0;
5570       after = vat_time_now (vam);
5571
5572       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5573                count, after - before, count / (after - before));
5574     }
5575   else
5576     {
5577       /* Wait for a reply... */
5578       W;
5579     }
5580
5581   /* Return the good/bad news */
5582   return (vam->retval);
5583 }
5584
5585 static int
5586 api_proxy_arp_add_del (vat_main_t * vam)
5587 {
5588   unformat_input_t *i = vam->input;
5589   vl_api_proxy_arp_add_del_t *mp;
5590   f64 timeout;
5591   u32 vrf_id = 0;
5592   u8 is_add = 1;
5593   ip4_address_t lo, hi;
5594   u8 range_set = 0;
5595
5596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5597     {
5598       if (unformat (i, "vrf %d", &vrf_id))
5599         ;
5600       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5601                          unformat_ip4_address, &hi))
5602         range_set = 1;
5603       else if (unformat (i, "del"))
5604         is_add = 0;
5605       else
5606         {
5607           clib_warning ("parse error '%U'", format_unformat_error, i);
5608           return -99;
5609         }
5610     }
5611
5612   if (range_set == 0)
5613     {
5614       errmsg ("address range not set\n");
5615       return -99;
5616     }
5617
5618   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5619
5620   mp->vrf_id = ntohl (vrf_id);
5621   mp->is_add = is_add;
5622   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5623   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5624
5625   S;
5626   W;
5627   /* NOTREACHED */
5628   return 0;
5629 }
5630
5631 static int
5632 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5633 {
5634   unformat_input_t *i = vam->input;
5635   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5636   f64 timeout;
5637   u32 sw_if_index;
5638   u8 enable = 1;
5639   u8 sw_if_index_set = 0;
5640
5641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5642     {
5643       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5644         sw_if_index_set = 1;
5645       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5646         sw_if_index_set = 1;
5647       else if (unformat (i, "enable"))
5648         enable = 1;
5649       else if (unformat (i, "disable"))
5650         enable = 0;
5651       else
5652         {
5653           clib_warning ("parse error '%U'", format_unformat_error, i);
5654           return -99;
5655         }
5656     }
5657
5658   if (sw_if_index_set == 0)
5659     {
5660       errmsg ("missing interface name or sw_if_index\n");
5661       return -99;
5662     }
5663
5664   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5665
5666   mp->sw_if_index = ntohl (sw_if_index);
5667   mp->enable_disable = enable;
5668
5669   S;
5670   W;
5671   /* NOTREACHED */
5672   return 0;
5673 }
5674
5675 static int
5676 api_mpls_add_del_decap (vat_main_t * vam)
5677 {
5678   unformat_input_t *i = vam->input;
5679   vl_api_mpls_add_del_decap_t *mp;
5680   f64 timeout;
5681   u32 rx_vrf_id = 0;
5682   u32 tx_vrf_id = 0;
5683   u32 label = 0;
5684   u8 is_add = 1;
5685   u8 s_bit = 1;
5686   u32 next_index = 1;
5687
5688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5689     {
5690       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5691         ;
5692       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5693         ;
5694       else if (unformat (i, "label %d", &label))
5695         ;
5696       else if (unformat (i, "next-index %d", &next_index))
5697         ;
5698       else if (unformat (i, "del"))
5699         is_add = 0;
5700       else if (unformat (i, "s-bit-clear"))
5701         s_bit = 0;
5702       else
5703         {
5704           clib_warning ("parse error '%U'", format_unformat_error, i);
5705           return -99;
5706         }
5707     }
5708
5709   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5710
5711   mp->rx_vrf_id = ntohl (rx_vrf_id);
5712   mp->tx_vrf_id = ntohl (tx_vrf_id);
5713   mp->label = ntohl (label);
5714   mp->next_index = ntohl (next_index);
5715   mp->s_bit = s_bit;
5716   mp->is_add = is_add;
5717
5718   S;
5719   W;
5720   /* NOTREACHED */
5721   return 0;
5722 }
5723
5724 static int
5725 api_mpls_add_del_encap (vat_main_t * vam)
5726 {
5727   unformat_input_t *i = vam->input;
5728   vl_api_mpls_add_del_encap_t *mp;
5729   f64 timeout;
5730   u32 vrf_id = 0;
5731   u32 *labels = 0;
5732   u32 label;
5733   ip4_address_t dst_address;
5734   u8 is_add = 1;
5735
5736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5737     {
5738       if (unformat (i, "vrf %d", &vrf_id))
5739         ;
5740       else if (unformat (i, "label %d", &label))
5741         vec_add1 (labels, ntohl (label));
5742       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5743         ;
5744       else if (unformat (i, "del"))
5745         is_add = 0;
5746       else
5747         {
5748           clib_warning ("parse error '%U'", format_unformat_error, i);
5749           return -99;
5750         }
5751     }
5752
5753   if (vec_len (labels) == 0)
5754     {
5755       errmsg ("missing encap label stack\n");
5756       return -99;
5757     }
5758
5759   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
5760       sizeof (u32) * vec_len (labels));
5761
5762   mp->vrf_id = ntohl (vrf_id);
5763   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5764   mp->is_add = is_add;
5765   mp->nlabels = vec_len (labels);
5766   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
5767
5768   vec_free (labels);
5769
5770   S;
5771   W;
5772   /* NOTREACHED */
5773   return 0;
5774 }
5775
5776 static int
5777 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
5778 {
5779   unformat_input_t *i = vam->input;
5780   vl_api_mpls_gre_add_del_tunnel_t *mp;
5781   f64 timeout;
5782   u32 inner_vrf_id = 0;
5783   u32 outer_vrf_id = 0;
5784   ip4_address_t src_address;
5785   ip4_address_t dst_address;
5786   ip4_address_t intfc_address;
5787   u32 tmp;
5788   u8 intfc_address_length = 0;
5789   u8 is_add = 1;
5790   u8 l2_only = 0;
5791
5792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5793     {
5794       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5795         ;
5796       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5797         ;
5798       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
5799         ;
5800       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5801         ;
5802       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5803                          &intfc_address, &tmp))
5804         intfc_address_length = tmp;
5805       else if (unformat (i, "l2-only"))
5806         l2_only = 1;
5807       else if (unformat (i, "del"))
5808         is_add = 0;
5809       else
5810         {
5811           clib_warning ("parse error '%U'", format_unformat_error, i);
5812           return -99;
5813         }
5814     }
5815
5816   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
5817
5818   mp->inner_vrf_id = ntohl (inner_vrf_id);
5819   mp->outer_vrf_id = ntohl (outer_vrf_id);
5820   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
5821   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5822   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
5823   mp->intfc_address_length = intfc_address_length;
5824   mp->l2_only = l2_only;
5825   mp->is_add = is_add;
5826
5827   S;
5828   W;
5829   /* NOTREACHED */
5830   return 0;
5831 }
5832
5833 static int
5834 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
5835 {
5836   unformat_input_t *i = vam->input;
5837   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
5838   f64 timeout;
5839   u32 inner_vrf_id = 0;
5840   ip4_address_t intfc_address;
5841   u8 dst_mac_address[6];
5842   int dst_set = 1;
5843   u32 tmp;
5844   u8 intfc_address_length = 0;
5845   u8 is_add = 1;
5846   u8 l2_only = 0;
5847   u32 tx_sw_if_index;
5848   int tx_sw_if_index_set = 0;
5849
5850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5851     {
5852       if (unformat (i, "vrf %d", &inner_vrf_id))
5853         ;
5854       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5855                          &intfc_address, &tmp))
5856         intfc_address_length = tmp;
5857       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
5858         tx_sw_if_index_set = 1;
5859       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5860         tx_sw_if_index_set = 1;
5861       else if (unformat (i, "dst %U", unformat_ethernet_address,
5862                          dst_mac_address))
5863         dst_set = 1;
5864       else if (unformat (i, "l2-only"))
5865         l2_only = 1;
5866       else if (unformat (i, "del"))
5867         is_add = 0;
5868       else
5869         {
5870           clib_warning ("parse error '%U'", format_unformat_error, i);
5871           return -99;
5872         }
5873     }
5874
5875   if (!dst_set)
5876     {
5877       errmsg ("dst (mac address) not set\n");
5878       return -99;
5879     }
5880   if (!tx_sw_if_index_set)
5881     {
5882       errmsg ("tx-intfc not set\n");
5883       return -99;
5884     }
5885
5886   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
5887
5888   mp->vrf_id = ntohl (inner_vrf_id);
5889   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
5890   mp->adj_address_length = intfc_address_length;
5891   clib_memcpy (mp->dst_mac_address, dst_mac_address,
5892                sizeof (dst_mac_address));
5893   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5894   mp->l2_only = l2_only;
5895   mp->is_add = is_add;
5896
5897   S;
5898   W;
5899   /* NOTREACHED */
5900   return 0;
5901 }
5902
5903 static int
5904 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
5905 {
5906   unformat_input_t *i = vam->input;
5907   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
5908   f64 timeout;
5909   u32 inner_vrf_id = 0;
5910   u32 outer_vrf_id = 0;
5911   ip4_address_t adj_address;
5912   int adj_address_set = 0;
5913   ip4_address_t next_hop_address;
5914   int next_hop_address_set = 0;
5915   u32 tmp;
5916   u8 adj_address_length = 0;
5917   u8 l2_only = 0;
5918   u8 is_add = 1;
5919   u32 resolve_attempts = 5;
5920   u8 resolve_if_needed = 1;
5921
5922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5923     {
5924       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5925         ;
5926       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5927         ;
5928       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5929                          &adj_address, &tmp))
5930         {
5931           adj_address_length = tmp;
5932           adj_address_set = 1;
5933         }
5934       else if (unformat (i, "next-hop %U", unformat_ip4_address,
5935                          &next_hop_address))
5936         next_hop_address_set = 1;
5937       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5938         ;
5939       else if (unformat (i, "resolve-if-needed %d", &tmp))
5940         resolve_if_needed = tmp;
5941       else if (unformat (i, "l2-only"))
5942         l2_only = 1;
5943       else if (unformat (i, "del"))
5944         is_add = 0;
5945       else
5946         {
5947           clib_warning ("parse error '%U'", format_unformat_error, i);
5948           return -99;
5949         }
5950     }
5951
5952   if (!adj_address_set)
5953     {
5954       errmsg ("adjacency address/mask not set\n");
5955       return -99;
5956     }
5957   if (!next_hop_address_set)
5958     {
5959       errmsg ("ip4 next hop address (in outer fib) not set\n");
5960       return -99;
5961     }
5962
5963   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
5964
5965   mp->inner_vrf_id = ntohl (inner_vrf_id);
5966   mp->outer_vrf_id = ntohl (outer_vrf_id);
5967   mp->resolve_attempts = ntohl (resolve_attempts);
5968   mp->resolve_if_needed = resolve_if_needed;
5969   mp->is_add = is_add;
5970   mp->l2_only = l2_only;
5971   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
5972   mp->adj_address_length = adj_address_length;
5973   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
5974                sizeof (next_hop_address));
5975
5976   S;
5977   W;
5978   /* NOTREACHED */
5979   return 0;
5980 }
5981
5982 static int
5983 api_sw_interface_set_unnumbered (vat_main_t * vam)
5984 {
5985   unformat_input_t *i = vam->input;
5986   vl_api_sw_interface_set_unnumbered_t *mp;
5987   f64 timeout;
5988   u32 sw_if_index;
5989   u32 unnum_sw_index = ~0;
5990   u8 is_add = 1;
5991   u8 sw_if_index_set = 0;
5992
5993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5994     {
5995       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5996         sw_if_index_set = 1;
5997       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5998         sw_if_index_set = 1;
5999       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6000         ;
6001       else if (unformat (i, "del"))
6002         is_add = 0;
6003       else
6004         {
6005           clib_warning ("parse error '%U'", format_unformat_error, i);
6006           return -99;
6007         }
6008     }
6009
6010   if (sw_if_index_set == 0)
6011     {
6012       errmsg ("missing interface name or sw_if_index\n");
6013       return -99;
6014     }
6015
6016   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6017
6018   mp->sw_if_index = ntohl (sw_if_index);
6019   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6020   mp->is_add = is_add;
6021
6022   S;
6023   W;
6024   /* NOTREACHED */
6025   return 0;
6026 }
6027
6028 static int
6029 api_ip_neighbor_add_del (vat_main_t * vam)
6030 {
6031   unformat_input_t *i = vam->input;
6032   vl_api_ip_neighbor_add_del_t *mp;
6033   f64 timeout;
6034   u32 sw_if_index;
6035   u8 sw_if_index_set = 0;
6036   u32 vrf_id = 0;
6037   u8 is_add = 1;
6038   u8 is_static = 0;
6039   u8 mac_address[6];
6040   u8 mac_set = 0;
6041   u8 v4_address_set = 0;
6042   u8 v6_address_set = 0;
6043   ip4_address_t v4address;
6044   ip6_address_t v6address;
6045
6046   memset (mac_address, 0, sizeof (mac_address));
6047
6048   /* Parse args required to build the message */
6049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6050     {
6051       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6052         {
6053           mac_set = 1;
6054         }
6055       else if (unformat (i, "del"))
6056         is_add = 0;
6057       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6058         sw_if_index_set = 1;
6059       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6060         sw_if_index_set = 1;
6061       else if (unformat (i, "is_static"))
6062         is_static = 1;
6063       else if (unformat (i, "vrf %d", &vrf_id))
6064         ;
6065       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6066         v4_address_set = 1;
6067       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6068         v6_address_set = 1;
6069       else
6070         {
6071           clib_warning ("parse error '%U'", format_unformat_error, i);
6072           return -99;
6073         }
6074     }
6075
6076   if (sw_if_index_set == 0)
6077     {
6078       errmsg ("missing interface name or sw_if_index\n");
6079       return -99;
6080     }
6081   if (v4_address_set && v6_address_set)
6082     {
6083       errmsg ("both v4 and v6 addresses set\n");
6084       return -99;
6085     }
6086   if (!v4_address_set && !v6_address_set)
6087     {
6088       errmsg ("no address set\n");
6089       return -99;
6090     }
6091
6092   /* Construct the API message */
6093   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6094
6095   mp->sw_if_index = ntohl (sw_if_index);
6096   mp->is_add = is_add;
6097   mp->vrf_id = ntohl (vrf_id);
6098   mp->is_static = is_static;
6099   if (mac_set)
6100     clib_memcpy (mp->mac_address, mac_address, 6);
6101   if (v6_address_set)
6102     {
6103       mp->is_ipv6 = 1;
6104       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6105     }
6106   else
6107     {
6108       /* mp->is_ipv6 = 0; via memset in M macro above */
6109       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6110     }
6111
6112   /* send it... */
6113   S;
6114
6115   /* Wait for a reply, return good/bad news  */
6116   W;
6117
6118   /* NOTREACHED */
6119   return 0;
6120 }
6121
6122 static int
6123 api_reset_vrf (vat_main_t * vam)
6124 {
6125   unformat_input_t *i = vam->input;
6126   vl_api_reset_vrf_t *mp;
6127   f64 timeout;
6128   u32 vrf_id = 0;
6129   u8 is_ipv6 = 0;
6130   u8 vrf_id_set = 0;
6131
6132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6133     {
6134       if (unformat (i, "vrf %d", &vrf_id))
6135         vrf_id_set = 1;
6136       else if (unformat (i, "ipv6"))
6137         is_ipv6 = 1;
6138       else
6139         {
6140           clib_warning ("parse error '%U'", format_unformat_error, i);
6141           return -99;
6142         }
6143     }
6144
6145   if (vrf_id_set == 0)
6146     {
6147       errmsg ("missing vrf id\n");
6148       return -99;
6149     }
6150
6151   M (RESET_VRF, reset_vrf);
6152
6153   mp->vrf_id = ntohl (vrf_id);
6154   mp->is_ipv6 = is_ipv6;
6155
6156   S;
6157   W;
6158   /* NOTREACHED */
6159   return 0;
6160 }
6161
6162 static int
6163 api_create_vlan_subif (vat_main_t * vam)
6164 {
6165   unformat_input_t *i = vam->input;
6166   vl_api_create_vlan_subif_t *mp;
6167   f64 timeout;
6168   u32 sw_if_index;
6169   u8 sw_if_index_set = 0;
6170   u32 vlan_id;
6171   u8 vlan_id_set = 0;
6172
6173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6174     {
6175       if (unformat (i, "sw_if_index %d", &sw_if_index))
6176         sw_if_index_set = 1;
6177       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6178         sw_if_index_set = 1;
6179       else if (unformat (i, "vlan %d", &vlan_id))
6180         vlan_id_set = 1;
6181       else
6182         {
6183           clib_warning ("parse error '%U'", format_unformat_error, i);
6184           return -99;
6185         }
6186     }
6187
6188   if (sw_if_index_set == 0)
6189     {
6190       errmsg ("missing interface name or sw_if_index\n");
6191       return -99;
6192     }
6193
6194   if (vlan_id_set == 0)
6195     {
6196       errmsg ("missing vlan_id\n");
6197       return -99;
6198     }
6199   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6200
6201   mp->sw_if_index = ntohl (sw_if_index);
6202   mp->vlan_id = ntohl (vlan_id);
6203
6204   S;
6205   W;
6206   /* NOTREACHED */
6207   return 0;
6208 }
6209
6210 #define foreach_create_subif_bit                \
6211 _(no_tags)                                      \
6212 _(one_tag)                                      \
6213 _(two_tags)                                     \
6214 _(dot1ad)                                       \
6215 _(exact_match)                                  \
6216 _(default_sub)                                  \
6217 _(outer_vlan_id_any)                            \
6218 _(inner_vlan_id_any)
6219
6220 static int
6221 api_create_subif (vat_main_t * vam)
6222 {
6223   unformat_input_t *i = vam->input;
6224   vl_api_create_subif_t *mp;
6225   f64 timeout;
6226   u32 sw_if_index;
6227   u8 sw_if_index_set = 0;
6228   u32 sub_id;
6229   u8 sub_id_set = 0;
6230   u32 no_tags = 0;
6231   u32 one_tag = 0;
6232   u32 two_tags = 0;
6233   u32 dot1ad = 0;
6234   u32 exact_match = 0;
6235   u32 default_sub = 0;
6236   u32 outer_vlan_id_any = 0;
6237   u32 inner_vlan_id_any = 0;
6238   u32 tmp;
6239   u16 outer_vlan_id = 0;
6240   u16 inner_vlan_id = 0;
6241
6242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6243     {
6244       if (unformat (i, "sw_if_index %d", &sw_if_index))
6245         sw_if_index_set = 1;
6246       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6247         sw_if_index_set = 1;
6248       else if (unformat (i, "sub_id %d", &sub_id))
6249         sub_id_set = 1;
6250       else if (unformat (i, "outer_vlan_id %d", &tmp))
6251         outer_vlan_id = tmp;
6252       else if (unformat (i, "inner_vlan_id %d", &tmp))
6253         inner_vlan_id = tmp;
6254
6255 #define _(a) else if (unformat (i, #a)) a = 1 ;
6256       foreach_create_subif_bit
6257 #undef _
6258         else
6259         {
6260           clib_warning ("parse error '%U'", format_unformat_error, i);
6261           return -99;
6262         }
6263     }
6264
6265   if (sw_if_index_set == 0)
6266     {
6267       errmsg ("missing interface name or sw_if_index\n");
6268       return -99;
6269     }
6270
6271   if (sub_id_set == 0)
6272     {
6273       errmsg ("missing sub_id\n");
6274       return -99;
6275     }
6276   M (CREATE_SUBIF, create_subif);
6277
6278   mp->sw_if_index = ntohl (sw_if_index);
6279   mp->sub_id = ntohl (sub_id);
6280
6281 #define _(a) mp->a = a;
6282   foreach_create_subif_bit;
6283 #undef _
6284
6285   mp->outer_vlan_id = ntohs (outer_vlan_id);
6286   mp->inner_vlan_id = ntohs (inner_vlan_id);
6287
6288   S;
6289   W;
6290   /* NOTREACHED */
6291   return 0;
6292 }
6293
6294 static int
6295 api_oam_add_del (vat_main_t * vam)
6296 {
6297   unformat_input_t *i = vam->input;
6298   vl_api_oam_add_del_t *mp;
6299   f64 timeout;
6300   u32 vrf_id = 0;
6301   u8 is_add = 1;
6302   ip4_address_t src, dst;
6303   u8 src_set = 0;
6304   u8 dst_set = 0;
6305
6306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6307     {
6308       if (unformat (i, "vrf %d", &vrf_id))
6309         ;
6310       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6311         src_set = 1;
6312       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6313         dst_set = 1;
6314       else if (unformat (i, "del"))
6315         is_add = 0;
6316       else
6317         {
6318           clib_warning ("parse error '%U'", format_unformat_error, i);
6319           return -99;
6320         }
6321     }
6322
6323   if (src_set == 0)
6324     {
6325       errmsg ("missing src addr\n");
6326       return -99;
6327     }
6328
6329   if (dst_set == 0)
6330     {
6331       errmsg ("missing dst addr\n");
6332       return -99;
6333     }
6334
6335   M (OAM_ADD_DEL, oam_add_del);
6336
6337   mp->vrf_id = ntohl (vrf_id);
6338   mp->is_add = is_add;
6339   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6340   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6341
6342   S;
6343   W;
6344   /* NOTREACHED */
6345   return 0;
6346 }
6347
6348 static int
6349 api_reset_fib (vat_main_t * vam)
6350 {
6351   unformat_input_t *i = vam->input;
6352   vl_api_reset_fib_t *mp;
6353   f64 timeout;
6354   u32 vrf_id = 0;
6355   u8 is_ipv6 = 0;
6356   u8 vrf_id_set = 0;
6357
6358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6359     {
6360       if (unformat (i, "vrf %d", &vrf_id))
6361         vrf_id_set = 1;
6362       else if (unformat (i, "ipv6"))
6363         is_ipv6 = 1;
6364       else
6365         {
6366           clib_warning ("parse error '%U'", format_unformat_error, i);
6367           return -99;
6368         }
6369     }
6370
6371   if (vrf_id_set == 0)
6372     {
6373       errmsg ("missing vrf id\n");
6374       return -99;
6375     }
6376
6377   M (RESET_FIB, reset_fib);
6378
6379   mp->vrf_id = ntohl (vrf_id);
6380   mp->is_ipv6 = is_ipv6;
6381
6382   S;
6383   W;
6384   /* NOTREACHED */
6385   return 0;
6386 }
6387
6388 static int
6389 api_dhcp_proxy_config (vat_main_t * vam)
6390 {
6391   unformat_input_t *i = vam->input;
6392   vl_api_dhcp_proxy_config_t *mp;
6393   f64 timeout;
6394   u32 vrf_id = 0;
6395   u8 is_add = 1;
6396   u8 insert_cid = 1;
6397   u8 v4_address_set = 0;
6398   u8 v6_address_set = 0;
6399   ip4_address_t v4address;
6400   ip6_address_t v6address;
6401   u8 v4_src_address_set = 0;
6402   u8 v6_src_address_set = 0;
6403   ip4_address_t v4srcaddress;
6404   ip6_address_t v6srcaddress;
6405
6406   /* Parse args required to build the message */
6407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6408     {
6409       if (unformat (i, "del"))
6410         is_add = 0;
6411       else if (unformat (i, "vrf %d", &vrf_id))
6412         ;
6413       else if (unformat (i, "insert-cid %d", &insert_cid))
6414         ;
6415       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6416         v4_address_set = 1;
6417       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6418         v6_address_set = 1;
6419       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6420         v4_src_address_set = 1;
6421       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6422         v6_src_address_set = 1;
6423       else
6424         break;
6425     }
6426
6427   if (v4_address_set && v6_address_set)
6428     {
6429       errmsg ("both v4 and v6 server addresses set\n");
6430       return -99;
6431     }
6432   if (!v4_address_set && !v6_address_set)
6433     {
6434       errmsg ("no server addresses set\n");
6435       return -99;
6436     }
6437
6438   if (v4_src_address_set && v6_src_address_set)
6439     {
6440       errmsg ("both v4 and v6  src addresses set\n");
6441       return -99;
6442     }
6443   if (!v4_src_address_set && !v6_src_address_set)
6444     {
6445       errmsg ("no src addresses set\n");
6446       return -99;
6447     }
6448
6449   if (!(v4_src_address_set && v4_address_set) &&
6450       !(v6_src_address_set && v6_address_set))
6451     {
6452       errmsg ("no matching server and src addresses set\n");
6453       return -99;
6454     }
6455
6456   /* Construct the API message */
6457   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6458
6459   mp->insert_circuit_id = insert_cid;
6460   mp->is_add = is_add;
6461   mp->vrf_id = ntohl (vrf_id);
6462   if (v6_address_set)
6463     {
6464       mp->is_ipv6 = 1;
6465       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6466       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6467     }
6468   else
6469     {
6470       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6471       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6472     }
6473
6474   /* send it... */
6475   S;
6476
6477   /* Wait for a reply, return good/bad news  */
6478   W;
6479   /* NOTREACHED */
6480   return 0;
6481 }
6482
6483 static int
6484 api_dhcp_proxy_config_2 (vat_main_t * vam)
6485 {
6486   unformat_input_t *i = vam->input;
6487   vl_api_dhcp_proxy_config_2_t *mp;
6488   f64 timeout;
6489   u32 rx_vrf_id = 0;
6490   u32 server_vrf_id = 0;
6491   u8 is_add = 1;
6492   u8 insert_cid = 1;
6493   u8 v4_address_set = 0;
6494   u8 v6_address_set = 0;
6495   ip4_address_t v4address;
6496   ip6_address_t v6address;
6497   u8 v4_src_address_set = 0;
6498   u8 v6_src_address_set = 0;
6499   ip4_address_t v4srcaddress;
6500   ip6_address_t v6srcaddress;
6501
6502   /* Parse args required to build the message */
6503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6504     {
6505       if (unformat (i, "del"))
6506         is_add = 0;
6507       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6508         ;
6509       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6510         ;
6511       else if (unformat (i, "insert-cid %d", &insert_cid))
6512         ;
6513       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6514         v4_address_set = 1;
6515       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6516         v6_address_set = 1;
6517       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6518         v4_src_address_set = 1;
6519       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6520         v6_src_address_set = 1;
6521       else
6522         break;
6523     }
6524
6525   if (v4_address_set && v6_address_set)
6526     {
6527       errmsg ("both v4 and v6 server addresses set\n");
6528       return -99;
6529     }
6530   if (!v4_address_set && !v6_address_set)
6531     {
6532       errmsg ("no server addresses set\n");
6533       return -99;
6534     }
6535
6536   if (v4_src_address_set && v6_src_address_set)
6537     {
6538       errmsg ("both v4 and v6  src addresses set\n");
6539       return -99;
6540     }
6541   if (!v4_src_address_set && !v6_src_address_set)
6542     {
6543       errmsg ("no src addresses set\n");
6544       return -99;
6545     }
6546
6547   if (!(v4_src_address_set && v4_address_set) &&
6548       !(v6_src_address_set && v6_address_set))
6549     {
6550       errmsg ("no matching server and src addresses set\n");
6551       return -99;
6552     }
6553
6554   /* Construct the API message */
6555   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6556
6557   mp->insert_circuit_id = insert_cid;
6558   mp->is_add = is_add;
6559   mp->rx_vrf_id = ntohl (rx_vrf_id);
6560   mp->server_vrf_id = ntohl (server_vrf_id);
6561   if (v6_address_set)
6562     {
6563       mp->is_ipv6 = 1;
6564       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6565       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6566     }
6567   else
6568     {
6569       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6570       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6571     }
6572
6573   /* send it... */
6574   S;
6575
6576   /* Wait for a reply, return good/bad news  */
6577   W;
6578   /* NOTREACHED */
6579   return 0;
6580 }
6581
6582 static int
6583 api_dhcp_proxy_set_vss (vat_main_t * vam)
6584 {
6585   unformat_input_t *i = vam->input;
6586   vl_api_dhcp_proxy_set_vss_t *mp;
6587   f64 timeout;
6588   u8 is_ipv6 = 0;
6589   u8 is_add = 1;
6590   u32 tbl_id;
6591   u8 tbl_id_set = 0;
6592   u32 oui;
6593   u8 oui_set = 0;
6594   u32 fib_id;
6595   u8 fib_id_set = 0;
6596
6597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6598     {
6599       if (unformat (i, "tbl_id %d", &tbl_id))
6600         tbl_id_set = 1;
6601       if (unformat (i, "fib_id %d", &fib_id))
6602         fib_id_set = 1;
6603       if (unformat (i, "oui %d", &oui))
6604         oui_set = 1;
6605       else if (unformat (i, "ipv6"))
6606         is_ipv6 = 1;
6607       else if (unformat (i, "del"))
6608         is_add = 0;
6609       else
6610         {
6611           clib_warning ("parse error '%U'", format_unformat_error, i);
6612           return -99;
6613         }
6614     }
6615
6616   if (tbl_id_set == 0)
6617     {
6618       errmsg ("missing tbl id\n");
6619       return -99;
6620     }
6621
6622   if (fib_id_set == 0)
6623     {
6624       errmsg ("missing fib id\n");
6625       return -99;
6626     }
6627   if (oui_set == 0)
6628     {
6629       errmsg ("missing oui\n");
6630       return -99;
6631     }
6632
6633   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6634   mp->tbl_id = ntohl (tbl_id);
6635   mp->fib_id = ntohl (fib_id);
6636   mp->oui = ntohl (oui);
6637   mp->is_ipv6 = is_ipv6;
6638   mp->is_add = is_add;
6639
6640   S;
6641   W;
6642   /* NOTREACHED */
6643   return 0;
6644 }
6645
6646 static int
6647 api_dhcp_client_config (vat_main_t * vam)
6648 {
6649   unformat_input_t *i = vam->input;
6650   vl_api_dhcp_client_config_t *mp;
6651   f64 timeout;
6652   u32 sw_if_index;
6653   u8 sw_if_index_set = 0;
6654   u8 is_add = 1;
6655   u8 *hostname = 0;
6656   u8 disable_event = 0;
6657
6658   /* Parse args required to build the message */
6659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6660     {
6661       if (unformat (i, "del"))
6662         is_add = 0;
6663       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6664         sw_if_index_set = 1;
6665       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6666         sw_if_index_set = 1;
6667       else if (unformat (i, "hostname %s", &hostname))
6668         ;
6669       else if (unformat (i, "disable_event"))
6670         disable_event = 1;
6671       else
6672         break;
6673     }
6674
6675   if (sw_if_index_set == 0)
6676     {
6677       errmsg ("missing interface name or sw_if_index\n");
6678       return -99;
6679     }
6680
6681   if (vec_len (hostname) > 63)
6682     {
6683       errmsg ("hostname too long\n");
6684     }
6685   vec_add1 (hostname, 0);
6686
6687   /* Construct the API message */
6688   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6689
6690   mp->sw_if_index = ntohl (sw_if_index);
6691   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6692   vec_free (hostname);
6693   mp->is_add = is_add;
6694   mp->want_dhcp_event = disable_event ? 0 : 1;
6695   mp->pid = getpid ();
6696
6697   /* send it... */
6698   S;
6699
6700   /* Wait for a reply, return good/bad news  */
6701   W;
6702   /* NOTREACHED */
6703   return 0;
6704 }
6705
6706 static int
6707 api_set_ip_flow_hash (vat_main_t * vam)
6708 {
6709   unformat_input_t *i = vam->input;
6710   vl_api_set_ip_flow_hash_t *mp;
6711   f64 timeout;
6712   u32 vrf_id = 0;
6713   u8 is_ipv6 = 0;
6714   u8 vrf_id_set = 0;
6715   u8 src = 0;
6716   u8 dst = 0;
6717   u8 sport = 0;
6718   u8 dport = 0;
6719   u8 proto = 0;
6720   u8 reverse = 0;
6721
6722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6723     {
6724       if (unformat (i, "vrf %d", &vrf_id))
6725         vrf_id_set = 1;
6726       else if (unformat (i, "ipv6"))
6727         is_ipv6 = 1;
6728       else if (unformat (i, "src"))
6729         src = 1;
6730       else if (unformat (i, "dst"))
6731         dst = 1;
6732       else if (unformat (i, "sport"))
6733         sport = 1;
6734       else if (unformat (i, "dport"))
6735         dport = 1;
6736       else if (unformat (i, "proto"))
6737         proto = 1;
6738       else if (unformat (i, "reverse"))
6739         reverse = 1;
6740
6741       else
6742         {
6743           clib_warning ("parse error '%U'", format_unformat_error, i);
6744           return -99;
6745         }
6746     }
6747
6748   if (vrf_id_set == 0)
6749     {
6750       errmsg ("missing vrf id\n");
6751       return -99;
6752     }
6753
6754   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
6755   mp->src = src;
6756   mp->dst = dst;
6757   mp->sport = sport;
6758   mp->dport = dport;
6759   mp->proto = proto;
6760   mp->reverse = reverse;
6761   mp->vrf_id = ntohl (vrf_id);
6762   mp->is_ipv6 = is_ipv6;
6763
6764   S;
6765   W;
6766   /* NOTREACHED */
6767   return 0;
6768 }
6769
6770 static int
6771 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
6772 {
6773   unformat_input_t *i = vam->input;
6774   vl_api_sw_interface_ip6_enable_disable_t *mp;
6775   f64 timeout;
6776   u32 sw_if_index;
6777   u8 sw_if_index_set = 0;
6778   u8 enable = 0;
6779
6780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6781     {
6782       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6783         sw_if_index_set = 1;
6784       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6785         sw_if_index_set = 1;
6786       else if (unformat (i, "enable"))
6787         enable = 1;
6788       else if (unformat (i, "disable"))
6789         enable = 0;
6790       else
6791         {
6792           clib_warning ("parse error '%U'", format_unformat_error, i);
6793           return -99;
6794         }
6795     }
6796
6797   if (sw_if_index_set == 0)
6798     {
6799       errmsg ("missing interface name or sw_if_index\n");
6800       return -99;
6801     }
6802
6803   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
6804
6805   mp->sw_if_index = ntohl (sw_if_index);
6806   mp->enable = enable;
6807
6808   S;
6809   W;
6810   /* NOTREACHED */
6811   return 0;
6812 }
6813
6814 static int
6815 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
6816 {
6817   unformat_input_t *i = vam->input;
6818   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
6819   f64 timeout;
6820   u32 sw_if_index;
6821   u8 sw_if_index_set = 0;
6822   u32 address_length = 0;
6823   u8 v6_address_set = 0;
6824   ip6_address_t v6address;
6825
6826   /* Parse args required to build the message */
6827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6828     {
6829       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6830         sw_if_index_set = 1;
6831       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6832         sw_if_index_set = 1;
6833       else if (unformat (i, "%U/%d",
6834                          unformat_ip6_address, &v6address, &address_length))
6835         v6_address_set = 1;
6836       else
6837         break;
6838     }
6839
6840   if (sw_if_index_set == 0)
6841     {
6842       errmsg ("missing interface name or sw_if_index\n");
6843       return -99;
6844     }
6845   if (!v6_address_set)
6846     {
6847       errmsg ("no address set\n");
6848       return -99;
6849     }
6850
6851   /* Construct the API message */
6852   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
6853      sw_interface_ip6_set_link_local_address);
6854
6855   mp->sw_if_index = ntohl (sw_if_index);
6856   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6857   mp->address_length = address_length;
6858
6859   /* send it... */
6860   S;
6861
6862   /* Wait for a reply, return good/bad news  */
6863   W;
6864
6865   /* NOTREACHED */
6866   return 0;
6867 }
6868
6869
6870 static int
6871 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
6872 {
6873   unformat_input_t *i = vam->input;
6874   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
6875   f64 timeout;
6876   u32 sw_if_index;
6877   u8 sw_if_index_set = 0;
6878   u32 address_length = 0;
6879   u8 v6_address_set = 0;
6880   ip6_address_t v6address;
6881   u8 use_default = 0;
6882   u8 no_advertise = 0;
6883   u8 off_link = 0;
6884   u8 no_autoconfig = 0;
6885   u8 no_onlink = 0;
6886   u8 is_no = 0;
6887   u32 val_lifetime = 0;
6888   u32 pref_lifetime = 0;
6889
6890   /* Parse args required to build the message */
6891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6892     {
6893       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6894         sw_if_index_set = 1;
6895       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6896         sw_if_index_set = 1;
6897       else if (unformat (i, "%U/%d",
6898                          unformat_ip6_address, &v6address, &address_length))
6899         v6_address_set = 1;
6900       else if (unformat (i, "val_life %d", &val_lifetime))
6901         ;
6902       else if (unformat (i, "pref_life %d", &pref_lifetime))
6903         ;
6904       else if (unformat (i, "def"))
6905         use_default = 1;
6906       else if (unformat (i, "noadv"))
6907         no_advertise = 1;
6908       else if (unformat (i, "offl"))
6909         off_link = 1;
6910       else if (unformat (i, "noauto"))
6911         no_autoconfig = 1;
6912       else if (unformat (i, "nolink"))
6913         no_onlink = 1;
6914       else if (unformat (i, "isno"))
6915         is_no = 1;
6916       else
6917         {
6918           clib_warning ("parse error '%U'", format_unformat_error, i);
6919           return -99;
6920         }
6921     }
6922
6923   if (sw_if_index_set == 0)
6924     {
6925       errmsg ("missing interface name or sw_if_index\n");
6926       return -99;
6927     }
6928   if (!v6_address_set)
6929     {
6930       errmsg ("no address set\n");
6931       return -99;
6932     }
6933
6934   /* Construct the API message */
6935   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
6936
6937   mp->sw_if_index = ntohl (sw_if_index);
6938   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6939   mp->address_length = address_length;
6940   mp->use_default = use_default;
6941   mp->no_advertise = no_advertise;
6942   mp->off_link = off_link;
6943   mp->no_autoconfig = no_autoconfig;
6944   mp->no_onlink = no_onlink;
6945   mp->is_no = is_no;
6946   mp->val_lifetime = ntohl (val_lifetime);
6947   mp->pref_lifetime = ntohl (pref_lifetime);
6948
6949   /* send it... */
6950   S;
6951
6952   /* Wait for a reply, return good/bad news  */
6953   W;
6954
6955   /* NOTREACHED */
6956   return 0;
6957 }
6958
6959 static int
6960 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
6961 {
6962   unformat_input_t *i = vam->input;
6963   vl_api_sw_interface_ip6nd_ra_config_t *mp;
6964   f64 timeout;
6965   u32 sw_if_index;
6966   u8 sw_if_index_set = 0;
6967   u8 suppress = 0;
6968   u8 managed = 0;
6969   u8 other = 0;
6970   u8 ll_option = 0;
6971   u8 send_unicast = 0;
6972   u8 cease = 0;
6973   u8 is_no = 0;
6974   u8 default_router = 0;
6975   u32 max_interval = 0;
6976   u32 min_interval = 0;
6977   u32 lifetime = 0;
6978   u32 initial_count = 0;
6979   u32 initial_interval = 0;
6980
6981
6982   /* Parse args required to build the message */
6983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6984     {
6985       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6986         sw_if_index_set = 1;
6987       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6988         sw_if_index_set = 1;
6989       else if (unformat (i, "maxint %d", &max_interval))
6990         ;
6991       else if (unformat (i, "minint %d", &min_interval))
6992         ;
6993       else if (unformat (i, "life %d", &lifetime))
6994         ;
6995       else if (unformat (i, "count %d", &initial_count))
6996         ;
6997       else if (unformat (i, "interval %d", &initial_interval))
6998         ;
6999       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7000         suppress = 1;
7001       else if (unformat (i, "managed"))
7002         managed = 1;
7003       else if (unformat (i, "other"))
7004         other = 1;
7005       else if (unformat (i, "ll"))
7006         ll_option = 1;
7007       else if (unformat (i, "send"))
7008         send_unicast = 1;
7009       else if (unformat (i, "cease"))
7010         cease = 1;
7011       else if (unformat (i, "isno"))
7012         is_no = 1;
7013       else if (unformat (i, "def"))
7014         default_router = 1;
7015       else
7016         {
7017           clib_warning ("parse error '%U'", format_unformat_error, i);
7018           return -99;
7019         }
7020     }
7021
7022   if (sw_if_index_set == 0)
7023     {
7024       errmsg ("missing interface name or sw_if_index\n");
7025       return -99;
7026     }
7027
7028   /* Construct the API message */
7029   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7030
7031   mp->sw_if_index = ntohl (sw_if_index);
7032   mp->max_interval = ntohl (max_interval);
7033   mp->min_interval = ntohl (min_interval);
7034   mp->lifetime = ntohl (lifetime);
7035   mp->initial_count = ntohl (initial_count);
7036   mp->initial_interval = ntohl (initial_interval);
7037   mp->suppress = suppress;
7038   mp->managed = managed;
7039   mp->other = other;
7040   mp->ll_option = ll_option;
7041   mp->send_unicast = send_unicast;
7042   mp->cease = cease;
7043   mp->is_no = is_no;
7044   mp->default_router = default_router;
7045
7046   /* send it... */
7047   S;
7048
7049   /* Wait for a reply, return good/bad news  */
7050   W;
7051
7052   /* NOTREACHED */
7053   return 0;
7054 }
7055
7056 static int
7057 api_set_arp_neighbor_limit (vat_main_t * vam)
7058 {
7059   unformat_input_t *i = vam->input;
7060   vl_api_set_arp_neighbor_limit_t *mp;
7061   f64 timeout;
7062   u32 arp_nbr_limit;
7063   u8 limit_set = 0;
7064   u8 is_ipv6 = 0;
7065
7066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7067     {
7068       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7069         limit_set = 1;
7070       else if (unformat (i, "ipv6"))
7071         is_ipv6 = 1;
7072       else
7073         {
7074           clib_warning ("parse error '%U'", format_unformat_error, i);
7075           return -99;
7076         }
7077     }
7078
7079   if (limit_set == 0)
7080     {
7081       errmsg ("missing limit value\n");
7082       return -99;
7083     }
7084
7085   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7086
7087   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7088   mp->is_ipv6 = is_ipv6;
7089
7090   S;
7091   W;
7092   /* NOTREACHED */
7093   return 0;
7094 }
7095
7096 static int
7097 api_l2_patch_add_del (vat_main_t * vam)
7098 {
7099   unformat_input_t *i = vam->input;
7100   vl_api_l2_patch_add_del_t *mp;
7101   f64 timeout;
7102   u32 rx_sw_if_index;
7103   u8 rx_sw_if_index_set = 0;
7104   u32 tx_sw_if_index;
7105   u8 tx_sw_if_index_set = 0;
7106   u8 is_add = 1;
7107
7108   /* Parse args required to build the message */
7109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7110     {
7111       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7112         rx_sw_if_index_set = 1;
7113       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7114         tx_sw_if_index_set = 1;
7115       else if (unformat (i, "rx"))
7116         {
7117           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7118             {
7119               if (unformat (i, "%U", unformat_sw_if_index, vam,
7120                             &rx_sw_if_index))
7121                 rx_sw_if_index_set = 1;
7122             }
7123           else
7124             break;
7125         }
7126       else if (unformat (i, "tx"))
7127         {
7128           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7129             {
7130               if (unformat (i, "%U", unformat_sw_if_index, vam,
7131                             &tx_sw_if_index))
7132                 tx_sw_if_index_set = 1;
7133             }
7134           else
7135             break;
7136         }
7137       else if (unformat (i, "del"))
7138         is_add = 0;
7139       else
7140         break;
7141     }
7142
7143   if (rx_sw_if_index_set == 0)
7144     {
7145       errmsg ("missing rx interface name or rx_sw_if_index\n");
7146       return -99;
7147     }
7148
7149   if (tx_sw_if_index_set == 0)
7150     {
7151       errmsg ("missing tx interface name or tx_sw_if_index\n");
7152       return -99;
7153     }
7154
7155   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7156
7157   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7158   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7159   mp->is_add = is_add;
7160
7161   S;
7162   W;
7163   /* NOTREACHED */
7164   return 0;
7165 }
7166
7167 static int
7168 api_trace_profile_add (vat_main_t * vam)
7169 {
7170   unformat_input_t *input = vam->input;
7171   vl_api_trace_profile_add_t *mp;
7172   f64 timeout;
7173   u32 id = 0;
7174   u32 trace_option_elts = 0;
7175   u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
7176   int has_pow_option = 0;
7177   int has_ppc_option = 0;
7178
7179   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7180     {
7181       if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
7182                     "trace-tsp %d node-id 0x%x app-data 0x%x",
7183                     &id, &trace_type, &trace_option_elts, &trace_tsp,
7184                     &node_id, &app_data))
7185         ;
7186       else if (unformat (input, "pow"))
7187         has_pow_option = 1;
7188       else if (unformat (input, "ppc encap"))
7189         has_ppc_option = PPC_ENCAP;
7190       else if (unformat (input, "ppc decap"))
7191         has_ppc_option = PPC_DECAP;
7192       else if (unformat (input, "ppc none"))
7193         has_ppc_option = PPC_NONE;
7194       else
7195         break;
7196     }
7197   M (TRACE_PROFILE_ADD, trace_profile_add);
7198   mp->id = htons (id);
7199   mp->trace_type = trace_type;
7200   mp->trace_num_elt = trace_option_elts;
7201   mp->trace_ppc = has_ppc_option;
7202   mp->trace_app_data = htonl (app_data);
7203   mp->pow_enable = has_pow_option;
7204   mp->trace_tsp = trace_tsp;
7205   mp->node_id = htonl (node_id);
7206
7207   S;
7208   W;
7209
7210   return (0);
7211
7212 }
7213
7214 static int
7215 api_trace_profile_apply (vat_main_t * vam)
7216 {
7217   unformat_input_t *input = vam->input;
7218   vl_api_trace_profile_apply_t *mp;
7219   f64 timeout;
7220   ip6_address_t addr;
7221   u32 mask_width = ~0;
7222   int is_add = 0;
7223   int is_pop = 0;
7224   int is_none = 0;
7225   u32 vrf_id = 0;
7226   u32 id = 0;
7227
7228   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7229     {
7230       if (unformat (input, "%U/%d", unformat_ip6_address, &addr, &mask_width))
7231         ;
7232       else if (unformat (input, "id %d", &id))
7233         ;
7234       else if (unformat (input, "vrf-id %d", &vrf_id))
7235         ;
7236       else if (unformat (input, "add"))
7237         is_add = 1;
7238       else if (unformat (input, "pop"))
7239         is_pop = 1;
7240       else if (unformat (input, "none"))
7241         is_none = 1;
7242       else
7243         break;
7244     }
7245
7246   if ((is_add + is_pop + is_none) != 1)
7247     {
7248       errmsg ("One of (add, pop, none) required");
7249       return -99;
7250     }
7251   if (mask_width == ~0)
7252     {
7253       errmsg ("<address>/<mask-width> required");
7254       return -99;
7255     }
7256   M (TRACE_PROFILE_APPLY, trace_profile_apply);
7257   clib_memcpy (mp->dest_ipv6, &addr, sizeof (mp->dest_ipv6));
7258   mp->id = htons (id);
7259   mp->prefix_length = htonl (mask_width);
7260   mp->vrf_id = htonl (vrf_id);
7261   if (is_add)
7262     mp->trace_op = IOAM_HBYH_ADD;
7263   else if (is_pop)
7264     mp->trace_op = IOAM_HBYH_POP;
7265   else
7266     mp->trace_op = IOAM_HBYH_MOD;
7267
7268   if (is_none)
7269     mp->enable = 0;
7270   else
7271     mp->enable = 1;
7272
7273   S;
7274   W;
7275
7276   return 0;
7277 }
7278
7279 static int
7280 api_trace_profile_del (vat_main_t * vam)
7281 {
7282   vl_api_trace_profile_del_t *mp;
7283   f64 timeout;
7284
7285   M (TRACE_PROFILE_DEL, trace_profile_del);
7286   S;
7287   W;
7288   return 0;
7289 }
7290
7291 static int
7292 api_sr_tunnel_add_del (vat_main_t * vam)
7293 {
7294   unformat_input_t *i = vam->input;
7295   vl_api_sr_tunnel_add_del_t *mp;
7296   f64 timeout;
7297   int is_del = 0;
7298   int pl_index;
7299   ip6_address_t src_address;
7300   int src_address_set = 0;
7301   ip6_address_t dst_address;
7302   u32 dst_mask_width;
7303   int dst_address_set = 0;
7304   u16 flags = 0;
7305   u32 rx_table_id = 0;
7306   u32 tx_table_id = 0;
7307   ip6_address_t *segments = 0;
7308   ip6_address_t *this_seg;
7309   ip6_address_t *tags = 0;
7310   ip6_address_t *this_tag;
7311   ip6_address_t next_address, tag;
7312   u8 *name = 0;
7313   u8 *policy_name = 0;
7314
7315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7316     {
7317       if (unformat (i, "del"))
7318         is_del = 1;
7319       else if (unformat (i, "name %s", &name))
7320         ;
7321       else if (unformat (i, "policy %s", &policy_name))
7322         ;
7323       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7324         ;
7325       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7326         ;
7327       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7328         src_address_set = 1;
7329       else if (unformat (i, "dst %U/%d",
7330                          unformat_ip6_address, &dst_address, &dst_mask_width))
7331         dst_address_set = 1;
7332       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7333         {
7334           vec_add2 (segments, this_seg, 1);
7335           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7336                        sizeof (*this_seg));
7337         }
7338       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7339         {
7340           vec_add2 (tags, this_tag, 1);
7341           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7342         }
7343       else if (unformat (i, "clean"))
7344         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7345       else if (unformat (i, "protected"))
7346         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7347       else if (unformat (i, "InPE %d", &pl_index))
7348         {
7349           if (pl_index <= 0 || pl_index > 4)
7350             {
7351             pl_index_range_error:
7352               errmsg ("pl index %d out of range\n", pl_index);
7353               return -99;
7354             }
7355           flags |=
7356             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7357         }
7358       else if (unformat (i, "EgPE %d", &pl_index))
7359         {
7360           if (pl_index <= 0 || pl_index > 4)
7361             goto pl_index_range_error;
7362           flags |=
7363             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7364         }
7365       else if (unformat (i, "OrgSrc %d", &pl_index))
7366         {
7367           if (pl_index <= 0 || pl_index > 4)
7368             goto pl_index_range_error;
7369           flags |=
7370             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7371         }
7372       else
7373         break;
7374     }
7375
7376   if (!src_address_set)
7377     {
7378       errmsg ("src address required\n");
7379       return -99;
7380     }
7381
7382   if (!dst_address_set)
7383     {
7384       errmsg ("dst address required\n");
7385       return -99;
7386     }
7387
7388   if (!segments)
7389     {
7390       errmsg ("at least one sr segment required\n");
7391       return -99;
7392     }
7393
7394   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7395       vec_len (segments) * sizeof (ip6_address_t)
7396       + vec_len (tags) * sizeof (ip6_address_t));
7397
7398   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7399   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7400   mp->dst_mask_width = dst_mask_width;
7401   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7402   mp->n_segments = vec_len (segments);
7403   mp->n_tags = vec_len (tags);
7404   mp->is_add = is_del == 0;
7405   clib_memcpy (mp->segs_and_tags, segments,
7406                vec_len (segments) * sizeof (ip6_address_t));
7407   clib_memcpy (mp->segs_and_tags +
7408                vec_len (segments) * sizeof (ip6_address_t), tags,
7409                vec_len (tags) * sizeof (ip6_address_t));
7410
7411   mp->outer_vrf_id = ntohl (rx_table_id);
7412   mp->inner_vrf_id = ntohl (tx_table_id);
7413   memcpy (mp->name, name, vec_len (name));
7414   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7415
7416   vec_free (segments);
7417   vec_free (tags);
7418
7419   S;
7420   W;
7421   /* NOTREACHED */
7422 }
7423
7424 static int
7425 api_sr_policy_add_del (vat_main_t * vam)
7426 {
7427   unformat_input_t *input = vam->input;
7428   vl_api_sr_policy_add_del_t *mp;
7429   f64 timeout;
7430   int is_del = 0;
7431   u8 *name = 0;
7432   u8 *tunnel_name = 0;
7433   u8 **tunnel_names = 0;
7434
7435   int name_set = 0;
7436   int tunnel_set = 0;
7437   int j = 0;
7438   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7439   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7440
7441   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7442     {
7443       if (unformat (input, "del"))
7444         is_del = 1;
7445       else if (unformat (input, "name %s", &name))
7446         name_set = 1;
7447       else if (unformat (input, "tunnel %s", &tunnel_name))
7448         {
7449           if (tunnel_name)
7450             {
7451               vec_add1 (tunnel_names, tunnel_name);
7452               /* For serializer:
7453                  - length = #bytes to store in serial vector
7454                  - +1 = byte to store that length
7455                */
7456               tunnel_names_length += (vec_len (tunnel_name) + 1);
7457               tunnel_set = 1;
7458               tunnel_name = 0;
7459             }
7460         }
7461       else
7462         break;
7463     }
7464
7465   if (!name_set)
7466     {
7467       errmsg ("policy name required\n");
7468       return -99;
7469     }
7470
7471   if ((!tunnel_set) && (!is_del))
7472     {
7473       errmsg ("tunnel name required\n");
7474       return -99;
7475     }
7476
7477   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7478
7479
7480
7481   mp->is_add = !is_del;
7482
7483   memcpy (mp->name, name, vec_len (name));
7484   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7485   u8 *serial_orig = 0;
7486   vec_validate (serial_orig, tunnel_names_length);
7487   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7488   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7489
7490   for (j = 0; j < vec_len (tunnel_names); j++)
7491     {
7492       tun_name_len = vec_len (tunnel_names[j]);
7493       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7494       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7495       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7496       serial_orig += tun_name_len;      // Advance past the copy
7497     }
7498   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7499
7500   vec_free (tunnel_names);
7501   vec_free (tunnel_name);
7502
7503   S;
7504   W;
7505   /* NOTREACHED */
7506 }
7507
7508 static int
7509 api_sr_multicast_map_add_del (vat_main_t * vam)
7510 {
7511   unformat_input_t *input = vam->input;
7512   vl_api_sr_multicast_map_add_del_t *mp;
7513   f64 timeout;
7514   int is_del = 0;
7515   ip6_address_t multicast_address;
7516   u8 *policy_name = 0;
7517   int multicast_address_set = 0;
7518
7519   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7520     {
7521       if (unformat (input, "del"))
7522         is_del = 1;
7523       else
7524         if (unformat
7525             (input, "address %U", unformat_ip6_address, &multicast_address))
7526         multicast_address_set = 1;
7527       else if (unformat (input, "sr-policy %s", &policy_name))
7528         ;
7529       else
7530         break;
7531     }
7532
7533   if (!is_del && !policy_name)
7534     {
7535       errmsg ("sr-policy name required\n");
7536       return -99;
7537     }
7538
7539
7540   if (!multicast_address_set)
7541     {
7542       errmsg ("address required\n");
7543       return -99;
7544     }
7545
7546   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7547
7548   mp->is_add = !is_del;
7549   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7550   clib_memcpy (mp->multicast_address, &multicast_address,
7551                sizeof (mp->multicast_address));
7552
7553
7554   vec_free (policy_name);
7555
7556   S;
7557   W;
7558   /* NOTREACHED */
7559 }
7560
7561
7562 #define foreach_ip4_proto_field                 \
7563 _(src_address)                                  \
7564 _(dst_address)                                  \
7565 _(tos)                                          \
7566 _(length)                                       \
7567 _(fragment_id)                                  \
7568 _(ttl)                                          \
7569 _(protocol)                                     \
7570 _(checksum)
7571
7572 uword
7573 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7574 {
7575   u8 **maskp = va_arg (*args, u8 **);
7576   u8 *mask = 0;
7577   u8 found_something = 0;
7578   ip4_header_t *ip;
7579
7580 #define _(a) u8 a=0;
7581   foreach_ip4_proto_field;
7582 #undef _
7583   u8 version = 0;
7584   u8 hdr_length = 0;
7585
7586
7587   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7588     {
7589       if (unformat (input, "version"))
7590         version = 1;
7591       else if (unformat (input, "hdr_length"))
7592         hdr_length = 1;
7593       else if (unformat (input, "src"))
7594         src_address = 1;
7595       else if (unformat (input, "dst"))
7596         dst_address = 1;
7597       else if (unformat (input, "proto"))
7598         protocol = 1;
7599
7600 #define _(a) else if (unformat (input, #a)) a=1;
7601       foreach_ip4_proto_field
7602 #undef _
7603         else
7604         break;
7605     }
7606
7607 #define _(a) found_something += a;
7608   foreach_ip4_proto_field;
7609 #undef _
7610
7611   if (found_something == 0)
7612     return 0;
7613
7614   vec_validate (mask, sizeof (*ip) - 1);
7615
7616   ip = (ip4_header_t *) mask;
7617
7618 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7619   foreach_ip4_proto_field;
7620 #undef _
7621
7622   ip->ip_version_and_header_length = 0;
7623
7624   if (version)
7625     ip->ip_version_and_header_length |= 0xF0;
7626
7627   if (hdr_length)
7628     ip->ip_version_and_header_length |= 0x0F;
7629
7630   *maskp = mask;
7631   return 1;
7632 }
7633
7634 #define foreach_ip6_proto_field                 \
7635 _(src_address)                                  \
7636 _(dst_address)                                  \
7637 _(payload_length)                               \
7638 _(hop_limit)                                    \
7639 _(protocol)
7640
7641 uword
7642 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7643 {
7644   u8 **maskp = va_arg (*args, u8 **);
7645   u8 *mask = 0;
7646   u8 found_something = 0;
7647   ip6_header_t *ip;
7648   u32 ip_version_traffic_class_and_flow_label;
7649
7650 #define _(a) u8 a=0;
7651   foreach_ip6_proto_field;
7652 #undef _
7653   u8 version = 0;
7654   u8 traffic_class = 0;
7655   u8 flow_label = 0;
7656
7657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7658     {
7659       if (unformat (input, "version"))
7660         version = 1;
7661       else if (unformat (input, "traffic-class"))
7662         traffic_class = 1;
7663       else if (unformat (input, "flow-label"))
7664         flow_label = 1;
7665       else if (unformat (input, "src"))
7666         src_address = 1;
7667       else if (unformat (input, "dst"))
7668         dst_address = 1;
7669       else if (unformat (input, "proto"))
7670         protocol = 1;
7671
7672 #define _(a) else if (unformat (input, #a)) a=1;
7673       foreach_ip6_proto_field
7674 #undef _
7675         else
7676         break;
7677     }
7678
7679 #define _(a) found_something += a;
7680   foreach_ip6_proto_field;
7681 #undef _
7682
7683   if (found_something == 0)
7684     return 0;
7685
7686   vec_validate (mask, sizeof (*ip) - 1);
7687
7688   ip = (ip6_header_t *) mask;
7689
7690 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7691   foreach_ip6_proto_field;
7692 #undef _
7693
7694   ip_version_traffic_class_and_flow_label = 0;
7695
7696   if (version)
7697     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7698
7699   if (traffic_class)
7700     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7701
7702   if (flow_label)
7703     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7704
7705   ip->ip_version_traffic_class_and_flow_label =
7706     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7707
7708   *maskp = mask;
7709   return 1;
7710 }
7711
7712 uword
7713 unformat_l3_mask (unformat_input_t * input, va_list * args)
7714 {
7715   u8 **maskp = va_arg (*args, u8 **);
7716
7717   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7718     {
7719       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7720         return 1;
7721       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7722         return 1;
7723       else
7724         break;
7725     }
7726   return 0;
7727 }
7728
7729 uword
7730 unformat_l2_mask (unformat_input_t * input, va_list * args)
7731 {
7732   u8 **maskp = va_arg (*args, u8 **);
7733   u8 *mask = 0;
7734   u8 src = 0;
7735   u8 dst = 0;
7736   u8 proto = 0;
7737   u8 tag1 = 0;
7738   u8 tag2 = 0;
7739   u8 ignore_tag1 = 0;
7740   u8 ignore_tag2 = 0;
7741   u8 cos1 = 0;
7742   u8 cos2 = 0;
7743   u8 dot1q = 0;
7744   u8 dot1ad = 0;
7745   int len = 14;
7746
7747   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7748     {
7749       if (unformat (input, "src"))
7750         src = 1;
7751       else if (unformat (input, "dst"))
7752         dst = 1;
7753       else if (unformat (input, "proto"))
7754         proto = 1;
7755       else if (unformat (input, "tag1"))
7756         tag1 = 1;
7757       else if (unformat (input, "tag2"))
7758         tag2 = 1;
7759       else if (unformat (input, "ignore-tag1"))
7760         ignore_tag1 = 1;
7761       else if (unformat (input, "ignore-tag2"))
7762         ignore_tag2 = 1;
7763       else if (unformat (input, "cos1"))
7764         cos1 = 1;
7765       else if (unformat (input, "cos2"))
7766         cos2 = 1;
7767       else if (unformat (input, "dot1q"))
7768         dot1q = 1;
7769       else if (unformat (input, "dot1ad"))
7770         dot1ad = 1;
7771       else
7772         break;
7773     }
7774   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7775        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7776     return 0;
7777
7778   if (tag1 || ignore_tag1 || cos1 || dot1q)
7779     len = 18;
7780   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7781     len = 22;
7782
7783   vec_validate (mask, len - 1);
7784
7785   if (dst)
7786     memset (mask, 0xff, 6);
7787
7788   if (src)
7789     memset (mask + 6, 0xff, 6);
7790
7791   if (tag2 || dot1ad)
7792     {
7793       /* inner vlan tag */
7794       if (tag2)
7795         {
7796           mask[19] = 0xff;
7797           mask[18] = 0x0f;
7798         }
7799       if (cos2)
7800         mask[18] |= 0xe0;
7801       if (proto)
7802         mask[21] = mask[20] = 0xff;
7803       if (tag1)
7804         {
7805           mask[15] = 0xff;
7806           mask[14] = 0x0f;
7807         }
7808       if (cos1)
7809         mask[14] |= 0xe0;
7810       *maskp = mask;
7811       return 1;
7812     }
7813   if (tag1 | dot1q)
7814     {
7815       if (tag1)
7816         {
7817           mask[15] = 0xff;
7818           mask[14] = 0x0f;
7819         }
7820       if (cos1)
7821         mask[14] |= 0xe0;
7822       if (proto)
7823         mask[16] = mask[17] = 0xff;
7824
7825       *maskp = mask;
7826       return 1;
7827     }
7828   if (cos2)
7829     mask[18] |= 0xe0;
7830   if (cos1)
7831     mask[14] |= 0xe0;
7832   if (proto)
7833     mask[12] = mask[13] = 0xff;
7834
7835   *maskp = mask;
7836   return 1;
7837 }
7838
7839 uword
7840 unformat_classify_mask (unformat_input_t * input, va_list * args)
7841 {
7842   u8 **maskp = va_arg (*args, u8 **);
7843   u32 *skipp = va_arg (*args, u32 *);
7844   u32 *matchp = va_arg (*args, u32 *);
7845   u32 match;
7846   u8 *mask = 0;
7847   u8 *l2 = 0;
7848   u8 *l3 = 0;
7849   int i;
7850
7851   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7852     {
7853       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7854         ;
7855       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7856         ;
7857       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7858         ;
7859       else
7860         break;
7861     }
7862
7863   if (mask || l2 || l3)
7864     {
7865       if (l2 || l3)
7866         {
7867           /* "With a free Ethernet header in every package" */
7868           if (l2 == 0)
7869             vec_validate (l2, 13);
7870           mask = l2;
7871           if (vec_len (l3))
7872             {
7873               vec_append (mask, l3);
7874               vec_free (l3);
7875             }
7876         }
7877
7878       /* Scan forward looking for the first significant mask octet */
7879       for (i = 0; i < vec_len (mask); i++)
7880         if (mask[i])
7881           break;
7882
7883       /* compute (skip, match) params */
7884       *skipp = i / sizeof (u32x4);
7885       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7886
7887       /* Pad mask to an even multiple of the vector size */
7888       while (vec_len (mask) % sizeof (u32x4))
7889         vec_add1 (mask, 0);
7890
7891       match = vec_len (mask) / sizeof (u32x4);
7892
7893       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7894         {
7895           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7896           if (*tmp || *(tmp + 1))
7897             break;
7898           match--;
7899         }
7900       if (match == 0)
7901         clib_warning ("BUG: match 0");
7902
7903       _vec_len (mask) = match * sizeof (u32x4);
7904
7905       *matchp = match;
7906       *maskp = mask;
7907
7908       return 1;
7909     }
7910
7911   return 0;
7912 }
7913
7914 #define foreach_l2_next                         \
7915 _(drop, DROP)                                   \
7916 _(ethernet, ETHERNET_INPUT)                     \
7917 _(ip4, IP4_INPUT)                               \
7918 _(ip6, IP6_INPUT)
7919
7920 uword
7921 unformat_l2_next_index (unformat_input_t * input, va_list * args)
7922 {
7923   u32 *miss_next_indexp = va_arg (*args, u32 *);
7924   u32 next_index = 0;
7925   u32 tmp;
7926
7927 #define _(n,N) \
7928   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
7929   foreach_l2_next;
7930 #undef _
7931
7932   if (unformat (input, "%d", &tmp))
7933     {
7934       next_index = tmp;
7935       goto out;
7936     }
7937
7938   return 0;
7939
7940 out:
7941   *miss_next_indexp = next_index;
7942   return 1;
7943 }
7944
7945 #define foreach_ip_next                         \
7946 _(miss, MISS)                                   \
7947 _(drop, DROP)                                   \
7948 _(local, LOCAL)                                 \
7949 _(rewrite, REWRITE)
7950
7951 uword
7952 unformat_ip_next_index (unformat_input_t * input, va_list * args)
7953 {
7954   u32 *miss_next_indexp = va_arg (*args, u32 *);
7955   u32 next_index = 0;
7956   u32 tmp;
7957
7958 #define _(n,N) \
7959   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7960   foreach_ip_next;
7961 #undef _
7962
7963   if (unformat (input, "%d", &tmp))
7964     {
7965       next_index = tmp;
7966       goto out;
7967     }
7968
7969   return 0;
7970
7971 out:
7972   *miss_next_indexp = next_index;
7973   return 1;
7974 }
7975
7976 #define foreach_acl_next                        \
7977 _(deny, DENY)
7978
7979 uword
7980 unformat_acl_next_index (unformat_input_t * input, va_list * args)
7981 {
7982   u32 *miss_next_indexp = va_arg (*args, u32 *);
7983   u32 next_index = 0;
7984   u32 tmp;
7985
7986 #define _(n,N) \
7987   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7988   foreach_acl_next;
7989 #undef _
7990
7991   if (unformat (input, "permit"))
7992     {
7993       next_index = ~0;
7994       goto out;
7995     }
7996   else if (unformat (input, "%d", &tmp))
7997     {
7998       next_index = tmp;
7999       goto out;
8000     }
8001
8002   return 0;
8003
8004 out:
8005   *miss_next_indexp = next_index;
8006   return 1;
8007 }
8008
8009 uword
8010 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8011 {
8012   u32 *r = va_arg (*args, u32 *);
8013
8014   if (unformat (input, "conform-color"))
8015     *r = POLICE_CONFORM;
8016   else if (unformat (input, "exceed-color"))
8017     *r = POLICE_EXCEED;
8018   else
8019     return 0;
8020
8021   return 1;
8022 }
8023
8024 static int
8025 api_classify_add_del_table (vat_main_t * vam)
8026 {
8027   unformat_input_t *i = vam->input;
8028   vl_api_classify_add_del_table_t *mp;
8029
8030   u32 nbuckets = 2;
8031   u32 skip = ~0;
8032   u32 match = ~0;
8033   int is_add = 1;
8034   u32 table_index = ~0;
8035   u32 next_table_index = ~0;
8036   u32 miss_next_index = ~0;
8037   u32 memory_size = 32 << 20;
8038   u8 *mask = 0;
8039   f64 timeout;
8040
8041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8042     {
8043       if (unformat (i, "del"))
8044         is_add = 0;
8045       else if (unformat (i, "buckets %d", &nbuckets))
8046         ;
8047       else if (unformat (i, "memory_size %d", &memory_size))
8048         ;
8049       else if (unformat (i, "skip %d", &skip))
8050         ;
8051       else if (unformat (i, "match %d", &match))
8052         ;
8053       else if (unformat (i, "table %d", &table_index))
8054         ;
8055       else if (unformat (i, "mask %U", unformat_classify_mask,
8056                          &mask, &skip, &match))
8057         ;
8058       else if (unformat (i, "next-table %d", &next_table_index))
8059         ;
8060       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8061                          &miss_next_index))
8062         ;
8063       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8064                          &miss_next_index))
8065         ;
8066       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8067                          &miss_next_index))
8068         ;
8069       else
8070         break;
8071     }
8072
8073   if (is_add && mask == 0)
8074     {
8075       errmsg ("Mask required\n");
8076       return -99;
8077     }
8078
8079   if (is_add && skip == ~0)
8080     {
8081       errmsg ("skip count required\n");
8082       return -99;
8083     }
8084
8085   if (is_add && match == ~0)
8086     {
8087       errmsg ("match count required\n");
8088       return -99;
8089     }
8090
8091   if (!is_add && table_index == ~0)
8092     {
8093       errmsg ("table index required for delete\n");
8094       return -99;
8095     }
8096
8097   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8098
8099   mp->is_add = is_add;
8100   mp->table_index = ntohl (table_index);
8101   mp->nbuckets = ntohl (nbuckets);
8102   mp->memory_size = ntohl (memory_size);
8103   mp->skip_n_vectors = ntohl (skip);
8104   mp->match_n_vectors = ntohl (match);
8105   mp->next_table_index = ntohl (next_table_index);
8106   mp->miss_next_index = ntohl (miss_next_index);
8107   clib_memcpy (mp->mask, mask, vec_len (mask));
8108
8109   vec_free (mask);
8110
8111   S;
8112   W;
8113   /* NOTREACHED */
8114 }
8115
8116 uword
8117 unformat_ip4_match (unformat_input_t * input, va_list * args)
8118 {
8119   u8 **matchp = va_arg (*args, u8 **);
8120   u8 *match = 0;
8121   ip4_header_t *ip;
8122   int version = 0;
8123   u32 version_val;
8124   int hdr_length = 0;
8125   u32 hdr_length_val;
8126   int src = 0, dst = 0;
8127   ip4_address_t src_val, dst_val;
8128   int proto = 0;
8129   u32 proto_val;
8130   int tos = 0;
8131   u32 tos_val;
8132   int length = 0;
8133   u32 length_val;
8134   int fragment_id = 0;
8135   u32 fragment_id_val;
8136   int ttl = 0;
8137   int ttl_val;
8138   int checksum = 0;
8139   u32 checksum_val;
8140
8141   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8142     {
8143       if (unformat (input, "version %d", &version_val))
8144         version = 1;
8145       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8146         hdr_length = 1;
8147       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8148         src = 1;
8149       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8150         dst = 1;
8151       else if (unformat (input, "proto %d", &proto_val))
8152         proto = 1;
8153       else if (unformat (input, "tos %d", &tos_val))
8154         tos = 1;
8155       else if (unformat (input, "length %d", &length_val))
8156         length = 1;
8157       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8158         fragment_id = 1;
8159       else if (unformat (input, "ttl %d", &ttl_val))
8160         ttl = 1;
8161       else if (unformat (input, "checksum %d", &checksum_val))
8162         checksum = 1;
8163       else
8164         break;
8165     }
8166
8167   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8168       + ttl + checksum == 0)
8169     return 0;
8170
8171   /*
8172    * Aligned because we use the real comparison functions
8173    */
8174   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8175
8176   ip = (ip4_header_t *) match;
8177
8178   /* These are realistically matched in practice */
8179   if (src)
8180     ip->src_address.as_u32 = src_val.as_u32;
8181
8182   if (dst)
8183     ip->dst_address.as_u32 = dst_val.as_u32;
8184
8185   if (proto)
8186     ip->protocol = proto_val;
8187
8188
8189   /* These are not, but they're included for completeness */
8190   if (version)
8191     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8192
8193   if (hdr_length)
8194     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8195
8196   if (tos)
8197     ip->tos = tos_val;
8198
8199   if (length)
8200     ip->length = length_val;
8201
8202   if (ttl)
8203     ip->ttl = ttl_val;
8204
8205   if (checksum)
8206     ip->checksum = checksum_val;
8207
8208   *matchp = match;
8209   return 1;
8210 }
8211
8212 uword
8213 unformat_ip6_match (unformat_input_t * input, va_list * args)
8214 {
8215   u8 **matchp = va_arg (*args, u8 **);
8216   u8 *match = 0;
8217   ip6_header_t *ip;
8218   int version = 0;
8219   u32 version_val;
8220   u8 traffic_class = 0;
8221   u32 traffic_class_val = 0;
8222   u8 flow_label = 0;
8223   u8 flow_label_val;
8224   int src = 0, dst = 0;
8225   ip6_address_t src_val, dst_val;
8226   int proto = 0;
8227   u32 proto_val;
8228   int payload_length = 0;
8229   u32 payload_length_val;
8230   int hop_limit = 0;
8231   int hop_limit_val;
8232   u32 ip_version_traffic_class_and_flow_label;
8233
8234   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8235     {
8236       if (unformat (input, "version %d", &version_val))
8237         version = 1;
8238       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8239         traffic_class = 1;
8240       else if (unformat (input, "flow_label %d", &flow_label_val))
8241         flow_label = 1;
8242       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8243         src = 1;
8244       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8245         dst = 1;
8246       else if (unformat (input, "proto %d", &proto_val))
8247         proto = 1;
8248       else if (unformat (input, "payload_length %d", &payload_length_val))
8249         payload_length = 1;
8250       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8251         hop_limit = 1;
8252       else
8253         break;
8254     }
8255
8256   if (version + traffic_class + flow_label + src + dst + proto +
8257       payload_length + hop_limit == 0)
8258     return 0;
8259
8260   /*
8261    * Aligned because we use the real comparison functions
8262    */
8263   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8264
8265   ip = (ip6_header_t *) match;
8266
8267   if (src)
8268     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8269
8270   if (dst)
8271     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8272
8273   if (proto)
8274     ip->protocol = proto_val;
8275
8276   ip_version_traffic_class_and_flow_label = 0;
8277
8278   if (version)
8279     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8280
8281   if (traffic_class)
8282     ip_version_traffic_class_and_flow_label |=
8283       (traffic_class_val & 0xFF) << 20;
8284
8285   if (flow_label)
8286     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8287
8288   ip->ip_version_traffic_class_and_flow_label =
8289     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8290
8291   if (payload_length)
8292     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8293
8294   if (hop_limit)
8295     ip->hop_limit = hop_limit_val;
8296
8297   *matchp = match;
8298   return 1;
8299 }
8300
8301 uword
8302 unformat_l3_match (unformat_input_t * input, va_list * args)
8303 {
8304   u8 **matchp = va_arg (*args, u8 **);
8305
8306   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8307     {
8308       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8309         return 1;
8310       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8311         return 1;
8312       else
8313         break;
8314     }
8315   return 0;
8316 }
8317
8318 uword
8319 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8320 {
8321   u8 *tagp = va_arg (*args, u8 *);
8322   u32 tag;
8323
8324   if (unformat (input, "%d", &tag))
8325     {
8326       tagp[0] = (tag >> 8) & 0x0F;
8327       tagp[1] = tag & 0xFF;
8328       return 1;
8329     }
8330
8331   return 0;
8332 }
8333
8334 uword
8335 unformat_l2_match (unformat_input_t * input, va_list * args)
8336 {
8337   u8 **matchp = va_arg (*args, u8 **);
8338   u8 *match = 0;
8339   u8 src = 0;
8340   u8 src_val[6];
8341   u8 dst = 0;
8342   u8 dst_val[6];
8343   u8 proto = 0;
8344   u16 proto_val;
8345   u8 tag1 = 0;
8346   u8 tag1_val[2];
8347   u8 tag2 = 0;
8348   u8 tag2_val[2];
8349   int len = 14;
8350   u8 ignore_tag1 = 0;
8351   u8 ignore_tag2 = 0;
8352   u8 cos1 = 0;
8353   u8 cos2 = 0;
8354   u32 cos1_val = 0;
8355   u32 cos2_val = 0;
8356
8357   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8358     {
8359       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8360         src = 1;
8361       else
8362         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8363         dst = 1;
8364       else if (unformat (input, "proto %U",
8365                          unformat_ethernet_type_host_byte_order, &proto_val))
8366         proto = 1;
8367       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8368         tag1 = 1;
8369       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8370         tag2 = 1;
8371       else if (unformat (input, "ignore-tag1"))
8372         ignore_tag1 = 1;
8373       else if (unformat (input, "ignore-tag2"))
8374         ignore_tag2 = 1;
8375       else if (unformat (input, "cos1 %d", &cos1_val))
8376         cos1 = 1;
8377       else if (unformat (input, "cos2 %d", &cos2_val))
8378         cos2 = 1;
8379       else
8380         break;
8381     }
8382   if ((src + dst + proto + tag1 + tag2 +
8383        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8384     return 0;
8385
8386   if (tag1 || ignore_tag1 || cos1)
8387     len = 18;
8388   if (tag2 || ignore_tag2 || cos2)
8389     len = 22;
8390
8391   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8392
8393   if (dst)
8394     clib_memcpy (match, dst_val, 6);
8395
8396   if (src)
8397     clib_memcpy (match + 6, src_val, 6);
8398
8399   if (tag2)
8400     {
8401       /* inner vlan tag */
8402       match[19] = tag2_val[1];
8403       match[18] = tag2_val[0];
8404       if (cos2)
8405         match[18] |= (cos2_val & 0x7) << 5;
8406       if (proto)
8407         {
8408           match[21] = proto_val & 0xff;
8409           match[20] = proto_val >> 8;
8410         }
8411       if (tag1)
8412         {
8413           match[15] = tag1_val[1];
8414           match[14] = tag1_val[0];
8415         }
8416       if (cos1)
8417         match[14] |= (cos1_val & 0x7) << 5;
8418       *matchp = match;
8419       return 1;
8420     }
8421   if (tag1)
8422     {
8423       match[15] = tag1_val[1];
8424       match[14] = tag1_val[0];
8425       if (proto)
8426         {
8427           match[17] = proto_val & 0xff;
8428           match[16] = proto_val >> 8;
8429         }
8430       if (cos1)
8431         match[14] |= (cos1_val & 0x7) << 5;
8432
8433       *matchp = match;
8434       return 1;
8435     }
8436   if (cos2)
8437     match[18] |= (cos2_val & 0x7) << 5;
8438   if (cos1)
8439     match[14] |= (cos1_val & 0x7) << 5;
8440   if (proto)
8441     {
8442       match[13] = proto_val & 0xff;
8443       match[12] = proto_val >> 8;
8444     }
8445
8446   *matchp = match;
8447   return 1;
8448 }
8449
8450
8451 uword
8452 unformat_classify_match (unformat_input_t * input, va_list * args)
8453 {
8454   u8 **matchp = va_arg (*args, u8 **);
8455   u32 skip_n_vectors = va_arg (*args, u32);
8456   u32 match_n_vectors = va_arg (*args, u32);
8457
8458   u8 *match = 0;
8459   u8 *l2 = 0;
8460   u8 *l3 = 0;
8461
8462   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8463     {
8464       if (unformat (input, "hex %U", unformat_hex_string, &match))
8465         ;
8466       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8467         ;
8468       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8469         ;
8470       else
8471         break;
8472     }
8473
8474   if (match || l2 || l3)
8475     {
8476       if (l2 || l3)
8477         {
8478           /* "Win a free Ethernet header in every packet" */
8479           if (l2 == 0)
8480             vec_validate_aligned (l2, 13, sizeof (u32x4));
8481           match = l2;
8482           if (vec_len (l3))
8483             {
8484               vec_append_aligned (match, l3, sizeof (u32x4));
8485               vec_free (l3);
8486             }
8487         }
8488
8489       /* Make sure the vector is big enough even if key is all 0's */
8490       vec_validate_aligned
8491         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8492          sizeof (u32x4));
8493
8494       /* Set size, include skipped vectors */
8495       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8496
8497       *matchp = match;
8498
8499       return 1;
8500     }
8501
8502   return 0;
8503 }
8504
8505 static int
8506 api_classify_add_del_session (vat_main_t * vam)
8507 {
8508   unformat_input_t *i = vam->input;
8509   vl_api_classify_add_del_session_t *mp;
8510   int is_add = 1;
8511   u32 table_index = ~0;
8512   u32 hit_next_index = ~0;
8513   u32 opaque_index = ~0;
8514   u8 *match = 0;
8515   i32 advance = 0;
8516   f64 timeout;
8517   u32 skip_n_vectors = 0;
8518   u32 match_n_vectors = 0;
8519
8520   /*
8521    * Warning: you have to supply skip_n and match_n
8522    * because the API client cant simply look at the classify
8523    * table object.
8524    */
8525
8526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8527     {
8528       if (unformat (i, "del"))
8529         is_add = 0;
8530       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8531                          &hit_next_index))
8532         ;
8533       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8534                          &hit_next_index))
8535         ;
8536       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8537                          &hit_next_index))
8538         ;
8539       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8540         ;
8541       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8542         ;
8543       else if (unformat (i, "opaque-index %d", &opaque_index))
8544         ;
8545       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8546         ;
8547       else if (unformat (i, "match_n %d", &match_n_vectors))
8548         ;
8549       else if (unformat (i, "match %U", unformat_classify_match,
8550                          &match, skip_n_vectors, match_n_vectors))
8551         ;
8552       else if (unformat (i, "advance %d", &advance))
8553         ;
8554       else if (unformat (i, "table-index %d", &table_index))
8555         ;
8556       else
8557         break;
8558     }
8559
8560   if (table_index == ~0)
8561     {
8562       errmsg ("Table index required\n");
8563       return -99;
8564     }
8565
8566   if (is_add && match == 0)
8567     {
8568       errmsg ("Match value required\n");
8569       return -99;
8570     }
8571
8572   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8573
8574   mp->is_add = is_add;
8575   mp->table_index = ntohl (table_index);
8576   mp->hit_next_index = ntohl (hit_next_index);
8577   mp->opaque_index = ntohl (opaque_index);
8578   mp->advance = ntohl (advance);
8579   clib_memcpy (mp->match, match, vec_len (match));
8580   vec_free (match);
8581
8582   S;
8583   W;
8584   /* NOTREACHED */
8585 }
8586
8587 static int
8588 api_classify_set_interface_ip_table (vat_main_t * vam)
8589 {
8590   unformat_input_t *i = vam->input;
8591   vl_api_classify_set_interface_ip_table_t *mp;
8592   f64 timeout;
8593   u32 sw_if_index;
8594   int sw_if_index_set;
8595   u32 table_index = ~0;
8596   u8 is_ipv6 = 0;
8597
8598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8599     {
8600       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8601         sw_if_index_set = 1;
8602       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8603         sw_if_index_set = 1;
8604       else if (unformat (i, "table %d", &table_index))
8605         ;
8606       else
8607         {
8608           clib_warning ("parse error '%U'", format_unformat_error, i);
8609           return -99;
8610         }
8611     }
8612
8613   if (sw_if_index_set == 0)
8614     {
8615       errmsg ("missing interface name or sw_if_index\n");
8616       return -99;
8617     }
8618
8619
8620   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8621
8622   mp->sw_if_index = ntohl (sw_if_index);
8623   mp->table_index = ntohl (table_index);
8624   mp->is_ipv6 = is_ipv6;
8625
8626   S;
8627   W;
8628   /* NOTREACHED */
8629   return 0;
8630 }
8631
8632 static int
8633 api_classify_set_interface_l2_tables (vat_main_t * vam)
8634 {
8635   unformat_input_t *i = vam->input;
8636   vl_api_classify_set_interface_l2_tables_t *mp;
8637   f64 timeout;
8638   u32 sw_if_index;
8639   int sw_if_index_set;
8640   u32 ip4_table_index = ~0;
8641   u32 ip6_table_index = ~0;
8642   u32 other_table_index = ~0;
8643   u32 is_input = 1;
8644
8645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8646     {
8647       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8648         sw_if_index_set = 1;
8649       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8650         sw_if_index_set = 1;
8651       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8652         ;
8653       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8654         ;
8655       else if (unformat (i, "other-table %d", &other_table_index))
8656         ;
8657       else if (unformat (i, "is-input %d", &is_input))
8658         ;
8659       else
8660         {
8661           clib_warning ("parse error '%U'", format_unformat_error, i);
8662           return -99;
8663         }
8664     }
8665
8666   if (sw_if_index_set == 0)
8667     {
8668       errmsg ("missing interface name or sw_if_index\n");
8669       return -99;
8670     }
8671
8672
8673   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8674
8675   mp->sw_if_index = ntohl (sw_if_index);
8676   mp->ip4_table_index = ntohl (ip4_table_index);
8677   mp->ip6_table_index = ntohl (ip6_table_index);
8678   mp->other_table_index = ntohl (other_table_index);
8679   mp->is_input = (u8) is_input;
8680
8681   S;
8682   W;
8683   /* NOTREACHED */
8684   return 0;
8685 }
8686
8687 static int
8688 api_ipfix_enable (vat_main_t * vam)
8689 {
8690   unformat_input_t *i = vam->input;
8691   vl_api_ipfix_enable_t *mp;
8692   ip4_address_t collector_address;
8693   u8 collector_address_set = 0;
8694   u32 collector_port = ~0;
8695   ip4_address_t src_address;
8696   u8 src_address_set = 0;
8697   u32 vrf_id = ~0;
8698   u32 path_mtu = ~0;
8699   u32 template_interval = ~0;
8700   f64 timeout;
8701
8702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8703     {
8704       if (unformat (i, "collector_address %U", unformat_ip4_address,
8705                     &collector_address))
8706         collector_address_set = 1;
8707       else if (unformat (i, "collector_port %d", &collector_port))
8708         ;
8709       else if (unformat (i, "src_address %U", unformat_ip4_address,
8710                          &src_address))
8711         src_address_set = 1;
8712       else if (unformat (i, "vrf_id %d", &vrf_id))
8713         ;
8714       else if (unformat (i, "path_mtu %d", &path_mtu))
8715         ;
8716       else if (unformat (i, "template_interval %d", &template_interval))
8717         ;
8718       else
8719         break;
8720     }
8721
8722   if (collector_address_set == 0)
8723     {
8724       errmsg ("collector_address required\n");
8725       return -99;
8726     }
8727
8728   if (src_address_set == 0)
8729     {
8730       errmsg ("src_address required\n");
8731       return -99;
8732     }
8733
8734   M (IPFIX_ENABLE, ipfix_enable);
8735
8736   memcpy (mp->collector_address, collector_address.data,
8737           sizeof (collector_address.data));
8738   mp->collector_port = htons ((u16) collector_port);
8739   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8740   mp->vrf_id = htonl (vrf_id);
8741   mp->path_mtu = htonl (path_mtu);
8742   mp->template_interval = htonl (template_interval);
8743
8744   S;
8745   W;
8746   /* NOTREACHED */
8747 }
8748
8749 static int
8750 api_get_node_index (vat_main_t * vam)
8751 {
8752   unformat_input_t *i = vam->input;
8753   vl_api_get_node_index_t *mp;
8754   f64 timeout;
8755   u8 *name = 0;
8756
8757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8758     {
8759       if (unformat (i, "node %s", &name))
8760         ;
8761       else
8762         break;
8763     }
8764   if (name == 0)
8765     {
8766       errmsg ("node name required\n");
8767       return -99;
8768     }
8769   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8770     {
8771       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8772       return -99;
8773     }
8774
8775   M (GET_NODE_INDEX, get_node_index);
8776   clib_memcpy (mp->node_name, name, vec_len (name));
8777   vec_free (name);
8778
8779   S;
8780   W;
8781   /* NOTREACHED */
8782   return 0;
8783 }
8784
8785 static int
8786 api_get_next_index (vat_main_t * vam)
8787 {
8788   unformat_input_t *i = vam->input;
8789   vl_api_get_next_index_t *mp;
8790   f64 timeout;
8791   u8 *node_name = 0, *next_node_name = 0;
8792
8793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8794     {
8795       if (unformat (i, "node-name %s", &node_name))
8796         ;
8797       else if (unformat (i, "next-node-name %s", &next_node_name))
8798         break;
8799     }
8800
8801   if (node_name == 0)
8802     {
8803       errmsg ("node name required\n");
8804       return -99;
8805     }
8806   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
8807     {
8808       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8809       return -99;
8810     }
8811
8812   if (next_node_name == 0)
8813     {
8814       errmsg ("next node name required\n");
8815       return -99;
8816     }
8817   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
8818     {
8819       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
8820       return -99;
8821     }
8822
8823   M (GET_NEXT_INDEX, get_next_index);
8824   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
8825   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
8826   vec_free (node_name);
8827   vec_free (next_node_name);
8828
8829   S;
8830   W;
8831   /* NOTREACHED */
8832   return 0;
8833 }
8834
8835 static int
8836 api_add_node_next (vat_main_t * vam)
8837 {
8838   unformat_input_t *i = vam->input;
8839   vl_api_add_node_next_t *mp;
8840   f64 timeout;
8841   u8 *name = 0;
8842   u8 *next = 0;
8843
8844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8845     {
8846       if (unformat (i, "node %s", &name))
8847         ;
8848       else if (unformat (i, "next %s", &next))
8849         ;
8850       else
8851         break;
8852     }
8853   if (name == 0)
8854     {
8855       errmsg ("node name required\n");
8856       return -99;
8857     }
8858   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8859     {
8860       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8861       return -99;
8862     }
8863   if (next == 0)
8864     {
8865       errmsg ("next node required\n");
8866       return -99;
8867     }
8868   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
8869     {
8870       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
8871       return -99;
8872     }
8873
8874   M (ADD_NODE_NEXT, add_node_next);
8875   clib_memcpy (mp->node_name, name, vec_len (name));
8876   clib_memcpy (mp->next_name, next, vec_len (next));
8877   vec_free (name);
8878   vec_free (next);
8879
8880   S;
8881   W;
8882   /* NOTREACHED */
8883   return 0;
8884 }
8885
8886 static int
8887 api_l2tpv3_create_tunnel (vat_main_t * vam)
8888 {
8889   unformat_input_t *i = vam->input;
8890   ip6_address_t client_address, our_address;
8891   int client_address_set = 0;
8892   int our_address_set = 0;
8893   u32 local_session_id = 0;
8894   u32 remote_session_id = 0;
8895   u64 local_cookie = 0;
8896   u64 remote_cookie = 0;
8897   u8 l2_sublayer_present = 0;
8898   vl_api_l2tpv3_create_tunnel_t *mp;
8899   f64 timeout;
8900
8901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8902     {
8903       if (unformat (i, "client_address %U", unformat_ip6_address,
8904                     &client_address))
8905         client_address_set = 1;
8906       else if (unformat (i, "our_address %U", unformat_ip6_address,
8907                          &our_address))
8908         our_address_set = 1;
8909       else if (unformat (i, "local_session_id %d", &local_session_id))
8910         ;
8911       else if (unformat (i, "remote_session_id %d", &remote_session_id))
8912         ;
8913       else if (unformat (i, "local_cookie %lld", &local_cookie))
8914         ;
8915       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
8916         ;
8917       else if (unformat (i, "l2-sublayer-present"))
8918         l2_sublayer_present = 1;
8919       else
8920         break;
8921     }
8922
8923   if (client_address_set == 0)
8924     {
8925       errmsg ("client_address required\n");
8926       return -99;
8927     }
8928
8929   if (our_address_set == 0)
8930     {
8931       errmsg ("our_address required\n");
8932       return -99;
8933     }
8934
8935   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
8936
8937   clib_memcpy (mp->client_address, client_address.as_u8,
8938                sizeof (mp->client_address));
8939
8940   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
8941
8942   mp->local_session_id = ntohl (local_session_id);
8943   mp->remote_session_id = ntohl (remote_session_id);
8944   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
8945   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
8946   mp->l2_sublayer_present = l2_sublayer_present;
8947   mp->is_ipv6 = 1;
8948
8949   S;
8950   W;
8951   /* NOTREACHED */
8952   return 0;
8953 }
8954
8955 static int
8956 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
8957 {
8958   unformat_input_t *i = vam->input;
8959   u32 sw_if_index;
8960   u8 sw_if_index_set = 0;
8961   u64 new_local_cookie = 0;
8962   u64 new_remote_cookie = 0;
8963   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
8964   f64 timeout;
8965
8966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8967     {
8968       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8969         sw_if_index_set = 1;
8970       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8971         sw_if_index_set = 1;
8972       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
8973         ;
8974       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
8975         ;
8976       else
8977         break;
8978     }
8979
8980   if (sw_if_index_set == 0)
8981     {
8982       errmsg ("missing interface name or sw_if_index\n");
8983       return -99;
8984     }
8985
8986   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
8987
8988   mp->sw_if_index = ntohl (sw_if_index);
8989   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
8990   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
8991
8992   S;
8993   W;
8994   /* NOTREACHED */
8995   return 0;
8996 }
8997
8998 static int
8999 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9000 {
9001   unformat_input_t *i = vam->input;
9002   vl_api_l2tpv3_interface_enable_disable_t *mp;
9003   f64 timeout;
9004   u32 sw_if_index;
9005   u8 sw_if_index_set = 0;
9006   u8 enable_disable = 1;
9007
9008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9009     {
9010       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9011         sw_if_index_set = 1;
9012       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9013         sw_if_index_set = 1;
9014       else if (unformat (i, "enable"))
9015         enable_disable = 1;
9016       else if (unformat (i, "disable"))
9017         enable_disable = 0;
9018       else
9019         break;
9020     }
9021
9022   if (sw_if_index_set == 0)
9023     {
9024       errmsg ("missing interface name or sw_if_index\n");
9025       return -99;
9026     }
9027
9028   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9029
9030   mp->sw_if_index = ntohl (sw_if_index);
9031   mp->enable_disable = enable_disable;
9032
9033   S;
9034   W;
9035   /* NOTREACHED */
9036   return 0;
9037 }
9038
9039 static int
9040 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9041 {
9042   unformat_input_t *i = vam->input;
9043   vl_api_l2tpv3_set_lookup_key_t *mp;
9044   f64 timeout;
9045   u8 key = ~0;
9046
9047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9048     {
9049       if (unformat (i, "lookup_v6_src"))
9050         key = L2T_LOOKUP_SRC_ADDRESS;
9051       else if (unformat (i, "lookup_v6_dst"))
9052         key = L2T_LOOKUP_DST_ADDRESS;
9053       else if (unformat (i, "lookup_session_id"))
9054         key = L2T_LOOKUP_SESSION_ID;
9055       else
9056         break;
9057     }
9058
9059   if (key == (u8) ~ 0)
9060     {
9061       errmsg ("l2tp session lookup key unset\n");
9062       return -99;
9063     }
9064
9065   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9066
9067   mp->key = key;
9068
9069   S;
9070   W;
9071   /* NOTREACHED */
9072   return 0;
9073 }
9074
9075 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9076   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9077 {
9078   vat_main_t *vam = &vat_main;
9079
9080   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9081            format_ip6_address, mp->our_address,
9082            format_ip6_address, mp->client_address,
9083            clib_net_to_host_u32 (mp->sw_if_index));
9084
9085   fformat (vam->ofp,
9086            "   local cookies %016llx %016llx remote cookie %016llx\n",
9087            clib_net_to_host_u64 (mp->local_cookie[0]),
9088            clib_net_to_host_u64 (mp->local_cookie[1]),
9089            clib_net_to_host_u64 (mp->remote_cookie));
9090
9091   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9092            clib_net_to_host_u32 (mp->local_session_id),
9093            clib_net_to_host_u32 (mp->remote_session_id));
9094
9095   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9096            mp->l2_sublayer_present ? "preset" : "absent");
9097
9098 }
9099
9100 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9101   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9102 {
9103   vat_main_t *vam = &vat_main;
9104   vat_json_node_t *node = NULL;
9105   struct in6_addr addr;
9106
9107   if (VAT_JSON_ARRAY != vam->json_tree.type)
9108     {
9109       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9110       vat_json_init_array (&vam->json_tree);
9111     }
9112   node = vat_json_array_add (&vam->json_tree);
9113
9114   vat_json_init_object (node);
9115
9116   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9117   vat_json_object_add_ip6 (node, "our_address", addr);
9118   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9119   vat_json_object_add_ip6 (node, "client_address", addr);
9120
9121   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9122   vat_json_init_array (lc);
9123   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9124   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9125   vat_json_object_add_uint (node, "remote_cookie",
9126                             clib_net_to_host_u64 (mp->remote_cookie));
9127
9128   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9129   vat_json_object_add_uint (node, "local_session_id",
9130                             clib_net_to_host_u32 (mp->local_session_id));
9131   vat_json_object_add_uint (node, "remote_session_id",
9132                             clib_net_to_host_u32 (mp->remote_session_id));
9133   vat_json_object_add_string_copy (node, "l2_sublayer",
9134                                    mp->l2_sublayer_present ? (u8 *) "present"
9135                                    : (u8 *) "absent");
9136 }
9137
9138 static int
9139 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9140 {
9141   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9142   f64 timeout;
9143
9144   /* Get list of l2tpv3-tunnel interfaces */
9145   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9146   S;
9147
9148   /* Use a control ping for synchronization */
9149   {
9150     vl_api_control_ping_t *mp;
9151     M (CONTROL_PING, control_ping);
9152     S;
9153   }
9154   W;
9155 }
9156
9157
9158 static void vl_api_sw_interface_tap_details_t_handler
9159   (vl_api_sw_interface_tap_details_t * mp)
9160 {
9161   vat_main_t *vam = &vat_main;
9162
9163   fformat (vam->ofp, "%-16s %d\n",
9164            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9165 }
9166
9167 static void vl_api_sw_interface_tap_details_t_handler_json
9168   (vl_api_sw_interface_tap_details_t * mp)
9169 {
9170   vat_main_t *vam = &vat_main;
9171   vat_json_node_t *node = NULL;
9172
9173   if (VAT_JSON_ARRAY != vam->json_tree.type)
9174     {
9175       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9176       vat_json_init_array (&vam->json_tree);
9177     }
9178   node = vat_json_array_add (&vam->json_tree);
9179
9180   vat_json_init_object (node);
9181   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9182   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9183 }
9184
9185 static int
9186 api_sw_interface_tap_dump (vat_main_t * vam)
9187 {
9188   vl_api_sw_interface_tap_dump_t *mp;
9189   f64 timeout;
9190
9191   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9192   /* Get list of tap interfaces */
9193   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9194   S;
9195
9196   /* Use a control ping for synchronization */
9197   {
9198     vl_api_control_ping_t *mp;
9199     M (CONTROL_PING, control_ping);
9200     S;
9201   }
9202   W;
9203 }
9204
9205 static uword unformat_vxlan_decap_next
9206   (unformat_input_t * input, va_list * args)
9207 {
9208   u32 *result = va_arg (*args, u32 *);
9209   u32 tmp;
9210
9211   if (unformat (input, "drop"))
9212     *result = VXLAN_INPUT_NEXT_DROP;
9213   else if (unformat (input, "ip4"))
9214     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9215   else if (unformat (input, "ip6"))
9216     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9217   else if (unformat (input, "l2"))
9218     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9219   else if (unformat (input, "%d", &tmp))
9220     *result = tmp;
9221   else
9222     return 0;
9223   return 1;
9224 }
9225
9226 static int
9227 api_vxlan_add_del_tunnel (vat_main_t * vam)
9228 {
9229   unformat_input_t *line_input = vam->input;
9230   vl_api_vxlan_add_del_tunnel_t *mp;
9231   f64 timeout;
9232   ip4_address_t src4, dst4;
9233   ip6_address_t src6, dst6;
9234   u8 is_add = 1;
9235   u8 ipv4_set = 0, ipv6_set = 0;
9236   u8 src_set = 0;
9237   u8 dst_set = 0;
9238   u32 encap_vrf_id = 0;
9239   u32 decap_next_index = ~0;
9240   u32 vni = 0;
9241
9242   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9243     {
9244       if (unformat (line_input, "del"))
9245         is_add = 0;
9246       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9247         {
9248           ipv4_set = 1;
9249           src_set = 1;
9250         }
9251       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9252         {
9253           ipv4_set = 1;
9254           dst_set = 1;
9255         }
9256       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9257         {
9258           ipv6_set = 1;
9259           src_set = 1;
9260         }
9261       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9262         {
9263           ipv6_set = 1;
9264           dst_set = 1;
9265         }
9266       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9267         ;
9268       else if (unformat (line_input, "decap-next %U",
9269                          unformat_vxlan_decap_next, &decap_next_index))
9270         ;
9271       else if (unformat (line_input, "vni %d", &vni))
9272         ;
9273       else
9274         {
9275           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9276           return -99;
9277         }
9278     }
9279
9280   if (src_set == 0)
9281     {
9282       errmsg ("tunnel src address not specified\n");
9283       return -99;
9284     }
9285   if (dst_set == 0)
9286     {
9287       errmsg ("tunnel dst address not specified\n");
9288       return -99;
9289     }
9290
9291   if (ipv4_set && ipv6_set)
9292     {
9293       errmsg ("both IPv4 and IPv6 addresses specified");
9294       return -99;
9295     }
9296
9297   if ((vni == 0) || (vni >> 24))
9298     {
9299       errmsg ("vni not specified or out of range\n");
9300       return -99;
9301     }
9302
9303   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9304
9305   if (ipv6_set)
9306     {
9307       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9308       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9309     }
9310   else
9311     {
9312       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9313       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9314     }
9315   mp->encap_vrf_id = ntohl (encap_vrf_id);
9316   mp->decap_next_index = ntohl (decap_next_index);
9317   mp->vni = ntohl (vni);
9318   mp->is_add = is_add;
9319   mp->is_ipv6 = ipv6_set;
9320
9321   S;
9322   W;
9323   /* NOTREACHED */
9324   return 0;
9325 }
9326
9327 static void vl_api_vxlan_tunnel_details_t_handler
9328   (vl_api_vxlan_tunnel_details_t * mp)
9329 {
9330   vat_main_t *vam = &vat_main;
9331
9332   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9333            ntohl (mp->sw_if_index),
9334            format_ip46_address, &(mp->src_address[0]),
9335            IP46_TYPE_ANY,
9336            format_ip46_address, &(mp->dst_address[0]),
9337            IP46_TYPE_ANY,
9338            ntohl (mp->encap_vrf_id),
9339            ntohl (mp->decap_next_index), ntohl (mp->vni));
9340 }
9341
9342 static void vl_api_vxlan_tunnel_details_t_handler_json
9343   (vl_api_vxlan_tunnel_details_t * mp)
9344 {
9345   vat_main_t *vam = &vat_main;
9346   vat_json_node_t *node = NULL;
9347   struct in_addr ip4;
9348   struct in6_addr ip6;
9349
9350   if (VAT_JSON_ARRAY != vam->json_tree.type)
9351     {
9352       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9353       vat_json_init_array (&vam->json_tree);
9354     }
9355   node = vat_json_array_add (&vam->json_tree);
9356
9357   vat_json_init_object (node);
9358   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9359   if (mp->is_ipv6)
9360     {
9361       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9362       vat_json_object_add_ip6 (node, "src_address", ip6);
9363       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9364       vat_json_object_add_ip6 (node, "dst_address", ip6);
9365     }
9366   else
9367     {
9368       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9369       vat_json_object_add_ip4 (node, "src_address", ip4);
9370       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9371       vat_json_object_add_ip4 (node, "dst_address", ip4);
9372     }
9373   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9374   vat_json_object_add_uint (node, "decap_next_index",
9375                             ntohl (mp->decap_next_index));
9376   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9377   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9378 }
9379
9380 static int
9381 api_vxlan_tunnel_dump (vat_main_t * vam)
9382 {
9383   unformat_input_t *i = vam->input;
9384   vl_api_vxlan_tunnel_dump_t *mp;
9385   f64 timeout;
9386   u32 sw_if_index;
9387   u8 sw_if_index_set = 0;
9388
9389   /* Parse args required to build the message */
9390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9391     {
9392       if (unformat (i, "sw_if_index %d", &sw_if_index))
9393         sw_if_index_set = 1;
9394       else
9395         break;
9396     }
9397
9398   if (sw_if_index_set == 0)
9399     {
9400       sw_if_index = ~0;
9401     }
9402
9403   if (!vam->json_output)
9404     {
9405       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9406                "sw_if_index", "src_address", "dst_address",
9407                "encap_vrf_id", "decap_next_index", "vni");
9408     }
9409
9410   /* Get list of vxlan-tunnel interfaces */
9411   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9412
9413   mp->sw_if_index = htonl (sw_if_index);
9414
9415   S;
9416
9417   /* Use a control ping for synchronization */
9418   {
9419     vl_api_control_ping_t *mp;
9420     M (CONTROL_PING, control_ping);
9421     S;
9422   }
9423   W;
9424 }
9425
9426 static int
9427 api_gre_add_del_tunnel (vat_main_t * vam)
9428 {
9429   unformat_input_t *line_input = vam->input;
9430   vl_api_gre_add_del_tunnel_t *mp;
9431   f64 timeout;
9432   ip4_address_t src4, dst4;
9433   u8 is_add = 1;
9434   u8 src_set = 0;
9435   u8 dst_set = 0;
9436   u32 outer_fib_id = 0;
9437
9438   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9439     {
9440       if (unformat (line_input, "del"))
9441         is_add = 0;
9442       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9443         src_set = 1;
9444       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9445         dst_set = 1;
9446       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9447         ;
9448       else
9449         {
9450           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9451           return -99;
9452         }
9453     }
9454
9455   if (src_set == 0)
9456     {
9457       errmsg ("tunnel src address not specified\n");
9458       return -99;
9459     }
9460   if (dst_set == 0)
9461     {
9462       errmsg ("tunnel dst address not specified\n");
9463       return -99;
9464     }
9465
9466
9467   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9468
9469   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9470   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9471   mp->outer_fib_id = ntohl (outer_fib_id);
9472   mp->is_add = is_add;
9473
9474   S;
9475   W;
9476   /* NOTREACHED */
9477   return 0;
9478 }
9479
9480 static void vl_api_gre_tunnel_details_t_handler
9481   (vl_api_gre_tunnel_details_t * mp)
9482 {
9483   vat_main_t *vam = &vat_main;
9484
9485   fformat (vam->ofp, "%11d%15U%15U%14d\n",
9486            ntohl (mp->sw_if_index),
9487            format_ip4_address, &mp->src_address,
9488            format_ip4_address, &mp->dst_address, ntohl (mp->outer_fib_id));
9489 }
9490
9491 static void vl_api_gre_tunnel_details_t_handler_json
9492   (vl_api_gre_tunnel_details_t * mp)
9493 {
9494   vat_main_t *vam = &vat_main;
9495   vat_json_node_t *node = NULL;
9496   struct in_addr ip4;
9497
9498   if (VAT_JSON_ARRAY != vam->json_tree.type)
9499     {
9500       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9501       vat_json_init_array (&vam->json_tree);
9502     }
9503   node = vat_json_array_add (&vam->json_tree);
9504
9505   vat_json_init_object (node);
9506   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9507   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9508   vat_json_object_add_ip4 (node, "src_address", ip4);
9509   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9510   vat_json_object_add_ip4 (node, "dst_address", ip4);
9511   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9512 }
9513
9514 static int
9515 api_gre_tunnel_dump (vat_main_t * vam)
9516 {
9517   unformat_input_t *i = vam->input;
9518   vl_api_gre_tunnel_dump_t *mp;
9519   f64 timeout;
9520   u32 sw_if_index;
9521   u8 sw_if_index_set = 0;
9522
9523   /* Parse args required to build the message */
9524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9525     {
9526       if (unformat (i, "sw_if_index %d", &sw_if_index))
9527         sw_if_index_set = 1;
9528       else
9529         break;
9530     }
9531
9532   if (sw_if_index_set == 0)
9533     {
9534       sw_if_index = ~0;
9535     }
9536
9537   if (!vam->json_output)
9538     {
9539       fformat (vam->ofp, "%11s%15s%15s%14s\n",
9540                "sw_if_index", "src_address", "dst_address", "outer_fib_id");
9541     }
9542
9543   /* Get list of gre-tunnel interfaces */
9544   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9545
9546   mp->sw_if_index = htonl (sw_if_index);
9547
9548   S;
9549
9550   /* Use a control ping for synchronization */
9551   {
9552     vl_api_control_ping_t *mp;
9553     M (CONTROL_PING, control_ping);
9554     S;
9555   }
9556   W;
9557 }
9558
9559 static int
9560 api_l2_fib_clear_table (vat_main_t * vam)
9561 {
9562 //  unformat_input_t * i = vam->input;
9563   vl_api_l2_fib_clear_table_t *mp;
9564   f64 timeout;
9565
9566   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9567
9568   S;
9569   W;
9570   /* NOTREACHED */
9571   return 0;
9572 }
9573
9574 static int
9575 api_l2_interface_efp_filter (vat_main_t * vam)
9576 {
9577   unformat_input_t *i = vam->input;
9578   vl_api_l2_interface_efp_filter_t *mp;
9579   f64 timeout;
9580   u32 sw_if_index;
9581   u8 enable = 1;
9582   u8 sw_if_index_set = 0;
9583
9584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9585     {
9586       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9587         sw_if_index_set = 1;
9588       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9589         sw_if_index_set = 1;
9590       else if (unformat (i, "enable"))
9591         enable = 1;
9592       else if (unformat (i, "disable"))
9593         enable = 0;
9594       else
9595         {
9596           clib_warning ("parse error '%U'", format_unformat_error, i);
9597           return -99;
9598         }
9599     }
9600
9601   if (sw_if_index_set == 0)
9602     {
9603       errmsg ("missing sw_if_index\n");
9604       return -99;
9605     }
9606
9607   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9608
9609   mp->sw_if_index = ntohl (sw_if_index);
9610   mp->enable_disable = enable;
9611
9612   S;
9613   W;
9614   /* NOTREACHED */
9615   return 0;
9616 }
9617
9618 #define foreach_vtr_op                          \
9619 _("disable",  L2_VTR_DISABLED)                  \
9620 _("push-1",  L2_VTR_PUSH_1)                     \
9621 _("push-2",  L2_VTR_PUSH_2)                     \
9622 _("pop-1",  L2_VTR_POP_1)                       \
9623 _("pop-2",  L2_VTR_POP_2)                       \
9624 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9625 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9626 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9627 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9628
9629 static int
9630 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9631 {
9632   unformat_input_t *i = vam->input;
9633   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9634   f64 timeout;
9635   u32 sw_if_index;
9636   u8 sw_if_index_set = 0;
9637   u8 vtr_op_set = 0;
9638   u32 vtr_op = 0;
9639   u32 push_dot1q = 1;
9640   u32 tag1 = ~0;
9641   u32 tag2 = ~0;
9642
9643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9644     {
9645       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9646         sw_if_index_set = 1;
9647       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9648         sw_if_index_set = 1;
9649       else if (unformat (i, "vtr_op %d", &vtr_op))
9650         vtr_op_set = 1;
9651 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9652       foreach_vtr_op
9653 #undef _
9654         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9655         ;
9656       else if (unformat (i, "tag1 %d", &tag1))
9657         ;
9658       else if (unformat (i, "tag2 %d", &tag2))
9659         ;
9660       else
9661         {
9662           clib_warning ("parse error '%U'", format_unformat_error, i);
9663           return -99;
9664         }
9665     }
9666
9667   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9668     {
9669       errmsg ("missing vtr operation or sw_if_index\n");
9670       return -99;
9671     }
9672
9673   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
9674     mp->sw_if_index = ntohl (sw_if_index);
9675   mp->vtr_op = ntohl (vtr_op);
9676   mp->push_dot1q = ntohl (push_dot1q);
9677   mp->tag1 = ntohl (tag1);
9678   mp->tag2 = ntohl (tag2);
9679
9680   S;
9681   W;
9682   /* NOTREACHED */
9683   return 0;
9684 }
9685
9686 static int
9687 api_create_vhost_user_if (vat_main_t * vam)
9688 {
9689   unformat_input_t *i = vam->input;
9690   vl_api_create_vhost_user_if_t *mp;
9691   f64 timeout;
9692   u8 *file_name;
9693   u8 is_server = 0;
9694   u8 file_name_set = 0;
9695   u32 custom_dev_instance = ~0;
9696   u8 hwaddr[6];
9697   u8 use_custom_mac = 0;
9698
9699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9700     {
9701       if (unformat (i, "socket %s", &file_name))
9702         {
9703           file_name_set = 1;
9704         }
9705       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9706         ;
9707       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9708         use_custom_mac = 1;
9709       else if (unformat (i, "server"))
9710         is_server = 1;
9711       else
9712         break;
9713     }
9714
9715   if (file_name_set == 0)
9716     {
9717       errmsg ("missing socket file name\n");
9718       return -99;
9719     }
9720
9721   if (vec_len (file_name) > 255)
9722     {
9723       errmsg ("socket file name too long\n");
9724       return -99;
9725     }
9726   vec_add1 (file_name, 0);
9727
9728   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
9729
9730   mp->is_server = is_server;
9731   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9732   vec_free (file_name);
9733   if (custom_dev_instance != ~0)
9734     {
9735       mp->renumber = 1;
9736       mp->custom_dev_instance = ntohl (custom_dev_instance);
9737     }
9738   mp->use_custom_mac = use_custom_mac;
9739   clib_memcpy (mp->mac_address, hwaddr, 6);
9740
9741   S;
9742   W;
9743   /* NOTREACHED */
9744   return 0;
9745 }
9746
9747 static int
9748 api_modify_vhost_user_if (vat_main_t * vam)
9749 {
9750   unformat_input_t *i = vam->input;
9751   vl_api_modify_vhost_user_if_t *mp;
9752   f64 timeout;
9753   u8 *file_name;
9754   u8 is_server = 0;
9755   u8 file_name_set = 0;
9756   u32 custom_dev_instance = ~0;
9757   u8 sw_if_index_set = 0;
9758   u32 sw_if_index = (u32) ~ 0;
9759
9760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9761     {
9762       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9763         sw_if_index_set = 1;
9764       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9765         sw_if_index_set = 1;
9766       else if (unformat (i, "socket %s", &file_name))
9767         {
9768           file_name_set = 1;
9769         }
9770       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9771         ;
9772       else if (unformat (i, "server"))
9773         is_server = 1;
9774       else
9775         break;
9776     }
9777
9778   if (sw_if_index_set == 0)
9779     {
9780       errmsg ("missing sw_if_index or interface name\n");
9781       return -99;
9782     }
9783
9784   if (file_name_set == 0)
9785     {
9786       errmsg ("missing socket file name\n");
9787       return -99;
9788     }
9789
9790   if (vec_len (file_name) > 255)
9791     {
9792       errmsg ("socket file name too long\n");
9793       return -99;
9794     }
9795   vec_add1 (file_name, 0);
9796
9797   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
9798
9799   mp->sw_if_index = ntohl (sw_if_index);
9800   mp->is_server = is_server;
9801   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9802   vec_free (file_name);
9803   if (custom_dev_instance != ~0)
9804     {
9805       mp->renumber = 1;
9806       mp->custom_dev_instance = ntohl (custom_dev_instance);
9807     }
9808
9809   S;
9810   W;
9811   /* NOTREACHED */
9812   return 0;
9813 }
9814
9815 static int
9816 api_delete_vhost_user_if (vat_main_t * vam)
9817 {
9818   unformat_input_t *i = vam->input;
9819   vl_api_delete_vhost_user_if_t *mp;
9820   f64 timeout;
9821   u32 sw_if_index = ~0;
9822   u8 sw_if_index_set = 0;
9823
9824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9825     {
9826       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9827         sw_if_index_set = 1;
9828       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9829         sw_if_index_set = 1;
9830       else
9831         break;
9832     }
9833
9834   if (sw_if_index_set == 0)
9835     {
9836       errmsg ("missing sw_if_index or interface name\n");
9837       return -99;
9838     }
9839
9840
9841   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
9842
9843   mp->sw_if_index = ntohl (sw_if_index);
9844
9845   S;
9846   W;
9847   /* NOTREACHED */
9848   return 0;
9849 }
9850
9851 static void vl_api_sw_interface_vhost_user_details_t_handler
9852   (vl_api_sw_interface_vhost_user_details_t * mp)
9853 {
9854   vat_main_t *vam = &vat_main;
9855
9856   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
9857            (char *) mp->interface_name,
9858            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
9859            clib_net_to_host_u64 (mp->features), mp->is_server,
9860            ntohl (mp->num_regions), (char *) mp->sock_filename);
9861   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
9862 }
9863
9864 static void vl_api_sw_interface_vhost_user_details_t_handler_json
9865   (vl_api_sw_interface_vhost_user_details_t * mp)
9866 {
9867   vat_main_t *vam = &vat_main;
9868   vat_json_node_t *node = NULL;
9869
9870   if (VAT_JSON_ARRAY != vam->json_tree.type)
9871     {
9872       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9873       vat_json_init_array (&vam->json_tree);
9874     }
9875   node = vat_json_array_add (&vam->json_tree);
9876
9877   vat_json_init_object (node);
9878   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9879   vat_json_object_add_string_copy (node, "interface_name",
9880                                    mp->interface_name);
9881   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
9882                             ntohl (mp->virtio_net_hdr_sz));
9883   vat_json_object_add_uint (node, "features",
9884                             clib_net_to_host_u64 (mp->features));
9885   vat_json_object_add_uint (node, "is_server", mp->is_server);
9886   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
9887   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
9888   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
9889 }
9890
9891 static int
9892 api_sw_interface_vhost_user_dump (vat_main_t * vam)
9893 {
9894   vl_api_sw_interface_vhost_user_dump_t *mp;
9895   f64 timeout;
9896   fformat (vam->ofp,
9897            "Interface name           idx hdr_sz features server regions filename\n");
9898
9899   /* Get list of vhost-user interfaces */
9900   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
9901   S;
9902
9903   /* Use a control ping for synchronization */
9904   {
9905     vl_api_control_ping_t *mp;
9906     M (CONTROL_PING, control_ping);
9907     S;
9908   }
9909   W;
9910 }
9911
9912 static int
9913 api_show_version (vat_main_t * vam)
9914 {
9915   vl_api_show_version_t *mp;
9916   f64 timeout;
9917
9918   M (SHOW_VERSION, show_version);
9919
9920   S;
9921   W;
9922   /* NOTREACHED */
9923   return 0;
9924 }
9925
9926
9927 static int
9928 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
9929 {
9930   unformat_input_t *line_input = vam->input;
9931   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
9932   f64 timeout;
9933   ip4_address_t local4, remote4;
9934   ip6_address_t local6, remote6;
9935   u8 is_add = 1;
9936   u8 ipv4_set = 0, ipv6_set = 0;
9937   u8 local_set = 0;
9938   u8 remote_set = 0;
9939   u32 encap_vrf_id = 0;
9940   u32 decap_vrf_id = 0;
9941   u8 protocol = ~0;
9942   u32 vni;
9943   u8 vni_set = 0;
9944
9945   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9946     {
9947       if (unformat (line_input, "del"))
9948         is_add = 0;
9949       else if (unformat (line_input, "local %U",
9950                          unformat_ip4_address, &local4))
9951         {
9952           local_set = 1;
9953           ipv4_set = 1;
9954         }
9955       else if (unformat (line_input, "remote %U",
9956                          unformat_ip4_address, &remote4))
9957         {
9958           remote_set = 1;
9959           ipv4_set = 1;
9960         }
9961       else if (unformat (line_input, "local %U",
9962                          unformat_ip6_address, &local6))
9963         {
9964           local_set = 1;
9965           ipv6_set = 1;
9966         }
9967       else if (unformat (line_input, "remote %U",
9968                          unformat_ip6_address, &remote6))
9969         {
9970           remote_set = 1;
9971           ipv6_set = 1;
9972         }
9973       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9974         ;
9975       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
9976         ;
9977       else if (unformat (line_input, "vni %d", &vni))
9978         vni_set = 1;
9979       else if (unformat (line_input, "next-ip4"))
9980         protocol = 1;
9981       else if (unformat (line_input, "next-ip6"))
9982         protocol = 2;
9983       else if (unformat (line_input, "next-ethernet"))
9984         protocol = 3;
9985       else if (unformat (line_input, "next-nsh"))
9986         protocol = 4;
9987       else
9988         {
9989           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9990           return -99;
9991         }
9992     }
9993
9994   if (local_set == 0)
9995     {
9996       errmsg ("tunnel local address not specified\n");
9997       return -99;
9998     }
9999   if (remote_set == 0)
10000     {
10001       errmsg ("tunnel remote address not specified\n");
10002       return -99;
10003     }
10004   if (ipv4_set && ipv6_set)
10005     {
10006       errmsg ("both IPv4 and IPv6 addresses specified");
10007       return -99;
10008     }
10009
10010   if (vni_set == 0)
10011     {
10012       errmsg ("vni not specified\n");
10013       return -99;
10014     }
10015
10016   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10017
10018
10019   if (ipv6_set)
10020     {
10021       clib_memcpy (&mp->local, &local6, sizeof (local6));
10022       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10023     }
10024   else
10025     {
10026       clib_memcpy (&mp->local, &local4, sizeof (local4));
10027       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10028     }
10029
10030   mp->encap_vrf_id = ntohl (encap_vrf_id);
10031   mp->decap_vrf_id = ntohl (decap_vrf_id);
10032   mp->protocol = ntohl (protocol);
10033   mp->vni = ntohl (vni);
10034   mp->is_add = is_add;
10035   mp->is_ipv6 = ipv6_set;
10036
10037   S;
10038   W;
10039   /* NOTREACHED */
10040   return 0;
10041 }
10042
10043 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10044   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10045 {
10046   vat_main_t *vam = &vat_main;
10047
10048   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10049            ntohl (mp->sw_if_index),
10050            format_ip46_address, &(mp->local[0]),
10051            format_ip46_address, &(mp->remote[0]),
10052            ntohl (mp->vni),
10053            ntohl (mp->protocol),
10054            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10055 }
10056
10057 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10058   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10059 {
10060   vat_main_t *vam = &vat_main;
10061   vat_json_node_t *node = NULL;
10062   struct in_addr ip4;
10063   struct in6_addr ip6;
10064
10065   if (VAT_JSON_ARRAY != vam->json_tree.type)
10066     {
10067       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10068       vat_json_init_array (&vam->json_tree);
10069     }
10070   node = vat_json_array_add (&vam->json_tree);
10071
10072   vat_json_init_object (node);
10073   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10074   if (mp->is_ipv6)
10075     {
10076       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10077       vat_json_object_add_ip6 (node, "local", ip6);
10078       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10079       vat_json_object_add_ip6 (node, "remote", ip6);
10080     }
10081   else
10082     {
10083       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10084       vat_json_object_add_ip4 (node, "local", ip4);
10085       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10086       vat_json_object_add_ip4 (node, "remote", ip4);
10087     }
10088   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10089   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10090   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10091   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10092   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10093 }
10094
10095 static int
10096 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10097 {
10098   unformat_input_t *i = vam->input;
10099   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10100   f64 timeout;
10101   u32 sw_if_index;
10102   u8 sw_if_index_set = 0;
10103
10104   /* Parse args required to build the message */
10105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10106     {
10107       if (unformat (i, "sw_if_index %d", &sw_if_index))
10108         sw_if_index_set = 1;
10109       else
10110         break;
10111     }
10112
10113   if (sw_if_index_set == 0)
10114     {
10115       sw_if_index = ~0;
10116     }
10117
10118   if (!vam->json_output)
10119     {
10120       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10121                "sw_if_index", "local", "remote", "vni",
10122                "protocol", "encap_vrf_id", "decap_vrf_id");
10123     }
10124
10125   /* Get list of vxlan-tunnel interfaces */
10126   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10127
10128   mp->sw_if_index = htonl (sw_if_index);
10129
10130   S;
10131
10132   /* Use a control ping for synchronization */
10133   {
10134     vl_api_control_ping_t *mp;
10135     M (CONTROL_PING, control_ping);
10136     S;
10137   }
10138   W;
10139 }
10140
10141 u8 *
10142 format_l2_fib_mac_address (u8 * s, va_list * args)
10143 {
10144   u8 *a = va_arg (*args, u8 *);
10145
10146   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10147                  a[2], a[3], a[4], a[5], a[6], a[7]);
10148 }
10149
10150 static void vl_api_l2_fib_table_entry_t_handler
10151   (vl_api_l2_fib_table_entry_t * mp)
10152 {
10153   vat_main_t *vam = &vat_main;
10154
10155   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10156            "       %d       %d     %d\n",
10157            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10158            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10159            mp->bvi_mac);
10160 }
10161
10162 static void vl_api_l2_fib_table_entry_t_handler_json
10163   (vl_api_l2_fib_table_entry_t * mp)
10164 {
10165   vat_main_t *vam = &vat_main;
10166   vat_json_node_t *node = NULL;
10167
10168   if (VAT_JSON_ARRAY != vam->json_tree.type)
10169     {
10170       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10171       vat_json_init_array (&vam->json_tree);
10172     }
10173   node = vat_json_array_add (&vam->json_tree);
10174
10175   vat_json_init_object (node);
10176   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10177   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10178   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10179   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10180   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10181   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10182 }
10183
10184 static int
10185 api_l2_fib_table_dump (vat_main_t * vam)
10186 {
10187   unformat_input_t *i = vam->input;
10188   vl_api_l2_fib_table_dump_t *mp;
10189   f64 timeout;
10190   u32 bd_id;
10191   u8 bd_id_set = 0;
10192
10193   /* Parse args required to build the message */
10194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10195     {
10196       if (unformat (i, "bd_id %d", &bd_id))
10197         bd_id_set = 1;
10198       else
10199         break;
10200     }
10201
10202   if (bd_id_set == 0)
10203     {
10204       errmsg ("missing bridge domain\n");
10205       return -99;
10206     }
10207
10208   fformat (vam->ofp,
10209            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10210
10211   /* Get list of l2 fib entries */
10212   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10213
10214   mp->bd_id = ntohl (bd_id);
10215   S;
10216
10217   /* Use a control ping for synchronization */
10218   {
10219     vl_api_control_ping_t *mp;
10220     M (CONTROL_PING, control_ping);
10221     S;
10222   }
10223   W;
10224 }
10225
10226
10227 static int
10228 api_interface_name_renumber (vat_main_t * vam)
10229 {
10230   unformat_input_t *line_input = vam->input;
10231   vl_api_interface_name_renumber_t *mp;
10232   u32 sw_if_index = ~0;
10233   f64 timeout;
10234   u32 new_show_dev_instance = ~0;
10235
10236   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10237     {
10238       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10239                     &sw_if_index))
10240         ;
10241       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10242         ;
10243       else if (unformat (line_input, "new_show_dev_instance %d",
10244                          &new_show_dev_instance))
10245         ;
10246       else
10247         break;
10248     }
10249
10250   if (sw_if_index == ~0)
10251     {
10252       errmsg ("missing interface name or sw_if_index\n");
10253       return -99;
10254     }
10255
10256   if (new_show_dev_instance == ~0)
10257     {
10258       errmsg ("missing new_show_dev_instance\n");
10259       return -99;
10260     }
10261
10262   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10263
10264   mp->sw_if_index = ntohl (sw_if_index);
10265   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10266
10267   S;
10268   W;
10269 }
10270
10271 static int
10272 api_want_ip4_arp_events (vat_main_t * vam)
10273 {
10274   unformat_input_t *line_input = vam->input;
10275   vl_api_want_ip4_arp_events_t *mp;
10276   f64 timeout;
10277   ip4_address_t address;
10278   int address_set = 0;
10279   u32 enable_disable = 1;
10280
10281   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10282     {
10283       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10284         address_set = 1;
10285       else if (unformat (line_input, "del"))
10286         enable_disable = 0;
10287       else
10288         break;
10289     }
10290
10291   if (address_set == 0)
10292     {
10293       errmsg ("missing addresses\n");
10294       return -99;
10295     }
10296
10297   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10298   mp->enable_disable = enable_disable;
10299   mp->pid = getpid ();
10300   mp->address = address.as_u32;
10301
10302   S;
10303   W;
10304 }
10305
10306 static int
10307 api_want_ip6_nd_events (vat_main_t * vam)
10308 {
10309   unformat_input_t *line_input = vam->input;
10310   vl_api_want_ip6_nd_events_t *mp;
10311   f64 timeout;
10312   ip6_address_t address;
10313   int address_set = 0;
10314   u32 enable_disable = 1;
10315
10316   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10317     {
10318       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
10319         address_set = 1;
10320       else if (unformat (line_input, "del"))
10321         enable_disable = 0;
10322       else
10323         break;
10324     }
10325
10326   if (address_set == 0)
10327     {
10328       errmsg ("missing addresses\n");
10329       return -99;
10330     }
10331
10332   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
10333   mp->enable_disable = enable_disable;
10334   mp->pid = getpid ();
10335   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
10336
10337   S;
10338   W;
10339 }
10340
10341 static int
10342 api_input_acl_set_interface (vat_main_t * vam)
10343 {
10344   unformat_input_t *i = vam->input;
10345   vl_api_input_acl_set_interface_t *mp;
10346   f64 timeout;
10347   u32 sw_if_index;
10348   int sw_if_index_set;
10349   u32 ip4_table_index = ~0;
10350   u32 ip6_table_index = ~0;
10351   u32 l2_table_index = ~0;
10352   u8 is_add = 1;
10353
10354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10355     {
10356       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10357         sw_if_index_set = 1;
10358       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10359         sw_if_index_set = 1;
10360       else if (unformat (i, "del"))
10361         is_add = 0;
10362       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10363         ;
10364       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10365         ;
10366       else if (unformat (i, "l2-table %d", &l2_table_index))
10367         ;
10368       else
10369         {
10370           clib_warning ("parse error '%U'", format_unformat_error, i);
10371           return -99;
10372         }
10373     }
10374
10375   if (sw_if_index_set == 0)
10376     {
10377       errmsg ("missing interface name or sw_if_index\n");
10378       return -99;
10379     }
10380
10381   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10382
10383   mp->sw_if_index = ntohl (sw_if_index);
10384   mp->ip4_table_index = ntohl (ip4_table_index);
10385   mp->ip6_table_index = ntohl (ip6_table_index);
10386   mp->l2_table_index = ntohl (l2_table_index);
10387   mp->is_add = is_add;
10388
10389   S;
10390   W;
10391   /* NOTREACHED */
10392   return 0;
10393 }
10394
10395 static int
10396 api_ip_address_dump (vat_main_t * vam)
10397 {
10398   unformat_input_t *i = vam->input;
10399   vl_api_ip_address_dump_t *mp;
10400   u32 sw_if_index = ~0;
10401   u8 sw_if_index_set = 0;
10402   u8 ipv4_set = 0;
10403   u8 ipv6_set = 0;
10404   f64 timeout;
10405
10406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10407     {
10408       if (unformat (i, "sw_if_index %d", &sw_if_index))
10409         sw_if_index_set = 1;
10410       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10411         sw_if_index_set = 1;
10412       else if (unformat (i, "ipv4"))
10413         ipv4_set = 1;
10414       else if (unformat (i, "ipv6"))
10415         ipv6_set = 1;
10416       else
10417         break;
10418     }
10419
10420   if (ipv4_set && ipv6_set)
10421     {
10422       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10423       return -99;
10424     }
10425
10426   if ((!ipv4_set) && (!ipv6_set))
10427     {
10428       errmsg ("no ipv4 nor ipv6 flag set\n");
10429       return -99;
10430     }
10431
10432   if (sw_if_index_set == 0)
10433     {
10434       errmsg ("missing interface name or sw_if_index\n");
10435       return -99;
10436     }
10437
10438   vam->current_sw_if_index = sw_if_index;
10439   vam->is_ipv6 = ipv6_set;
10440
10441   M (IP_ADDRESS_DUMP, ip_address_dump);
10442   mp->sw_if_index = ntohl (sw_if_index);
10443   mp->is_ipv6 = ipv6_set;
10444   S;
10445
10446   /* Use a control ping for synchronization */
10447   {
10448     vl_api_control_ping_t *mp;
10449     M (CONTROL_PING, control_ping);
10450     S;
10451   }
10452   W;
10453 }
10454
10455 static int
10456 api_ip_dump (vat_main_t * vam)
10457 {
10458   vl_api_ip_dump_t *mp;
10459   unformat_input_t *in = vam->input;
10460   int ipv4_set = 0;
10461   int ipv6_set = 0;
10462   int is_ipv6;
10463   f64 timeout;
10464   int i;
10465
10466   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10467     {
10468       if (unformat (in, "ipv4"))
10469         ipv4_set = 1;
10470       else if (unformat (in, "ipv6"))
10471         ipv6_set = 1;
10472       else
10473         break;
10474     }
10475
10476   if (ipv4_set && ipv6_set)
10477     {
10478       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10479       return -99;
10480     }
10481
10482   if ((!ipv4_set) && (!ipv6_set))
10483     {
10484       errmsg ("no ipv4 nor ipv6 flag set\n");
10485       return -99;
10486     }
10487
10488   is_ipv6 = ipv6_set;
10489   vam->is_ipv6 = is_ipv6;
10490
10491   /* free old data */
10492   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10493     {
10494       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10495     }
10496   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10497
10498   M (IP_DUMP, ip_dump);
10499   mp->is_ipv6 = ipv6_set;
10500   S;
10501
10502   /* Use a control ping for synchronization */
10503   {
10504     vl_api_control_ping_t *mp;
10505     M (CONTROL_PING, control_ping);
10506     S;
10507   }
10508   W;
10509 }
10510
10511 static int
10512 api_ipsec_spd_add_del (vat_main_t * vam)
10513 {
10514 #if DPDK > 0
10515   unformat_input_t *i = vam->input;
10516   vl_api_ipsec_spd_add_del_t *mp;
10517   f64 timeout;
10518   u32 spd_id = ~0;
10519   u8 is_add = 1;
10520
10521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10522     {
10523       if (unformat (i, "spd_id %d", &spd_id))
10524         ;
10525       else if (unformat (i, "del"))
10526         is_add = 0;
10527       else
10528         {
10529           clib_warning ("parse error '%U'", format_unformat_error, i);
10530           return -99;
10531         }
10532     }
10533   if (spd_id == ~0)
10534     {
10535       errmsg ("spd_id must be set\n");
10536       return -99;
10537     }
10538
10539   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10540
10541   mp->spd_id = ntohl (spd_id);
10542   mp->is_add = is_add;
10543
10544   S;
10545   W;
10546   /* NOTREACHED */
10547   return 0;
10548 #else
10549   clib_warning ("unsupported (no dpdk)");
10550   return -99;
10551 #endif
10552 }
10553
10554 static int
10555 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10556 {
10557 #if DPDK > 0
10558   unformat_input_t *i = vam->input;
10559   vl_api_ipsec_interface_add_del_spd_t *mp;
10560   f64 timeout;
10561   u32 sw_if_index;
10562   u8 sw_if_index_set = 0;
10563   u32 spd_id = (u32) ~ 0;
10564   u8 is_add = 1;
10565
10566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10567     {
10568       if (unformat (i, "del"))
10569         is_add = 0;
10570       else if (unformat (i, "spd_id %d", &spd_id))
10571         ;
10572       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10573         sw_if_index_set = 1;
10574       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10575         sw_if_index_set = 1;
10576       else
10577         {
10578           clib_warning ("parse error '%U'", format_unformat_error, i);
10579           return -99;
10580         }
10581
10582     }
10583
10584   if (spd_id == (u32) ~ 0)
10585     {
10586       errmsg ("spd_id must be set\n");
10587       return -99;
10588     }
10589
10590   if (sw_if_index_set == 0)
10591     {
10592       errmsg ("missing interface name or sw_if_index\n");
10593       return -99;
10594     }
10595
10596   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10597
10598   mp->spd_id = ntohl (spd_id);
10599   mp->sw_if_index = ntohl (sw_if_index);
10600   mp->is_add = is_add;
10601
10602   S;
10603   W;
10604   /* NOTREACHED */
10605   return 0;
10606 #else
10607   clib_warning ("unsupported (no dpdk)");
10608   return -99;
10609 #endif
10610 }
10611
10612 static int
10613 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10614 {
10615 #if DPDK > 0
10616   unformat_input_t *i = vam->input;
10617   vl_api_ipsec_spd_add_del_entry_t *mp;
10618   f64 timeout;
10619   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10620   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10621   i32 priority = 0;
10622   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10623   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10624   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10625   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10626
10627   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10628   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10629   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10630   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10631   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10632   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10633
10634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10635     {
10636       if (unformat (i, "del"))
10637         is_add = 0;
10638       if (unformat (i, "outbound"))
10639         is_outbound = 1;
10640       if (unformat (i, "inbound"))
10641         is_outbound = 0;
10642       else if (unformat (i, "spd_id %d", &spd_id))
10643         ;
10644       else if (unformat (i, "sa_id %d", &sa_id))
10645         ;
10646       else if (unformat (i, "priority %d", &priority))
10647         ;
10648       else if (unformat (i, "protocol %d", &protocol))
10649         ;
10650       else if (unformat (i, "lport_start %d", &lport_start))
10651         ;
10652       else if (unformat (i, "lport_stop %d", &lport_stop))
10653         ;
10654       else if (unformat (i, "rport_start %d", &rport_start))
10655         ;
10656       else if (unformat (i, "rport_stop %d", &rport_stop))
10657         ;
10658       else
10659         if (unformat
10660             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10661         {
10662           is_ipv6 = 0;
10663           is_ip_any = 0;
10664         }
10665       else
10666         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10667         {
10668           is_ipv6 = 0;
10669           is_ip_any = 0;
10670         }
10671       else
10672         if (unformat
10673             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
10674         {
10675           is_ipv6 = 0;
10676           is_ip_any = 0;
10677         }
10678       else
10679         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
10680         {
10681           is_ipv6 = 0;
10682           is_ip_any = 0;
10683         }
10684       else
10685         if (unformat
10686             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
10687         {
10688           is_ipv6 = 1;
10689           is_ip_any = 0;
10690         }
10691       else
10692         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
10693         {
10694           is_ipv6 = 1;
10695           is_ip_any = 0;
10696         }
10697       else
10698         if (unformat
10699             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
10700         {
10701           is_ipv6 = 1;
10702           is_ip_any = 0;
10703         }
10704       else
10705         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
10706         {
10707           is_ipv6 = 1;
10708           is_ip_any = 0;
10709         }
10710       else
10711         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10712         {
10713           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10714             {
10715               clib_warning ("unsupported action: 'resolve'");
10716               return -99;
10717             }
10718         }
10719       else
10720         {
10721           clib_warning ("parse error '%U'", format_unformat_error, i);
10722           return -99;
10723         }
10724
10725     }
10726
10727   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
10728
10729   mp->spd_id = ntohl (spd_id);
10730   mp->priority = ntohl (priority);
10731   mp->is_outbound = is_outbound;
10732
10733   mp->is_ipv6 = is_ipv6;
10734   if (is_ipv6 || is_ip_any)
10735     {
10736       clib_memcpy (mp->remote_address_start, &raddr6_start,
10737                    sizeof (ip6_address_t));
10738       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
10739                    sizeof (ip6_address_t));
10740       clib_memcpy (mp->local_address_start, &laddr6_start,
10741                    sizeof (ip6_address_t));
10742       clib_memcpy (mp->local_address_stop, &laddr6_stop,
10743                    sizeof (ip6_address_t));
10744     }
10745   else
10746     {
10747       clib_memcpy (mp->remote_address_start, &raddr4_start,
10748                    sizeof (ip4_address_t));
10749       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
10750                    sizeof (ip4_address_t));
10751       clib_memcpy (mp->local_address_start, &laddr4_start,
10752                    sizeof (ip4_address_t));
10753       clib_memcpy (mp->local_address_stop, &laddr4_stop,
10754                    sizeof (ip4_address_t));
10755     }
10756   mp->protocol = (u8) protocol;
10757   mp->local_port_start = ntohs ((u16) lport_start);
10758   mp->local_port_stop = ntohs ((u16) lport_stop);
10759   mp->remote_port_start = ntohs ((u16) rport_start);
10760   mp->remote_port_stop = ntohs ((u16) rport_stop);
10761   mp->policy = (u8) policy;
10762   mp->sa_id = ntohl (sa_id);
10763   mp->is_add = is_add;
10764   mp->is_ip_any = is_ip_any;
10765   S;
10766   W;
10767   /* NOTREACHED */
10768   return 0;
10769 #else
10770   clib_warning ("unsupported (no dpdk)");
10771   return -99;
10772 #endif
10773 }
10774
10775 static int
10776 api_ipsec_sad_add_del_entry (vat_main_t * vam)
10777 {
10778 #if DPDK > 0
10779   unformat_input_t *i = vam->input;
10780   vl_api_ipsec_sad_add_del_entry_t *mp;
10781   f64 timeout;
10782   u32 sad_id = 0, spi = 0;
10783   u8 *ck = 0, *ik = 0;
10784   u8 is_add = 1;
10785
10786   u8 protocol = IPSEC_PROTOCOL_AH;
10787   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
10788   u32 crypto_alg = 0, integ_alg = 0;
10789   ip4_address_t tun_src4;
10790   ip4_address_t tun_dst4;
10791   ip6_address_t tun_src6;
10792   ip6_address_t tun_dst6;
10793
10794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10795     {
10796       if (unformat (i, "del"))
10797         is_add = 0;
10798       else if (unformat (i, "sad_id %d", &sad_id))
10799         ;
10800       else if (unformat (i, "spi %d", &spi))
10801         ;
10802       else if (unformat (i, "esp"))
10803         protocol = IPSEC_PROTOCOL_ESP;
10804       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
10805         {
10806           is_tunnel = 1;
10807           is_tunnel_ipv6 = 0;
10808         }
10809       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
10810         {
10811           is_tunnel = 1;
10812           is_tunnel_ipv6 = 0;
10813         }
10814       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
10815         {
10816           is_tunnel = 1;
10817           is_tunnel_ipv6 = 1;
10818         }
10819       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
10820         {
10821           is_tunnel = 1;
10822           is_tunnel_ipv6 = 1;
10823         }
10824       else
10825         if (unformat
10826             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
10827         {
10828           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
10829               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
10830             {
10831               clib_warning ("unsupported crypto-alg: '%U'",
10832                             format_ipsec_crypto_alg, crypto_alg);
10833               return -99;
10834             }
10835         }
10836       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10837         ;
10838       else
10839         if (unformat
10840             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
10841         {
10842           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
10843               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
10844             {
10845               clib_warning ("unsupported integ-alg: '%U'",
10846                             format_ipsec_integ_alg, integ_alg);
10847               return -99;
10848             }
10849         }
10850       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10851         ;
10852       else
10853         {
10854           clib_warning ("parse error '%U'", format_unformat_error, i);
10855           return -99;
10856         }
10857
10858     }
10859
10860   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
10861
10862   mp->sad_id = ntohl (sad_id);
10863   mp->is_add = is_add;
10864   mp->protocol = protocol;
10865   mp->spi = ntohl (spi);
10866   mp->is_tunnel = is_tunnel;
10867   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
10868   mp->crypto_algorithm = crypto_alg;
10869   mp->integrity_algorithm = integ_alg;
10870   mp->crypto_key_length = vec_len (ck);
10871   mp->integrity_key_length = vec_len (ik);
10872
10873   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10874     mp->crypto_key_length = sizeof (mp->crypto_key);
10875
10876   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10877     mp->integrity_key_length = sizeof (mp->integrity_key);
10878
10879   if (ck)
10880     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10881   if (ik)
10882     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10883
10884   if (is_tunnel)
10885     {
10886       if (is_tunnel_ipv6)
10887         {
10888           clib_memcpy (mp->tunnel_src_address, &tun_src6,
10889                        sizeof (ip6_address_t));
10890           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
10891                        sizeof (ip6_address_t));
10892         }
10893       else
10894         {
10895           clib_memcpy (mp->tunnel_src_address, &tun_src4,
10896                        sizeof (ip4_address_t));
10897           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
10898                        sizeof (ip4_address_t));
10899         }
10900     }
10901
10902   S;
10903   W;
10904   /* NOTREACHED */
10905   return 0;
10906 #else
10907   clib_warning ("unsupported (no dpdk)");
10908   return -99;
10909 #endif
10910 }
10911
10912 static int
10913 api_ipsec_sa_set_key (vat_main_t * vam)
10914 {
10915 #if DPDK > 0
10916   unformat_input_t *i = vam->input;
10917   vl_api_ipsec_sa_set_key_t *mp;
10918   f64 timeout;
10919   u32 sa_id;
10920   u8 *ck = 0, *ik = 0;
10921
10922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10923     {
10924       if (unformat (i, "sa_id %d", &sa_id))
10925         ;
10926       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10927         ;
10928       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10929         ;
10930       else
10931         {
10932           clib_warning ("parse error '%U'", format_unformat_error, i);
10933           return -99;
10934         }
10935     }
10936
10937   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
10938
10939   mp->sa_id = ntohl (sa_id);
10940   mp->crypto_key_length = vec_len (ck);
10941   mp->integrity_key_length = vec_len (ik);
10942
10943   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10944     mp->crypto_key_length = sizeof (mp->crypto_key);
10945
10946   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10947     mp->integrity_key_length = sizeof (mp->integrity_key);
10948
10949   if (ck)
10950     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10951   if (ik)
10952     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10953
10954   S;
10955   W;
10956   /* NOTREACHED */
10957   return 0;
10958 #else
10959   clib_warning ("unsupported (no dpdk)");
10960   return -99;
10961 #endif
10962 }
10963
10964 static int
10965 api_ikev2_profile_add_del (vat_main_t * vam)
10966 {
10967 #if DPDK > 0
10968   unformat_input_t *i = vam->input;
10969   vl_api_ikev2_profile_add_del_t *mp;
10970   f64 timeout;
10971   u8 is_add = 1;
10972   u8 *name = 0;
10973
10974   const char *valid_chars = "a-zA-Z0-9_";
10975
10976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10977     {
10978       if (unformat (i, "del"))
10979         is_add = 0;
10980       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10981         vec_add1 (name, 0);
10982       else
10983         {
10984           errmsg ("parse error '%U'", format_unformat_error, i);
10985           return -99;
10986         }
10987     }
10988
10989   if (!vec_len (name))
10990     {
10991       errmsg ("profile name must be specified");
10992       return -99;
10993     }
10994
10995   if (vec_len (name) > 64)
10996     {
10997       errmsg ("profile name too long");
10998       return -99;
10999     }
11000
11001   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11002
11003   clib_memcpy (mp->name, name, vec_len (name));
11004   mp->is_add = is_add;
11005   vec_free (name);
11006
11007   S;
11008   W;
11009   /* NOTREACHED */
11010   return 0;
11011 #else
11012   clib_warning ("unsupported (no dpdk)");
11013   return -99;
11014 #endif
11015 }
11016
11017 static int
11018 api_ikev2_profile_set_auth (vat_main_t * vam)
11019 {
11020 #if DPDK > 0
11021   unformat_input_t *i = vam->input;
11022   vl_api_ikev2_profile_set_auth_t *mp;
11023   f64 timeout;
11024   u8 *name = 0;
11025   u8 *data = 0;
11026   u32 auth_method = 0;
11027   u8 is_hex = 0;
11028
11029   const char *valid_chars = "a-zA-Z0-9_";
11030
11031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11032     {
11033       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11034         vec_add1 (name, 0);
11035       else if (unformat (i, "auth_method %U",
11036                          unformat_ikev2_auth_method, &auth_method))
11037         ;
11038       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11039         is_hex = 1;
11040       else if (unformat (i, "auth_data %v", &data))
11041         ;
11042       else
11043         {
11044           errmsg ("parse error '%U'", format_unformat_error, i);
11045           return -99;
11046         }
11047     }
11048
11049   if (!vec_len (name))
11050     {
11051       errmsg ("profile name must be specified");
11052       return -99;
11053     }
11054
11055   if (vec_len (name) > 64)
11056     {
11057       errmsg ("profile name too long");
11058       return -99;
11059     }
11060
11061   if (!vec_len (data))
11062     {
11063       errmsg ("auth_data must be specified");
11064       return -99;
11065     }
11066
11067   if (!auth_method)
11068     {
11069       errmsg ("auth_method must be specified");
11070       return -99;
11071     }
11072
11073   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11074
11075   mp->is_hex = is_hex;
11076   mp->auth_method = (u8) auth_method;
11077   mp->data_len = vec_len (data);
11078   clib_memcpy (mp->name, name, vec_len (name));
11079   clib_memcpy (mp->data, data, vec_len (data));
11080   vec_free (name);
11081   vec_free (data);
11082
11083   S;
11084   W;
11085   /* NOTREACHED */
11086   return 0;
11087 #else
11088   clib_warning ("unsupported (no dpdk)");
11089   return -99;
11090 #endif
11091 }
11092
11093 static int
11094 api_ikev2_profile_set_id (vat_main_t * vam)
11095 {
11096 #if DPDK > 0
11097   unformat_input_t *i = vam->input;
11098   vl_api_ikev2_profile_set_id_t *mp;
11099   f64 timeout;
11100   u8 *name = 0;
11101   u8 *data = 0;
11102   u8 is_local = 0;
11103   u32 id_type = 0;
11104   ip4_address_t ip4;
11105
11106   const char *valid_chars = "a-zA-Z0-9_";
11107
11108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11109     {
11110       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11111         vec_add1 (name, 0);
11112       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11113         ;
11114       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11115         {
11116           data = vec_new (u8, 4);
11117           clib_memcpy (data, ip4.as_u8, 4);
11118         }
11119       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11120         ;
11121       else if (unformat (i, "id_data %v", &data))
11122         ;
11123       else if (unformat (i, "local"))
11124         is_local = 1;
11125       else if (unformat (i, "remote"))
11126         is_local = 0;
11127       else
11128         {
11129           errmsg ("parse error '%U'", format_unformat_error, i);
11130           return -99;
11131         }
11132     }
11133
11134   if (!vec_len (name))
11135     {
11136       errmsg ("profile name must be specified");
11137       return -99;
11138     }
11139
11140   if (vec_len (name) > 64)
11141     {
11142       errmsg ("profile name too long");
11143       return -99;
11144     }
11145
11146   if (!vec_len (data))
11147     {
11148       errmsg ("id_data must be specified");
11149       return -99;
11150     }
11151
11152   if (!id_type)
11153     {
11154       errmsg ("id_type must be specified");
11155       return -99;
11156     }
11157
11158   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11159
11160   mp->is_local = is_local;
11161   mp->id_type = (u8) id_type;
11162   mp->data_len = vec_len (data);
11163   clib_memcpy (mp->name, name, vec_len (name));
11164   clib_memcpy (mp->data, data, vec_len (data));
11165   vec_free (name);
11166   vec_free (data);
11167
11168   S;
11169   W;
11170   /* NOTREACHED */
11171   return 0;
11172 #else
11173   clib_warning ("unsupported (no dpdk)");
11174   return -99;
11175 #endif
11176 }
11177
11178 static int
11179 api_ikev2_profile_set_ts (vat_main_t * vam)
11180 {
11181 #if DPDK > 0
11182   unformat_input_t *i = vam->input;
11183   vl_api_ikev2_profile_set_ts_t *mp;
11184   f64 timeout;
11185   u8 *name = 0;
11186   u8 is_local = 0;
11187   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11188   ip4_address_t start_addr, end_addr;
11189
11190   const char *valid_chars = "a-zA-Z0-9_";
11191
11192   start_addr.as_u32 = 0;
11193   end_addr.as_u32 = (u32) ~ 0;
11194
11195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11196     {
11197       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11198         vec_add1 (name, 0);
11199       else if (unformat (i, "protocol %d", &proto))
11200         ;
11201       else if (unformat (i, "start_port %d", &start_port))
11202         ;
11203       else if (unformat (i, "end_port %d", &end_port))
11204         ;
11205       else
11206         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11207         ;
11208       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11209         ;
11210       else if (unformat (i, "local"))
11211         is_local = 1;
11212       else if (unformat (i, "remote"))
11213         is_local = 0;
11214       else
11215         {
11216           errmsg ("parse error '%U'", format_unformat_error, i);
11217           return -99;
11218         }
11219     }
11220
11221   if (!vec_len (name))
11222     {
11223       errmsg ("profile name must be specified");
11224       return -99;
11225     }
11226
11227   if (vec_len (name) > 64)
11228     {
11229       errmsg ("profile name too long");
11230       return -99;
11231     }
11232
11233   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11234
11235   mp->is_local = is_local;
11236   mp->proto = (u8) proto;
11237   mp->start_port = (u16) start_port;
11238   mp->end_port = (u16) end_port;
11239   mp->start_addr = start_addr.as_u32;
11240   mp->end_addr = end_addr.as_u32;
11241   clib_memcpy (mp->name, name, vec_len (name));
11242   vec_free (name);
11243
11244   S;
11245   W;
11246   /* NOTREACHED */
11247   return 0;
11248 #else
11249   clib_warning ("unsupported (no dpdk)");
11250   return -99;
11251 #endif
11252 }
11253
11254 static int
11255 api_ikev2_set_local_key (vat_main_t * vam)
11256 {
11257 #if DPDK > 0
11258   unformat_input_t *i = vam->input;
11259   vl_api_ikev2_set_local_key_t *mp;
11260   f64 timeout;
11261   u8 *file = 0;
11262
11263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11264     {
11265       if (unformat (i, "file %v", &file))
11266         vec_add1 (file, 0);
11267       else
11268         {
11269           errmsg ("parse error '%U'", format_unformat_error, i);
11270           return -99;
11271         }
11272     }
11273
11274   if (!vec_len (file))
11275     {
11276       errmsg ("RSA key file must be specified");
11277       return -99;
11278     }
11279
11280   if (vec_len (file) > 256)
11281     {
11282       errmsg ("file name too long");
11283       return -99;
11284     }
11285
11286   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11287
11288   clib_memcpy (mp->key_file, file, vec_len (file));
11289   vec_free (file);
11290
11291   S;
11292   W;
11293   /* NOTREACHED */
11294   return 0;
11295 #else
11296   clib_warning ("unsupported (no dpdk)");
11297   return -99;
11298 #endif
11299 }
11300
11301 /*
11302  * MAP
11303  */
11304 static int
11305 api_map_add_domain (vat_main_t * vam)
11306 {
11307   unformat_input_t *i = vam->input;
11308   vl_api_map_add_domain_t *mp;
11309   f64 timeout;
11310
11311   ip4_address_t ip4_prefix;
11312   ip6_address_t ip6_prefix;
11313   ip6_address_t ip6_src;
11314   u32 num_m_args = 0;
11315   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11316     0, psid_length = 0;
11317   u8 is_translation = 0;
11318   u32 mtu = 0;
11319   u32 ip6_src_len = 128;
11320
11321   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11322     {
11323       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11324                     &ip4_prefix, &ip4_prefix_len))
11325         num_m_args++;
11326       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11327                          &ip6_prefix, &ip6_prefix_len))
11328         num_m_args++;
11329       else
11330         if (unformat
11331             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11332              &ip6_src_len))
11333         num_m_args++;
11334       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11335         num_m_args++;
11336       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11337         num_m_args++;
11338       else if (unformat (i, "psid-offset %d", &psid_offset))
11339         num_m_args++;
11340       else if (unformat (i, "psid-len %d", &psid_length))
11341         num_m_args++;
11342       else if (unformat (i, "mtu %d", &mtu))
11343         num_m_args++;
11344       else if (unformat (i, "map-t"))
11345         is_translation = 1;
11346       else
11347         {
11348           clib_warning ("parse error '%U'", format_unformat_error, i);
11349           return -99;
11350         }
11351     }
11352
11353   if (num_m_args < 3)
11354     {
11355       errmsg ("mandatory argument(s) missing\n");
11356       return -99;
11357     }
11358
11359   /* Construct the API message */
11360   M (MAP_ADD_DOMAIN, map_add_domain);
11361
11362   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11363   mp->ip4_prefix_len = ip4_prefix_len;
11364
11365   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11366   mp->ip6_prefix_len = ip6_prefix_len;
11367
11368   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11369   mp->ip6_src_prefix_len = ip6_src_len;
11370
11371   mp->ea_bits_len = ea_bits_len;
11372   mp->psid_offset = psid_offset;
11373   mp->psid_length = psid_length;
11374   mp->is_translation = is_translation;
11375   mp->mtu = htons (mtu);
11376
11377   /* send it... */
11378   S;
11379
11380   /* Wait for a reply, return good/bad news  */
11381   W;
11382 }
11383
11384 static int
11385 api_map_del_domain (vat_main_t * vam)
11386 {
11387   unformat_input_t *i = vam->input;
11388   vl_api_map_del_domain_t *mp;
11389   f64 timeout;
11390
11391   u32 num_m_args = 0;
11392   u32 index;
11393
11394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11395     {
11396       if (unformat (i, "index %d", &index))
11397         num_m_args++;
11398       else
11399         {
11400           clib_warning ("parse error '%U'", format_unformat_error, i);
11401           return -99;
11402         }
11403     }
11404
11405   if (num_m_args != 1)
11406     {
11407       errmsg ("mandatory argument(s) missing\n");
11408       return -99;
11409     }
11410
11411   /* Construct the API message */
11412   M (MAP_DEL_DOMAIN, map_del_domain);
11413
11414   mp->index = ntohl (index);
11415
11416   /* send it... */
11417   S;
11418
11419   /* Wait for a reply, return good/bad news  */
11420   W;
11421 }
11422
11423 static int
11424 api_map_add_del_rule (vat_main_t * vam)
11425 {
11426   unformat_input_t *i = vam->input;
11427   vl_api_map_add_del_rule_t *mp;
11428   f64 timeout;
11429   u8 is_add = 1;
11430   ip6_address_t ip6_dst;
11431   u32 num_m_args = 0, index, psid = 0;
11432
11433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11434     {
11435       if (unformat (i, "index %d", &index))
11436         num_m_args++;
11437       else if (unformat (i, "psid %d", &psid))
11438         num_m_args++;
11439       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11440         num_m_args++;
11441       else if (unformat (i, "del"))
11442         {
11443           is_add = 0;
11444         }
11445       else
11446         {
11447           clib_warning ("parse error '%U'", format_unformat_error, i);
11448           return -99;
11449         }
11450     }
11451
11452   /* Construct the API message */
11453   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11454
11455   mp->index = ntohl (index);
11456   mp->is_add = is_add;
11457   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11458   mp->psid = ntohs (psid);
11459
11460   /* send it... */
11461   S;
11462
11463   /* Wait for a reply, return good/bad news  */
11464   W;
11465 }
11466
11467 static int
11468 api_map_domain_dump (vat_main_t * vam)
11469 {
11470   vl_api_map_domain_dump_t *mp;
11471   f64 timeout;
11472
11473   /* Construct the API message */
11474   M (MAP_DOMAIN_DUMP, map_domain_dump);
11475
11476   /* send it... */
11477   S;
11478
11479   /* Use a control ping for synchronization */
11480   {
11481     vl_api_control_ping_t *mp;
11482     M (CONTROL_PING, control_ping);
11483     S;
11484   }
11485   W;
11486 }
11487
11488 static int
11489 api_map_rule_dump (vat_main_t * vam)
11490 {
11491   unformat_input_t *i = vam->input;
11492   vl_api_map_rule_dump_t *mp;
11493   f64 timeout;
11494   u32 domain_index = ~0;
11495
11496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11497     {
11498       if (unformat (i, "index %u", &domain_index))
11499         ;
11500       else
11501         break;
11502     }
11503
11504   if (domain_index == ~0)
11505     {
11506       clib_warning ("parse error: domain index expected");
11507       return -99;
11508     }
11509
11510   /* Construct the API message */
11511   M (MAP_RULE_DUMP, map_rule_dump);
11512
11513   mp->domain_index = htonl (domain_index);
11514
11515   /* send it... */
11516   S;
11517
11518   /* Use a control ping for synchronization */
11519   {
11520     vl_api_control_ping_t *mp;
11521     M (CONTROL_PING, control_ping);
11522     S;
11523   }
11524   W;
11525 }
11526
11527 static void vl_api_map_add_domain_reply_t_handler
11528   (vl_api_map_add_domain_reply_t * mp)
11529 {
11530   vat_main_t *vam = &vat_main;
11531   i32 retval = ntohl (mp->retval);
11532
11533   if (vam->async_mode)
11534     {
11535       vam->async_errors += (retval < 0);
11536     }
11537   else
11538     {
11539       vam->retval = retval;
11540       vam->result_ready = 1;
11541     }
11542 }
11543
11544 static void vl_api_map_add_domain_reply_t_handler_json
11545   (vl_api_map_add_domain_reply_t * mp)
11546 {
11547   vat_main_t *vam = &vat_main;
11548   vat_json_node_t node;
11549
11550   vat_json_init_object (&node);
11551   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11552   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11553
11554   vat_json_print (vam->ofp, &node);
11555   vat_json_free (&node);
11556
11557   vam->retval = ntohl (mp->retval);
11558   vam->result_ready = 1;
11559 }
11560
11561 static int
11562 api_get_first_msg_id (vat_main_t * vam)
11563 {
11564   vl_api_get_first_msg_id_t *mp;
11565   f64 timeout;
11566   unformat_input_t *i = vam->input;
11567   u8 *name;
11568   u8 name_set = 0;
11569
11570   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11571     {
11572       if (unformat (i, "client %s", &name))
11573         name_set = 1;
11574       else
11575         break;
11576     }
11577
11578   if (name_set == 0)
11579     {
11580       errmsg ("missing client name\n");
11581       return -99;
11582     }
11583   vec_add1 (name, 0);
11584
11585   if (vec_len (name) > 63)
11586     {
11587       errmsg ("client name too long\n");
11588       return -99;
11589     }
11590
11591   M (GET_FIRST_MSG_ID, get_first_msg_id);
11592   clib_memcpy (mp->name, name, vec_len (name));
11593   S;
11594   W;
11595   /* NOTREACHED */
11596   return 0;
11597 }
11598
11599 static int
11600 api_cop_interface_enable_disable (vat_main_t * vam)
11601 {
11602   unformat_input_t *line_input = vam->input;
11603   vl_api_cop_interface_enable_disable_t *mp;
11604   f64 timeout;
11605   u32 sw_if_index = ~0;
11606   u8 enable_disable = 1;
11607
11608   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11609     {
11610       if (unformat (line_input, "disable"))
11611         enable_disable = 0;
11612       if (unformat (line_input, "enable"))
11613         enable_disable = 1;
11614       else if (unformat (line_input, "%U", unformat_sw_if_index,
11615                          vam, &sw_if_index))
11616         ;
11617       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11618         ;
11619       else
11620         break;
11621     }
11622
11623   if (sw_if_index == ~0)
11624     {
11625       errmsg ("missing interface name or sw_if_index\n");
11626       return -99;
11627     }
11628
11629   /* Construct the API message */
11630   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11631   mp->sw_if_index = ntohl (sw_if_index);
11632   mp->enable_disable = enable_disable;
11633
11634   /* send it... */
11635   S;
11636   /* Wait for the reply */
11637   W;
11638 }
11639
11640 static int
11641 api_cop_whitelist_enable_disable (vat_main_t * vam)
11642 {
11643   unformat_input_t *line_input = vam->input;
11644   vl_api_cop_whitelist_enable_disable_t *mp;
11645   f64 timeout;
11646   u32 sw_if_index = ~0;
11647   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11648   u32 fib_id = 0;
11649
11650   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11651     {
11652       if (unformat (line_input, "ip4"))
11653         ip4 = 1;
11654       else if (unformat (line_input, "ip6"))
11655         ip6 = 1;
11656       else if (unformat (line_input, "default"))
11657         default_cop = 1;
11658       else if (unformat (line_input, "%U", unformat_sw_if_index,
11659                          vam, &sw_if_index))
11660         ;
11661       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11662         ;
11663       else if (unformat (line_input, "fib-id %d", &fib_id))
11664         ;
11665       else
11666         break;
11667     }
11668
11669   if (sw_if_index == ~0)
11670     {
11671       errmsg ("missing interface name or sw_if_index\n");
11672       return -99;
11673     }
11674
11675   /* Construct the API message */
11676   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
11677   mp->sw_if_index = ntohl (sw_if_index);
11678   mp->fib_id = ntohl (fib_id);
11679   mp->ip4 = ip4;
11680   mp->ip6 = ip6;
11681   mp->default_cop = default_cop;
11682
11683   /* send it... */
11684   S;
11685   /* Wait for the reply */
11686   W;
11687 }
11688
11689 static int
11690 api_get_node_graph (vat_main_t * vam)
11691 {
11692   vl_api_get_node_graph_t *mp;
11693   f64 timeout;
11694
11695   M (GET_NODE_GRAPH, get_node_graph);
11696
11697   /* send it... */
11698   S;
11699   /* Wait for the reply */
11700   W;
11701 }
11702
11703 /* *INDENT-OFF* */
11704 /** Used for parsing LISP eids */
11705 typedef CLIB_PACKED(struct{
11706   u8 addr[16];   /**< eid address */
11707   u32 len;       /**< prefix length if IP */
11708   u8 type;      /**< type of eid */
11709 }) lisp_eid_vat_t;
11710 /* *INDENT-ON* */
11711
11712 static uword
11713 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
11714 {
11715   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
11716
11717   memset (a, 0, sizeof (a[0]));
11718
11719   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
11720     {
11721       a->type = 0;              /* ipv4 type */
11722     }
11723   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
11724     {
11725       a->type = 1;              /* ipv6 type */
11726     }
11727   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
11728     {
11729       a->type = 2;              /* mac type */
11730     }
11731   else
11732     {
11733       return 0;
11734     }
11735
11736   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
11737     {
11738       return 0;
11739     }
11740
11741   return 1;
11742 }
11743
11744 static int
11745 lisp_eid_size_vat (u8 type)
11746 {
11747   switch (type)
11748     {
11749     case 0:
11750       return 4;
11751     case 1:
11752       return 16;
11753     case 2:
11754       return 6;
11755     }
11756   return 0;
11757 }
11758
11759 static void
11760 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
11761 {
11762   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
11763 }
11764
11765 /* *INDENT-OFF* */
11766 /** Used for transferring locators via VPP API */
11767 typedef CLIB_PACKED(struct
11768 {
11769   u32 sw_if_index; /**< locator sw_if_index */
11770   u8 priority; /**< locator priority */
11771   u8 weight;   /**< locator weight */
11772 }) ls_locator_t;
11773 /* *INDENT-ON* */
11774
11775 static int
11776 api_lisp_add_del_locator_set (vat_main_t * vam)
11777 {
11778   unformat_input_t *input = vam->input;
11779   vl_api_lisp_add_del_locator_set_t *mp;
11780   f64 timeout = ~0;
11781   u8 is_add = 1;
11782   u8 *locator_set_name = NULL;
11783   u8 locator_set_name_set = 0;
11784   ls_locator_t locator, *locators = 0;
11785   u32 sw_if_index, priority, weight;
11786
11787   /* Parse args required to build the message */
11788   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11789     {
11790       if (unformat (input, "del"))
11791         {
11792           is_add = 0;
11793         }
11794       else if (unformat (input, "locator-set %s", &locator_set_name))
11795         {
11796           locator_set_name_set = 1;
11797         }
11798       else if (unformat (input, "sw_if_index %u p %u w %u",
11799                          &sw_if_index, &priority, &weight))
11800         {
11801           locator.sw_if_index = htonl (sw_if_index);
11802           locator.priority = priority;
11803           locator.weight = weight;
11804           vec_add1 (locators, locator);
11805         }
11806       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
11807                          vam, &sw_if_index, &priority, &weight))
11808         {
11809           locator.sw_if_index = htonl (sw_if_index);
11810           locator.priority = priority;
11811           locator.weight = weight;
11812           vec_add1 (locators, locator);
11813         }
11814       else
11815         break;
11816     }
11817
11818   if (locator_set_name_set == 0)
11819     {
11820       errmsg ("missing locator-set name");
11821       vec_free (locators);
11822       return -99;
11823     }
11824
11825   if (vec_len (locator_set_name) > 64)
11826     {
11827       errmsg ("locator-set name too long\n");
11828       vec_free (locator_set_name);
11829       vec_free (locators);
11830       return -99;
11831     }
11832   vec_add1 (locator_set_name, 0);
11833
11834   /* Construct the API message */
11835   M (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
11836
11837   mp->is_add = is_add;
11838   clib_memcpy (mp->locator_set_name, locator_set_name,
11839                vec_len (locator_set_name));
11840   vec_free (locator_set_name);
11841
11842   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
11843   if (locators)
11844     clib_memcpy (mp->locators, locators,
11845                  (sizeof (ls_locator_t) * vec_len (locators)));
11846   vec_free (locators);
11847
11848   /* send it... */
11849   S;
11850
11851   /* Wait for a reply... */
11852   W;
11853
11854   /* NOTREACHED */
11855   return 0;
11856 }
11857
11858 static int
11859 api_lisp_add_del_locator (vat_main_t * vam)
11860 {
11861   unformat_input_t *input = vam->input;
11862   vl_api_lisp_add_del_locator_t *mp;
11863   f64 timeout = ~0;
11864   u32 tmp_if_index = ~0;
11865   u32 sw_if_index = ~0;
11866   u8 sw_if_index_set = 0;
11867   u8 sw_if_index_if_name_set = 0;
11868   u32 priority = ~0;
11869   u8 priority_set = 0;
11870   u32 weight = ~0;
11871   u8 weight_set = 0;
11872   u8 is_add = 1;
11873   u8 *locator_set_name = NULL;
11874   u8 locator_set_name_set = 0;
11875
11876   /* Parse args required to build the message */
11877   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11878     {
11879       if (unformat (input, "del"))
11880         {
11881           is_add = 0;
11882         }
11883       else if (unformat (input, "locator-set %s", &locator_set_name))
11884         {
11885           locator_set_name_set = 1;
11886         }
11887       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
11888                          &tmp_if_index))
11889         {
11890           sw_if_index_if_name_set = 1;
11891           sw_if_index = tmp_if_index;
11892         }
11893       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
11894         {
11895           sw_if_index_set = 1;
11896           sw_if_index = tmp_if_index;
11897         }
11898       else if (unformat (input, "p %d", &priority))
11899         {
11900           priority_set = 1;
11901         }
11902       else if (unformat (input, "w %d", &weight))
11903         {
11904           weight_set = 1;
11905         }
11906       else
11907         break;
11908     }
11909
11910   if (locator_set_name_set == 0)
11911     {
11912       errmsg ("missing locator-set name");
11913       return -99;
11914     }
11915
11916   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
11917     {
11918       errmsg ("missing sw_if_index");
11919       vec_free (locator_set_name);
11920       return -99;
11921     }
11922
11923   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
11924     {
11925       errmsg ("cannot use both params interface name and sw_if_index");
11926       vec_free (locator_set_name);
11927       return -99;
11928     }
11929
11930   if (priority_set == 0)
11931     {
11932       errmsg ("missing locator-set priority\n");
11933       vec_free (locator_set_name);
11934       return -99;
11935     }
11936
11937   if (weight_set == 0)
11938     {
11939       errmsg ("missing locator-set weight\n");
11940       vec_free (locator_set_name);
11941       return -99;
11942     }
11943
11944   if (vec_len (locator_set_name) > 64)
11945     {
11946       errmsg ("locator-set name too long\n");
11947       vec_free (locator_set_name);
11948       return -99;
11949     }
11950   vec_add1 (locator_set_name, 0);
11951
11952   /* Construct the API message */
11953   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
11954
11955   mp->is_add = is_add;
11956   mp->sw_if_index = ntohl (sw_if_index);
11957   mp->priority = priority;
11958   mp->weight = weight;
11959   clib_memcpy (mp->locator_set_name, locator_set_name,
11960                vec_len (locator_set_name));
11961   vec_free (locator_set_name);
11962
11963   /* send it... */
11964   S;
11965
11966   /* Wait for a reply... */
11967   W;
11968
11969   /* NOTREACHED */
11970   return 0;
11971 }
11972
11973 static int
11974 api_lisp_add_del_local_eid (vat_main_t * vam)
11975 {
11976   unformat_input_t *input = vam->input;
11977   vl_api_lisp_add_del_local_eid_t *mp;
11978   f64 timeout = ~0;
11979   u8 is_add = 1;
11980   u8 eid_set = 0;
11981   lisp_eid_vat_t _eid, *eid = &_eid;
11982   u8 *locator_set_name = 0;
11983   u8 locator_set_name_set = 0;
11984   u32 vni = 0;
11985
11986   /* Parse args required to build the message */
11987   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11988     {
11989       if (unformat (input, "del"))
11990         {
11991           is_add = 0;
11992         }
11993       else if (unformat (input, "vni %d", &vni))
11994         {
11995           ;
11996         }
11997       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
11998         {
11999           eid_set = 1;
12000         }
12001       else if (unformat (input, "locator-set %s", &locator_set_name))
12002         {
12003           locator_set_name_set = 1;
12004         }
12005       else
12006         break;
12007     }
12008
12009   if (locator_set_name_set == 0)
12010     {
12011       errmsg ("missing locator-set name\n");
12012       return -99;
12013     }
12014
12015   if (0 == eid_set)
12016     {
12017       errmsg ("EID address not set!");
12018       vec_free (locator_set_name);
12019       return -99;
12020     }
12021
12022   if (vec_len (locator_set_name) > 64)
12023     {
12024       errmsg ("locator-set name too long\n");
12025       vec_free (locator_set_name);
12026       return -99;
12027     }
12028   vec_add1 (locator_set_name, 0);
12029
12030   /* Construct the API message */
12031   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12032
12033   mp->is_add = is_add;
12034   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12035   mp->eid_type = eid->type;
12036   mp->prefix_len = eid->len;
12037   mp->vni = clib_host_to_net_u32 (vni);
12038   clib_memcpy (mp->locator_set_name, locator_set_name,
12039                vec_len (locator_set_name));
12040
12041   vec_free (locator_set_name);
12042
12043   /* send it... */
12044   S;
12045
12046   /* Wait for a reply... */
12047   W;
12048
12049   /* NOTREACHED */
12050   return 0;
12051 }
12052
12053 /* *INDENT-OFF* */
12054 /** Used for transferring locators via VPP API */
12055 typedef CLIB_PACKED(struct
12056 {
12057   u8 is_ip4; /**< is locator an IPv4 address? */
12058   u8 priority; /**< locator priority */
12059   u8 weight;   /**< locator weight */
12060   u8 addr[16]; /**< IPv4/IPv6 address */
12061 }) rloc_t;
12062 /* *INDENT-ON* */
12063
12064 static int
12065 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12066 {
12067   unformat_input_t *input = vam->input;
12068   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12069   f64 timeout = ~0;
12070   u8 is_add = 1;
12071   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12072   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12073   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12074   u32 action = ~0, p, w;
12075   ip4_address_t rmt_rloc4, lcl_rloc4;
12076   ip6_address_t rmt_rloc6, lcl_rloc6;
12077   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12078
12079   memset (&rloc, 0, sizeof (rloc));
12080
12081   /* Parse args required to build the message */
12082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12083     {
12084       if (unformat (input, "del"))
12085         {
12086           is_add = 0;
12087         }
12088       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12089         {
12090           rmt_eid_set = 1;
12091         }
12092       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12093         {
12094           lcl_eid_set = 1;
12095         }
12096       else if (unformat (input, "p %d w %d", &p, &w))
12097         {
12098           if (!curr_rloc)
12099             {
12100               errmsg ("No RLOC configured for setting priority/weight!");
12101               return -99;
12102             }
12103           curr_rloc->priority = p;
12104           curr_rloc->weight = w;
12105         }
12106       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12107                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12108         {
12109           rloc.is_ip4 = 1;
12110
12111           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12112           rloc.priority = rloc.weight = 0;
12113           vec_add1 (lcl_locs, rloc);
12114
12115           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12116           vec_add1 (rmt_locs, rloc);
12117           /* priority and weight saved in rmt loc */
12118           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12119         }
12120       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12121                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12122         {
12123           rloc.is_ip4 = 0;
12124           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12125           rloc.priority = rloc.weight = 0;
12126           vec_add1 (lcl_locs, rloc);
12127
12128           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12129           vec_add1 (rmt_locs, rloc);
12130           /* priority and weight saved in rmt loc */
12131           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12132         }
12133       else if (unformat (input, "action %d", &action))
12134         {
12135           ;
12136         }
12137       else
12138         {
12139           clib_warning ("parse error '%U'", format_unformat_error, input);
12140           return -99;
12141         }
12142     }
12143
12144   if (!rmt_eid_set)
12145     {
12146       errmsg ("remote eid addresses not set\n");
12147       return -99;
12148     }
12149
12150   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12151     {
12152       errmsg ("eid types don't match\n");
12153       return -99;
12154     }
12155
12156   if (0 == rmt_locs && (u32) ~ 0 == action)
12157     {
12158       errmsg ("action not set for negative mapping\n");
12159       return -99;
12160     }
12161
12162   /* Construct the API message */
12163   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12164
12165   mp->is_add = is_add;
12166   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12167   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12168   mp->eid_type = rmt_eid->type;
12169   mp->rmt_len = rmt_eid->len;
12170   mp->lcl_len = lcl_eid->len;
12171   mp->action = action;
12172
12173   if (0 != rmt_locs && 0 != lcl_locs)
12174     {
12175       mp->loc_num = vec_len (rmt_locs);
12176       clib_memcpy (mp->lcl_locs, lcl_locs,
12177                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12178       clib_memcpy (mp->rmt_locs, rmt_locs,
12179                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12180     }
12181   vec_free (lcl_locs);
12182   vec_free (rmt_locs);
12183
12184   /* send it... */
12185   S;
12186
12187   /* Wait for a reply... */
12188   W;
12189
12190   /* NOTREACHED */
12191   return 0;
12192 }
12193
12194 static int
12195 api_lisp_add_del_map_resolver (vat_main_t * vam)
12196 {
12197   unformat_input_t *input = vam->input;
12198   vl_api_lisp_add_del_map_resolver_t *mp;
12199   f64 timeout = ~0;
12200   u8 is_add = 1;
12201   u8 ipv4_set = 0;
12202   u8 ipv6_set = 0;
12203   ip4_address_t ipv4;
12204   ip6_address_t ipv6;
12205
12206   /* Parse args required to build the message */
12207   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12208     {
12209       if (unformat (input, "del"))
12210         {
12211           is_add = 0;
12212         }
12213       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12214         {
12215           ipv4_set = 1;
12216         }
12217       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12218         {
12219           ipv6_set = 1;
12220         }
12221       else
12222         break;
12223     }
12224
12225   if (ipv4_set && ipv6_set)
12226     {
12227       errmsg ("both eid v4 and v6 addresses set\n");
12228       return -99;
12229     }
12230
12231   if (!ipv4_set && !ipv6_set)
12232     {
12233       errmsg ("eid addresses not set\n");
12234       return -99;
12235     }
12236
12237   /* Construct the API message */
12238   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12239
12240   mp->is_add = is_add;
12241   if (ipv6_set)
12242     {
12243       mp->is_ipv6 = 1;
12244       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12245     }
12246   else
12247     {
12248       mp->is_ipv6 = 0;
12249       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12250     }
12251
12252   /* send it... */
12253   S;
12254
12255   /* Wait for a reply... */
12256   W;
12257
12258   /* NOTREACHED */
12259   return 0;
12260 }
12261
12262 static int
12263 api_lisp_gpe_enable_disable (vat_main_t * vam)
12264 {
12265   unformat_input_t *input = vam->input;
12266   vl_api_lisp_gpe_enable_disable_t *mp;
12267   f64 timeout = ~0;
12268   u8 is_set = 0;
12269   u8 is_en = 1;
12270
12271   /* Parse args required to build the message */
12272   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12273     {
12274       if (unformat (input, "enable"))
12275         {
12276           is_set = 1;
12277           is_en = 1;
12278         }
12279       else if (unformat (input, "disable"))
12280         {
12281           is_set = 1;
12282           is_en = 0;
12283         }
12284       else
12285         break;
12286     }
12287
12288   if (is_set == 0)
12289     {
12290       errmsg ("Value not set\n");
12291       return -99;
12292     }
12293
12294   /* Construct the API message */
12295   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12296
12297   mp->is_en = is_en;
12298
12299   /* send it... */
12300   S;
12301
12302   /* Wait for a reply... */
12303   W;
12304
12305   /* NOTREACHED */
12306   return 0;
12307 }
12308
12309 static int
12310 api_lisp_enable_disable (vat_main_t * vam)
12311 {
12312   unformat_input_t *input = vam->input;
12313   vl_api_lisp_enable_disable_t *mp;
12314   f64 timeout = ~0;
12315   u8 is_set = 0;
12316   u8 is_en = 0;
12317
12318   /* Parse args required to build the message */
12319   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12320     {
12321       if (unformat (input, "enable"))
12322         {
12323           is_set = 1;
12324           is_en = 1;
12325         }
12326       else if (unformat (input, "disable"))
12327         {
12328           is_set = 1;
12329         }
12330       else
12331         break;
12332     }
12333
12334   if (!is_set)
12335     {
12336       errmsg ("Value not set\n");
12337       return -99;
12338     }
12339
12340   /* Construct the API message */
12341   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12342
12343   mp->is_en = is_en;
12344
12345   /* send it... */
12346   S;
12347
12348   /* Wait for a reply... */
12349   W;
12350
12351   /* NOTREACHED */
12352   return 0;
12353 }
12354
12355 /**
12356  * Enable/disable LISP proxy ITR.
12357  *
12358  * @param vam vpp API test context
12359  * @return return code
12360  */
12361 static int
12362 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12363 {
12364   f64 timeout = ~0;
12365   u8 ls_name_set = 0;
12366   unformat_input_t *input = vam->input;
12367   vl_api_lisp_pitr_set_locator_set_t *mp;
12368   u8 is_add = 1;
12369   u8 *ls_name = 0;
12370
12371   /* Parse args required to build the message */
12372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12373     {
12374       if (unformat (input, "del"))
12375         is_add = 0;
12376       else if (unformat (input, "locator-set %s", &ls_name))
12377         ls_name_set = 1;
12378       else
12379         {
12380           errmsg ("parse error '%U'", format_unformat_error, input);
12381           return -99;
12382         }
12383     }
12384
12385   if (!ls_name_set)
12386     {
12387       errmsg ("locator-set name not set!");
12388       return -99;
12389     }
12390
12391   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12392
12393   mp->is_add = is_add;
12394   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12395   vec_free (ls_name);
12396
12397   /* send */
12398   S;
12399
12400   /* wait for reply */
12401   W;
12402
12403   /* notreached */
12404   return 0;
12405 }
12406
12407 static int
12408 api_show_lisp_pitr (vat_main_t * vam)
12409 {
12410   vl_api_show_lisp_pitr_t *mp;
12411   f64 timeout = ~0;
12412
12413   if (!vam->json_output)
12414     {
12415       fformat (vam->ofp, "%=20s\n", "lisp status:");
12416     }
12417
12418   M (SHOW_LISP_PITR, show_lisp_pitr);
12419   /* send it... */
12420   S;
12421
12422   /* Wait for a reply... */
12423   W;
12424
12425   /* NOTREACHED */
12426   return 0;
12427 }
12428
12429 /**
12430  * Add/delete mapping between vni and vrf
12431  */
12432 static int
12433 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12434 {
12435   f64 timeout = ~0;
12436   unformat_input_t *input = vam->input;
12437   vl_api_lisp_eid_table_add_del_map_t *mp;
12438   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12439   u32 vni, vrf, bd_index;
12440
12441   /* Parse args required to build the message */
12442   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12443     {
12444       if (unformat (input, "del"))
12445         is_add = 0;
12446       else if (unformat (input, "vrf %d", &vrf))
12447         vrf_set = 1;
12448       else if (unformat (input, "bd_index %d", &bd_index))
12449         bd_index_set = 1;
12450       else if (unformat (input, "vni %d", &vni))
12451         vni_set = 1;
12452       else
12453         break;
12454     }
12455
12456   if (!vni_set || (!vrf_set && !bd_index_set))
12457     {
12458       errmsg ("missing arguments!");
12459       return -99;
12460     }
12461
12462   if (vrf_set && bd_index_set)
12463     {
12464       errmsg ("error: both vrf and bd entered!");
12465       return -99;
12466     }
12467
12468   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12469
12470   mp->is_add = is_add;
12471   mp->vni = htonl (vni);
12472   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
12473   mp->is_l2 = bd_index_set;
12474
12475   /* send */
12476   S;
12477
12478   /* wait for reply */
12479   W;
12480
12481   /* notreached */
12482   return 0;
12483 }
12484
12485 /**
12486  * Add/del remote mapping to/from LISP control plane
12487  *
12488  * @param vam vpp API test context
12489  * @return return code
12490  */
12491 static int
12492 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12493 {
12494   unformat_input_t *input = vam->input;
12495   vl_api_lisp_add_del_remote_mapping_t *mp;
12496   f64 timeout = ~0;
12497   u32 vni = 0;
12498   //TODO: seid need remove
12499   lisp_eid_vat_t _eid, *eid = &_eid;
12500   lisp_eid_vat_t _seid, *seid = &_seid;
12501   u8 is_add = 1, del_all = 0, eid_set = 0;
12502   u32 action = ~0, p, w;
12503   ip4_address_t rloc4;
12504   ip6_address_t rloc6;
12505   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12506
12507   memset (&rloc, 0, sizeof (rloc));
12508
12509   /* Parse args required to build the message */
12510   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12511     {
12512       if (unformat (input, "del-all"))
12513         {
12514           del_all = 1;
12515         }
12516       else if (unformat (input, "del"))
12517         {
12518           is_add = 0;
12519         }
12520       else if (unformat (input, "add"))
12521         {
12522           is_add = 1;
12523         }
12524       else if (unformat (input, "deid %U", unformat_lisp_eid_vat, eid))
12525         {
12526           eid_set = 1;
12527         }
12528       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, &seid))
12529         {
12530           //TODO: Need remove, but first must be remove from CSIT test
12531         }
12532       else if (unformat (input, "vni %d", &vni))
12533         {
12534           ;
12535         }
12536       else if (unformat (input, "p %d w %d", &p, &w))
12537         {
12538           if (!curr_rloc)
12539             {
12540               errmsg ("No RLOC configured for setting priority/weight!");
12541               return -99;
12542             }
12543           curr_rloc->priority = p;
12544           curr_rloc->weight = w;
12545         }
12546       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12547         {
12548           rloc.is_ip4 = 1;
12549           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12550           vec_add1 (rlocs, rloc);
12551           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12552         }
12553       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12554         {
12555           rloc.is_ip4 = 0;
12556           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12557           vec_add1 (rlocs, rloc);
12558           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12559         }
12560       else if (unformat (input, "action %d", &action))
12561         {
12562           ;
12563         }
12564       else
12565         {
12566           clib_warning ("parse error '%U'", format_unformat_error, input);
12567           return -99;
12568         }
12569     }
12570
12571   if (0 == eid_set)
12572     {
12573       errmsg ("missing params!");
12574       return -99;
12575     }
12576
12577   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12578     {
12579       errmsg ("no action set for negative map-reply!");
12580       return -99;
12581     }
12582
12583   M (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
12584   mp->is_add = is_add;
12585   mp->vni = htonl (vni);
12586   mp->action = (u8) action;
12587   mp->eid_len = eid->len;
12588   mp->del_all = del_all;
12589   mp->eid_type = eid->type;
12590   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12591
12592   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
12593   clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
12594   vec_free (rlocs);
12595
12596   /* send it... */
12597   S;
12598
12599   /* Wait for a reply... */
12600   W;
12601
12602   /* NOTREACHED */
12603   return 0;
12604 }
12605
12606 /**
12607  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
12608  * forwarding entries in data-plane accordingly.
12609  *
12610  * @param vam vpp API test context
12611  * @return return code
12612  */
12613 static int
12614 api_lisp_add_del_adjacency (vat_main_t * vam)
12615 {
12616   unformat_input_t *input = vam->input;
12617   vl_api_lisp_add_del_adjacency_t *mp;
12618   f64 timeout = ~0;
12619   u32 vni = 0;
12620   ip4_address_t seid4, deid4;
12621   ip6_address_t seid6, deid6;
12622   u8 deid_mac[6] = { 0 };
12623   u8 seid_mac[6] = { 0 };
12624   u8 deid_type, seid_type;
12625   u32 seid_len = 0, deid_len = 0, len;
12626   u8 is_add = 1;
12627
12628   seid_type = deid_type = (u8) ~ 0;
12629
12630   /* Parse args required to build the message */
12631   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12632     {
12633       if (unformat (input, "del"))
12634         {
12635           is_add = 0;
12636         }
12637       else if (unformat (input, "add"))
12638         {
12639           is_add = 1;
12640         }
12641       else if (unformat (input, "deid %U/%d", unformat_ip4_address,
12642                          &deid4, &len))
12643         {
12644           deid_type = 0;        /* ipv4 */
12645           deid_len = len;
12646         }
12647       else if (unformat (input, "deid %U/%d", unformat_ip6_address,
12648                          &deid6, &len))
12649         {
12650           deid_type = 1;        /* ipv6 */
12651           deid_len = len;
12652         }
12653       else if (unformat (input, "deid %U", unformat_ethernet_address,
12654                          deid_mac))
12655         {
12656           deid_type = 2;        /* mac */
12657         }
12658       else if (unformat (input, "seid %U/%d", unformat_ip4_address,
12659                          &seid4, &len))
12660         {
12661           seid_type = 0;        /* ipv4 */
12662           seid_len = len;
12663         }
12664       else if (unformat (input, "seid %U/%d", unformat_ip6_address,
12665                          &seid6, &len))
12666         {
12667           seid_type = 1;        /* ipv6 */
12668           seid_len = len;
12669         }
12670       else if (unformat (input, "seid %U", unformat_ethernet_address,
12671                          seid_mac))
12672         {
12673           seid_type = 2;        /* mac */
12674         }
12675       else if (unformat (input, "vni %d", &vni))
12676         {
12677           ;
12678         }
12679       else
12680         {
12681           errmsg ("parse error '%U'", format_unformat_error, input);
12682           return -99;
12683         }
12684     }
12685
12686   if ((u8) ~ 0 == deid_type)
12687     {
12688       errmsg ("missing params!");
12689       return -99;
12690     }
12691
12692   if (seid_type != deid_type)
12693     {
12694       errmsg ("source and destination EIDs are of different types!");
12695       return -99;
12696     }
12697
12698   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
12699   mp->is_add = is_add;
12700   mp->vni = htonl (vni);
12701   mp->seid_len = seid_len;
12702   mp->deid_len = deid_len;
12703   mp->eid_type = deid_type;
12704
12705   switch (mp->eid_type)
12706     {
12707     case 0:
12708       clib_memcpy (mp->seid, &seid4, sizeof (seid4));
12709       clib_memcpy (mp->deid, &deid4, sizeof (deid4));
12710       break;
12711     case 1:
12712       clib_memcpy (mp->seid, &seid6, sizeof (seid6));
12713       clib_memcpy (mp->deid, &deid6, sizeof (deid6));
12714       break;
12715     case 2:
12716       clib_memcpy (mp->seid, seid_mac, 6);
12717       clib_memcpy (mp->deid, deid_mac, 6);
12718       break;
12719     default:
12720       errmsg ("unknown EID type %d!", mp->eid_type);
12721       return 0;
12722     }
12723
12724   /* send it... */
12725   S;
12726
12727   /* Wait for a reply... */
12728   W;
12729
12730   /* NOTREACHED */
12731   return 0;
12732 }
12733
12734 static int
12735 api_lisp_gpe_add_del_iface (vat_main_t * vam)
12736 {
12737   unformat_input_t *input = vam->input;
12738   vl_api_lisp_gpe_add_del_iface_t *mp;
12739   f64 timeout = ~0;
12740   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
12741   u32 dp_table = 0, vni = 0;
12742
12743   /* Parse args required to build the message */
12744   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12745     {
12746       if (unformat (input, "up"))
12747         {
12748           action_set = 1;
12749           is_add = 1;
12750         }
12751       else if (unformat (input, "down"))
12752         {
12753           action_set = 1;
12754           is_add = 0;
12755         }
12756       else if (unformat (input, "table_id %d", &dp_table))
12757         {
12758           dp_table_set = 1;
12759         }
12760       else if (unformat (input, "bd_id %d", &dp_table))
12761         {
12762           dp_table_set = 1;
12763           is_l2 = 1;
12764         }
12765       else if (unformat (input, "vni %d", &vni))
12766         {
12767           vni_set = 1;
12768         }
12769       else
12770         break;
12771     }
12772
12773   if (action_set == 0)
12774     {
12775       errmsg ("Action not set\n");
12776       return -99;
12777     }
12778   if (dp_table_set == 0 || vni_set == 0)
12779     {
12780       errmsg ("vni and dp_table must be set\n");
12781       return -99;
12782     }
12783
12784   /* Construct the API message */
12785   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
12786
12787   mp->is_add = is_add;
12788   mp->dp_table = dp_table;
12789   mp->is_l2 = is_l2;
12790   mp->vni = vni;
12791
12792   /* send it... */
12793   S;
12794
12795   /* Wait for a reply... */
12796   W;
12797
12798   /* NOTREACHED */
12799   return 0;
12800 }
12801
12802 /**
12803  * Add/del map request itr rlocs from LISP control plane and updates
12804  *
12805  * @param vam vpp API test context
12806  * @return return code
12807  */
12808 static int
12809 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
12810 {
12811   unformat_input_t *input = vam->input;
12812   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
12813   f64 timeout = ~0;
12814   u8 *locator_set_name = 0;
12815   u8 locator_set_name_set = 0;
12816   u8 is_add = 1;
12817
12818   /* Parse args required to build the message */
12819   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12820     {
12821       if (unformat (input, "del"))
12822         {
12823           is_add = 0;
12824         }
12825       else if (unformat (input, "%_%v%_", &locator_set_name))
12826         {
12827           locator_set_name_set = 1;
12828         }
12829       else
12830         {
12831           clib_warning ("parse error '%U'", format_unformat_error, input);
12832           return -99;
12833         }
12834     }
12835
12836   if (is_add && !locator_set_name_set)
12837     {
12838       errmsg ("itr-rloc is not set!");
12839       return -99;
12840     }
12841
12842   if (is_add && vec_len (locator_set_name) > 64)
12843     {
12844       errmsg ("itr-rloc locator-set name too long\n");
12845       vec_free (locator_set_name);
12846       return -99;
12847     }
12848
12849   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
12850   mp->is_add = is_add;
12851   if (is_add)
12852     {
12853       clib_memcpy (mp->locator_set_name, locator_set_name,
12854                    vec_len (locator_set_name));
12855     }
12856   else
12857     {
12858       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
12859     }
12860   vec_free (locator_set_name);
12861
12862   /* send it... */
12863   S;
12864
12865   /* Wait for a reply... */
12866   W;
12867
12868   /* NOTREACHED */
12869   return 0;
12870 }
12871
12872 static int
12873 lisp_locator_dump_send_msg (vat_main_t * vam, u32 locator_set_index,
12874                             u8 filter)
12875 {
12876   vl_api_lisp_locator_dump_t *mp;
12877   f64 timeout = ~0;
12878
12879   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
12880
12881   mp->locator_set_index = htonl (locator_set_index);
12882   mp->filter = filter;
12883
12884   /* send it... */
12885   S;
12886
12887   /* Use a control ping for synchronization */
12888   {
12889     vl_api_noprint_control_ping_t *mp;
12890     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12891     S;
12892   }
12893   /* Wait for a reply... */
12894   W;
12895 }
12896
12897 static inline void
12898 clean_locator_set_message (vat_main_t * vam)
12899 {
12900   locator_set_msg_t *ls = 0;
12901
12902   vec_foreach (ls, vam->locator_set_msg)
12903   {
12904     vec_free (ls->locator_set_name);
12905   }
12906
12907   vec_free (vam->locator_set_msg);
12908 }
12909
12910 static int
12911 print_locator_in_locator_set (vat_main_t * vam, u8 filter)
12912 {
12913   locator_set_msg_t *ls;
12914   locator_msg_t *loc;
12915   u8 *tmp_str = 0;
12916   int i = 0, ret = 0;
12917
12918   vec_foreach (ls, vam->locator_set_msg)
12919   {
12920     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12921     if (ret)
12922       {
12923         vec_free (vam->locator_msg);
12924         clean_locator_set_message (vam);
12925         return ret;
12926       }
12927
12928     tmp_str = format (0, "%=20s%=16d%s", ls->locator_set_name,
12929                       ls->locator_set_index,
12930                       vec_len (vam->locator_msg) ? "" : "\n");
12931     i = 0;
12932     vec_foreach (loc, vam->locator_msg)
12933     {
12934       if (i)
12935         {
12936           tmp_str = format (tmp_str, "%=37s", " ");
12937         }
12938       if (loc->local)
12939         {
12940           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
12941                             loc->sw_if_index, loc->priority, loc->weight);
12942         }
12943       else
12944         {
12945           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
12946                             loc->is_ipv6 ? format_ip6_address :
12947                             format_ip4_address,
12948                             loc->ip_address, loc->priority, loc->weight);
12949         }
12950       i++;
12951     }
12952
12953     fformat (vam->ofp, "%s", tmp_str);
12954     vec_free (tmp_str);
12955     vec_free (vam->locator_msg);
12956   }
12957
12958   clean_locator_set_message (vam);
12959
12960   return ret;
12961 }
12962
12963 static int
12964 json_locator_in_locator_set (vat_main_t * vam, u8 filter)
12965 {
12966   locator_set_msg_t *ls;
12967   locator_msg_t *loc;
12968   vat_json_node_t *node = NULL;
12969   vat_json_node_t *locator_array;
12970   vat_json_node_t *locator;
12971   struct in6_addr ip6;
12972   struct in_addr ip4;
12973   int ret = 0;
12974
12975   if (!vec_len (vam->locator_set_msg))
12976     {
12977       /* just print [] */
12978       vat_json_init_array (&vam->json_tree);
12979       vat_json_print (vam->ofp, &vam->json_tree);
12980       vam->json_tree.type = VAT_JSON_NONE;
12981       return ret;
12982     }
12983
12984   if (VAT_JSON_ARRAY != vam->json_tree.type)
12985     {
12986       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12987       vat_json_init_array (&vam->json_tree);
12988     }
12989
12990   vec_foreach (ls, vam->locator_set_msg)
12991   {
12992     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12993     if (ret)
12994       {
12995         vec_free (ls->locator_set_name);
12996         vec_free (vam->locator_msg);
12997         vec_free (vam->locator_set_msg);
12998         vat_json_free (&vam->json_tree);
12999         vam->json_tree.type = VAT_JSON_NONE;
13000         return ret;
13001       }
13002
13003     node = vat_json_array_add (&vam->json_tree);
13004     vat_json_init_object (node);
13005
13006     vat_json_object_add_uint (node, "locator-set-index",
13007                               ls->locator_set_index);
13008     vat_json_object_add_string_copy (node, "locator-set",
13009                                      ls->locator_set_name);
13010     locator_array = vat_json_object_add_list (node, "locator");
13011     vec_foreach (loc, vam->locator_msg)
13012     {
13013       locator = vat_json_array_add (locator_array);
13014       vat_json_init_object (locator);
13015       if (loc->local)
13016         {
13017           vat_json_object_add_uint (locator, "locator-index",
13018                                     loc->sw_if_index);
13019         }
13020       else
13021         {
13022           if (loc->is_ipv6)
13023             {
13024               clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
13025               vat_json_object_add_ip6 (locator, "locator", ip6);
13026             }
13027           else
13028             {
13029               clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
13030               vat_json_object_add_ip4 (locator, "locator", ip4);
13031             }
13032         }
13033       vat_json_object_add_uint (locator, "priority", loc->priority);
13034       vat_json_object_add_uint (locator, "weight", loc->weight);
13035     }
13036
13037     vec_free (ls->locator_set_name);
13038     vec_free (vam->locator_msg);
13039   }
13040
13041   vat_json_print (vam->ofp, &vam->json_tree);
13042   vat_json_free (&vam->json_tree);
13043   vam->json_tree.type = VAT_JSON_NONE;
13044
13045   vec_free (vam->locator_set_msg);
13046
13047   return ret;
13048 }
13049
13050 static int
13051 get_locator_set_index_from_msg (vat_main_t * vam, u8 * locator_set,
13052                                 u32 * locator_set_index)
13053 {
13054   locator_set_msg_t *ls;
13055   int ret = 0;
13056
13057   *locator_set_index = ~0;
13058
13059   if (!vec_len (vam->locator_set_msg))
13060     {
13061       return ret;
13062     }
13063
13064   vec_foreach (ls, vam->locator_set_msg)
13065   {
13066     if (!strcmp ((char *) locator_set, (char *) ls->locator_set_name))
13067       {
13068         *locator_set_index = ls->locator_set_index;
13069         vec_free (vam->locator_set_msg);
13070         return ret;
13071       }
13072   }
13073
13074   vec_free (vam->locator_set_msg);
13075
13076   return ret;
13077 }
13078
13079 static int
13080 get_locator_set_index (vat_main_t * vam, u8 * locator_set,
13081                        u32 * locator_set_index)
13082 {
13083   vl_api_lisp_locator_set_dump_t *mp;
13084   f64 timeout = ~0;
13085
13086   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13087   /* send it... */
13088   S;
13089
13090   /* Use a control ping for synchronization */
13091   {
13092     vl_api_noprint_control_ping_t *mp;
13093     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13094     S;
13095   }
13096
13097   vam->noprint_msg = 1;
13098   /* Wait for a reply... */
13099   /* *INDENT-OFF* */
13100   W_L
13101   ({
13102     get_locator_set_index_from_msg (vam, locator_set, locator_set_index);
13103     vam->noprint_msg = 0;
13104   });
13105   /* *INDENT-ON* */
13106
13107   /* NOTREACHED */
13108   return 0;
13109 }
13110
13111 static inline int
13112 lisp_locator_dump (vat_main_t * vam, u32 locator_set_index, u8 * locator_set,
13113                    u8 filter)
13114 {
13115   int ret = 0;
13116
13117   ASSERT (vam);
13118
13119   if (!vam->json_output)
13120     {
13121       fformat (vam->ofp, "%=20s%=16s%=16s\n",
13122                "locator", "priority", "weight");
13123     }
13124
13125   if (locator_set)
13126     {
13127       ret = get_locator_set_index (vam, locator_set, &locator_set_index);
13128     }
13129
13130   if (!ret && ~0 == locator_set_index)
13131     {
13132       return -99;
13133     }
13134
13135   ret = lisp_locator_dump_send_msg (vam, locator_set_index, filter);
13136
13137   return ret;
13138 }
13139
13140 static int
13141 lisp_locator_set_dump (vat_main_t * vam, u8 filter)
13142 {
13143   vl_api_lisp_locator_set_dump_t *mp;
13144   f64 timeout = ~0;
13145
13146   if (!vam->json_output)
13147     {
13148       fformat (vam->ofp, "%=20s%=16s%=16s%=16s%=16s\n",
13149                "locator-set", "locator-set-index", "locator", "priority",
13150                "weight");
13151     }
13152
13153   vam->noprint_msg = 1;
13154
13155   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13156
13157   mp->filter = filter;
13158
13159   /* send it... */
13160   S;
13161
13162   /* Use a control ping for synchronization */
13163   {
13164     vl_api_noprint_control_ping_t *mp;
13165     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13166     S;
13167   }
13168
13169   /* Wait for a reply... */
13170   /* *INDENT-OFF* */
13171   W_L
13172   ({
13173     if (vam->noprint_msg)
13174       {
13175         if (!vam->json_output)
13176           {
13177             print_locator_in_locator_set(vam, filter);
13178           }
13179         else
13180           {
13181             json_locator_in_locator_set(vam, filter);
13182           }
13183       }
13184     vam->noprint_msg = 0;
13185   });
13186   /* *INDENT-ON* */
13187
13188   /* NOTREACHED */
13189   return 0;
13190 }
13191
13192 static int
13193 api_lisp_locator_set_dump (vat_main_t * vam)
13194 {
13195   unformat_input_t *input = vam->input;
13196   vam->noprint_msg = 0;
13197   u32 locator_set_index = ~0;
13198   u8 locator_set_index_set = 0;
13199   u8 *locator_set = 0;
13200   u8 locator_set_set = 0;
13201   u8 filter = 0;
13202   int ret = 0;
13203
13204   /* Parse args required to build the message */
13205   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13206     {
13207       if (unformat (input, "locator-set-index %u", &locator_set_index))
13208         {
13209           locator_set_index_set = 1;
13210         }
13211       else if (unformat (input, "locator-set %s", &locator_set))
13212         {
13213           locator_set_set = 1;
13214         }
13215       else if (unformat (input, "local"))
13216         {
13217           filter = 1;
13218         }
13219       else if (unformat (input, "remote"))
13220         {
13221           filter = 2;
13222         }
13223       else
13224         {
13225           break;
13226         }
13227     }
13228
13229   if (locator_set_index_set && locator_set_set)
13230     {
13231       errmsg ("use only input parameter!\n");
13232       return -99;
13233     }
13234
13235   if (locator_set_index_set || locator_set_set)
13236     {
13237       ret = lisp_locator_dump (vam, locator_set_index, locator_set, filter);
13238     }
13239   else
13240     {
13241       ret = lisp_locator_set_dump (vam, filter);
13242     }
13243
13244   vec_free (locator_set);
13245
13246   return ret;
13247 }
13248
13249 static int
13250 api_lisp_eid_table_map_dump (vat_main_t * vam)
13251 {
13252   u8 is_l2 = 0;
13253   u8 mode_set = 0;
13254   unformat_input_t *input = vam->input;
13255   vl_api_lisp_eid_table_map_dump_t *mp;
13256   f64 timeout = ~0;
13257
13258   /* Parse args required to build the message */
13259   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13260     {
13261       if (unformat (input, "l2"))
13262         {
13263           is_l2 = 1;
13264           mode_set = 1;
13265         }
13266       else if (unformat (input, "l3"))
13267         {
13268           is_l2 = 0;
13269           mode_set = 1;
13270         }
13271       else
13272         {
13273           errmsg ("parse error '%U'", format_unformat_error, input);
13274           return -99;
13275         }
13276     }
13277
13278   if (!mode_set)
13279     {
13280       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13281       return -99;
13282     }
13283
13284   if (!vam->json_output)
13285     {
13286       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13287     }
13288
13289   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13290   mp->is_l2 = is_l2;
13291
13292   /* send it... */
13293   S;
13294
13295   /* Use a control ping for synchronization */
13296   {
13297     vl_api_control_ping_t *mp;
13298     M (CONTROL_PING, control_ping);
13299     S;
13300   }
13301   /* Wait for a reply... */
13302   W;
13303
13304   /* NOTREACHED */
13305   return 0;
13306 }
13307
13308 static int
13309 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13310 {
13311   vl_api_lisp_eid_table_vni_dump_t *mp;
13312   f64 timeout = ~0;
13313
13314   if (!vam->json_output)
13315     {
13316       fformat (vam->ofp, "VNI\n");
13317     }
13318
13319   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13320
13321   /* send it... */
13322   S;
13323
13324   /* Use a control ping for synchronization */
13325   {
13326     vl_api_control_ping_t *mp;
13327     M (CONTROL_PING, control_ping);
13328     S;
13329   }
13330   /* Wait for a reply... */
13331   W;
13332
13333   /* NOTREACHED */
13334   return 0;
13335 }
13336
13337 static int
13338 get_locator_set (vat_main_t * vam)
13339 {
13340   vl_api_lisp_locator_set_dump_t *mp;
13341   f64 timeout = ~0;
13342
13343   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13344   /* send it... */
13345   S;
13346
13347   /* Use a control ping for synchronization */
13348   {
13349     vl_api_noprint_control_ping_t *mp;
13350     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13351     S;
13352   }
13353
13354   /* Wait for a reply... */
13355   W;
13356
13357   /* NOTREACHED */
13358   return 0;
13359 }
13360
13361 static inline u8 *
13362 format_eid_for_eid_table (vat_main_t * vam, u8 * str, eid_table_t * eid_table,
13363                           int *ret)
13364 {
13365   u8 *(*format_eid) (u8 *, va_list *) = 0;
13366
13367   ASSERT (vam != NULL);
13368   ASSERT (eid_table != NULL);
13369
13370   if (ret)
13371     {
13372       *ret = 0;
13373     }
13374
13375   switch (eid_table->eid_type)
13376     {
13377     case 0:
13378     case 1:
13379       format_eid = (eid_table->eid_type ? format_ip6_address :
13380                     format_ip4_address);
13381       str = format (0, "[%d] %U/%d", eid_table->vni,
13382                     format_eid, eid_table->eid, eid_table->eid_prefix_len);
13383       break;
13384     case 2:
13385       str = format (0, "[%d] %U", eid_table->vni,
13386                     format_ethernet_address, eid_table->eid);
13387       break;
13388     default:
13389       errmsg ("unknown EID type %d!", eid_table->eid_type);
13390       if (ret)
13391         {
13392           *ret = -99;
13393         }
13394       return 0;
13395     }
13396
13397   return str;
13398 }
13399
13400 static inline u8 *
13401 format_locator_set_for_eid_table (vat_main_t * vam, u8 * str,
13402                                   eid_table_t * eid_table)
13403 {
13404   locator_set_msg_t *ls = 0;
13405
13406   ASSERT (vam != NULL);
13407   ASSERT (eid_table != NULL);
13408
13409   if (eid_table->is_local)
13410     {
13411       vec_foreach (ls, vam->locator_set_msg)
13412       {
13413         if (ls->locator_set_index == eid_table->locator_set_index)
13414           {
13415             str = format (0, "local(%s)", ls->locator_set_name);
13416             return str;
13417           }
13418       }
13419
13420       str = format (0, "local(N/A)");
13421     }
13422   else
13423     {
13424       str = format (0, "remote");
13425     }
13426
13427   return str;
13428 }
13429
13430 static inline u8 *
13431 format_locator_for_eid_table (vat_main_t * vam, u8 * str,
13432                               eid_table_t * eid_table)
13433 {
13434   locator_msg_t *loc = 0;
13435   int first_line = 1;
13436
13437   ASSERT (vam != NULL);
13438   ASSERT (eid_table != NULL);
13439
13440   if (~0 == eid_table->locator_set_index)
13441     {
13442       return format (0, "action: %d\n", eid_table->action);
13443     }
13444
13445   vec_foreach (loc, vam->locator_msg)
13446   {
13447     if (!first_line)
13448       {
13449         if (loc->local)
13450           {
13451             str = format (str, "%-55s%-d\n", " ", loc->sw_if_index);
13452           }
13453         else
13454           {
13455             str = format (str, "%=55s%-U\n", " ",
13456                           loc->is_ipv6 ? format_ip6_address :
13457                           format_ip4_address, loc->ip_address);
13458           }
13459
13460         continue;
13461       }
13462
13463     if (loc->local)
13464       {
13465         str = format (str, "%-30d%-20u%-u\n", loc->sw_if_index,
13466                       eid_table->ttl, eid_table->authoritative);
13467       }
13468     else
13469       {
13470         str = format (str, "%-30U%-20u%-u\n",
13471                       loc->is_ipv6 ? format_ip6_address :
13472                       format_ip4_address,
13473                       loc->ip_address, eid_table->ttl,
13474                       eid_table->authoritative);
13475       }
13476     first_line = 0;
13477   }
13478
13479   return str;
13480 }
13481
13482 static int
13483 print_lisp_eid_table_dump (vat_main_t * vam)
13484 {
13485   eid_table_t *eid_table = 0;
13486   u8 *tmp_str = 0, *tmp_str2 = 0;
13487   int ret = 0;
13488
13489   ASSERT (vam != NULL);
13490
13491   ret = get_locator_set (vam);
13492   if (ret)
13493     {
13494       vec_free (vam->eid_tables);
13495       return ret;
13496     }
13497
13498   fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type", "locators",
13499            "ttl", "authoritative");
13500
13501   vec_foreach (eid_table, vam->eid_tables)
13502   {
13503     if (~0 != eid_table->locator_set_index)
13504       {
13505         ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index,
13506                                           0);
13507         if (ret)
13508           {
13509             vec_free (vam->locator_msg);
13510             clean_locator_set_message (vam);
13511             vec_free (vam->eid_tables);
13512             return ret;
13513           }
13514       }
13515
13516     tmp_str2 = format_eid_for_eid_table (vam, tmp_str2, eid_table, &ret);
13517     if (ret)
13518       {
13519         vec_free (vam->locator_msg);
13520         clean_locator_set_message (vam);
13521         vec_free (vam->eid_tables);
13522         return ret;
13523       }
13524
13525     tmp_str = format (0, "%-35s", tmp_str2);
13526     vec_free (tmp_str2);
13527
13528     tmp_str2 = format_locator_set_for_eid_table (vam, tmp_str2, eid_table);
13529     tmp_str = format (tmp_str, "%-20s", tmp_str2);
13530     vec_free (tmp_str2);
13531
13532     tmp_str2 = format_locator_for_eid_table (vam, tmp_str2, eid_table);
13533     tmp_str = format (tmp_str, "%-s", tmp_str2);
13534     vec_free (tmp_str2);
13535
13536     fformat (vam->ofp, "%s", tmp_str);
13537     vec_free (tmp_str);
13538     vec_free (vam->locator_msg);
13539   }
13540
13541   clean_locator_set_message (vam);
13542   vec_free (vam->eid_tables);
13543
13544   return ret;
13545 }
13546
13547 static inline void
13548 json_locator_set_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13549                                 eid_table_t * eid_table)
13550 {
13551   locator_set_msg_t *ls = 0;
13552   u8 *s = 0;
13553
13554   ASSERT (vam != NULL);
13555   ASSERT (node != NULL);
13556   ASSERT (eid_table != NULL);
13557
13558   if (eid_table->is_local)
13559     {
13560       vec_foreach (ls, vam->locator_set_msg)
13561       {
13562         if (ls->locator_set_index == eid_table->locator_set_index)
13563           {
13564             vat_json_object_add_string_copy (node, "locator-set",
13565                                              ls->locator_set_name);
13566             return;
13567           }
13568       }
13569
13570       s = format (0, "N/A");
13571       vec_add1 (s, 0);
13572       vat_json_object_add_string_copy (node, "locator-set", s);
13573       vec_free (s);
13574     }
13575   else
13576     {
13577       s = format (0, "remote");
13578       vec_add1 (s, 0);
13579       vat_json_object_add_string_copy (node, "locator-set", s);
13580       vec_free (s);
13581     }
13582 }
13583
13584 static inline int
13585 json_eid_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13586                         eid_table_t * eid_table)
13587 {
13588   u8 *s = 0;
13589   struct in6_addr ip6;
13590   struct in_addr ip4;
13591
13592   ASSERT (vam != NULL);
13593   ASSERT (node != NULL);
13594   ASSERT (eid_table != NULL);
13595
13596   switch (eid_table->eid_type)
13597     {
13598     case 0:
13599       clib_memcpy (&ip4, eid_table->eid, sizeof (ip4));
13600       vat_json_object_add_ip4 (node, "eid", ip4);
13601       vat_json_object_add_uint (node, "eid-prefix-len",
13602                                 eid_table->eid_prefix_len);
13603       break;
13604     case 1:
13605       clib_memcpy (&ip6, eid_table->eid, sizeof (ip6));
13606       vat_json_object_add_ip6 (node, "eid", ip6);
13607       vat_json_object_add_uint (node, "eid-prefix-len",
13608                                 eid_table->eid_prefix_len);
13609       break;
13610     case 2:
13611       s = format (0, "%U", format_ethernet_address, eid_table->eid);
13612       vec_add1 (s, 0);
13613       vat_json_object_add_string_copy (node, "eid", s);
13614       vec_free (s);
13615       break;
13616     default:
13617       errmsg ("unknown EID type %d!", eid_table->eid_type);
13618       return -99;
13619     }
13620
13621   return 0;
13622 }
13623
13624 static inline void
13625 json_locator_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13626                             eid_table_t * eid_table)
13627 {
13628   locator_msg_t *loc = 0;
13629   vat_json_node_t *locator_array = 0;
13630   vat_json_node_t *locator = 0;
13631   struct in6_addr ip6;
13632   struct in_addr ip4;
13633
13634   ASSERT (vam != NULL);
13635   ASSERT (node != NULL);
13636   ASSERT (eid_table != NULL);
13637
13638   locator_array = vat_json_object_add_list (node, "locator");
13639   vec_foreach (loc, vam->locator_msg)
13640   {
13641     locator = vat_json_array_add (locator_array);
13642     vat_json_init_object (locator);
13643     if (loc->local)
13644       {
13645         vat_json_object_add_uint (locator, "locator-index", loc->sw_if_index);
13646       }
13647     else
13648       {
13649         if (loc->is_ipv6)
13650           {
13651             clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
13652             vat_json_object_add_ip6 (locator, "locator", ip6);
13653           }
13654         else
13655           {
13656             clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
13657             vat_json_object_add_ip4 (locator, "locator", ip4);
13658           }
13659       }
13660   }
13661 }
13662
13663 static int
13664 json_lisp_eid_table_dump (vat_main_t * vam)
13665 {
13666   eid_table_t *eid_table;
13667   vat_json_node_t *node = 0;
13668   int ret = 0;
13669
13670   ASSERT (vam != NULL);
13671
13672   ret = get_locator_set (vam);
13673   if (ret)
13674     {
13675       vec_free (vam->eid_tables);
13676       return ret;
13677     }
13678
13679   if (!vec_len (vam->eid_tables))
13680     {
13681       /* just print [] */
13682       vat_json_init_array (&vam->json_tree);
13683       vat_json_print (vam->ofp, &vam->json_tree);
13684       vam->json_tree.type = VAT_JSON_NONE;
13685       return ret;
13686     }
13687
13688   if (VAT_JSON_ARRAY != vam->json_tree.type)
13689     {
13690       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13691       vat_json_init_array (&vam->json_tree);
13692     }
13693
13694   vec_foreach (eid_table, vam->eid_tables)
13695   {
13696     ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index, 0);
13697     if (ret)
13698       {
13699         vec_free (vam->locator_msg);
13700         vec_free (vam->eid_tables);
13701         clean_locator_set_message (vam);
13702         vat_json_free (&vam->json_tree);
13703         vam->json_tree.type = VAT_JSON_NONE;
13704         return ret;
13705       }
13706
13707     node = vat_json_array_add (&vam->json_tree);
13708     vat_json_init_object (node);
13709
13710     vat_json_object_add_uint (node, "vni", eid_table->vni);
13711
13712     json_locator_set_for_eid_table (vam, node, eid_table);
13713     ret = json_eid_for_eid_table (vam, node, eid_table);
13714     if (ret)
13715       {
13716         vec_free (vam->locator_msg);
13717         vec_free (vam->eid_tables);
13718         clean_locator_set_message (vam);
13719         vat_json_free (&vam->json_tree);
13720         vam->json_tree.type = VAT_JSON_NONE;
13721         return ret;
13722       }
13723
13724     json_locator_for_eid_table (vam, node, eid_table);
13725
13726     vat_json_object_add_uint (node, "ttl", eid_table->ttl);
13727     vat_json_object_add_uint (node, "authoritative",
13728                               eid_table->authoritative);
13729
13730     vec_free (vam->locator_msg);
13731   }
13732
13733   vat_json_print (vam->ofp, &vam->json_tree);
13734   vat_json_free (&vam->json_tree);
13735   vam->json_tree.type = VAT_JSON_NONE;
13736
13737   clean_locator_set_message (vam);
13738   vec_free (vam->eid_tables);
13739
13740   return ret;
13741 }
13742
13743 static int
13744 api_lisp_eid_table_dump (vat_main_t * vam)
13745 {
13746   unformat_input_t *i = vam->input;
13747   vl_api_lisp_eid_table_dump_t *mp;
13748   f64 timeout = ~0;
13749   struct in_addr ip4;
13750   struct in6_addr ip6;
13751   u8 mac[6];
13752   u8 eid_type = ~0, eid_set = 0;
13753   u32 prefix_length = ~0, t, vni = 0;
13754   u8 filter = 0;
13755
13756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13757     {
13758       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13759         {
13760           eid_set = 1;
13761           eid_type = 0;
13762           prefix_length = t;
13763         }
13764       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13765         {
13766           eid_set = 1;
13767           eid_type = 1;
13768           prefix_length = t;
13769         }
13770       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13771         {
13772           eid_set = 1;
13773           eid_type = 2;
13774         }
13775       else if (unformat (i, "vni %d", &t))
13776         {
13777           vni = t;
13778         }
13779       else if (unformat (i, "local"))
13780         {
13781           filter = 1;
13782         }
13783       else if (unformat (i, "remote"))
13784         {
13785           filter = 2;
13786         }
13787       else
13788         {
13789           errmsg ("parse error '%U'", format_unformat_error, i);
13790           return -99;
13791         }
13792     }
13793
13794   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13795
13796   mp->filter = filter;
13797   if (eid_set)
13798     {
13799       mp->eid_set = 1;
13800       mp->vni = htonl (vni);
13801       mp->eid_type = eid_type;
13802       switch (eid_type)
13803         {
13804         case 0:
13805           mp->prefix_length = prefix_length;
13806           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13807           break;
13808         case 1:
13809           mp->prefix_length = prefix_length;
13810           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13811           break;
13812         case 2:
13813           clib_memcpy (mp->eid, mac, sizeof (mac));
13814           break;
13815         default:
13816           errmsg ("unknown EID type %d!", eid_type);
13817           return -99;
13818         }
13819     }
13820
13821   vam->noprint_msg = 1;
13822
13823   /* send it... */
13824   S;
13825
13826   /* Use a control ping for synchronization */
13827   {
13828     vl_api_noprint_control_ping_t *mp;
13829     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13830     S;
13831   }
13832
13833   /* Wait for a reply... */
13834   /* *INDENT-OFF* */
13835   W_L
13836   ({
13837     if (vam->noprint_msg)
13838       {
13839         if (!vam->json_output)
13840           {
13841             vam->retval = print_lisp_eid_table_dump(vam);
13842           }
13843         else
13844           {
13845             vam->retval = json_lisp_eid_table_dump(vam);
13846           }
13847       }
13848     vam->noprint_msg = 0;
13849   });
13850   /* *INDENT-ON* */
13851
13852   /* NOTREACHED */
13853   return 0;
13854 }
13855
13856 static int
13857 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13858 {
13859   vl_api_lisp_gpe_tunnel_dump_t *mp;
13860   f64 timeout = ~0;
13861
13862   if (!vam->json_output)
13863     {
13864       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13865                "%=16s%=16s%=16s%=16s%=16s\n",
13866                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13867                "Decap next", "Lisp version", "Flags", "Next protocol",
13868                "ver_res", "res", "iid");
13869     }
13870
13871   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13872   /* send it... */
13873   S;
13874
13875   /* Use a control ping for synchronization */
13876   {
13877     vl_api_control_ping_t *mp;
13878     M (CONTROL_PING, control_ping);
13879     S;
13880   }
13881   /* Wait for a reply... */
13882   W;
13883
13884   /* NOTREACHED */
13885   return 0;
13886 }
13887
13888 static int
13889 api_lisp_map_resolver_dump (vat_main_t * vam)
13890 {
13891   vl_api_lisp_map_resolver_dump_t *mp;
13892   f64 timeout = ~0;
13893
13894   if (!vam->json_output)
13895     {
13896       fformat (vam->ofp, "%=20s\n", "Map resolver");
13897     }
13898
13899   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13900   /* send it... */
13901   S;
13902
13903   /* Use a control ping for synchronization */
13904   {
13905     vl_api_control_ping_t *mp;
13906     M (CONTROL_PING, control_ping);
13907     S;
13908   }
13909   /* Wait for a reply... */
13910   W;
13911
13912   /* NOTREACHED */
13913   return 0;
13914 }
13915
13916 static int
13917 api_show_lisp_status (vat_main_t * vam)
13918 {
13919   vl_api_show_lisp_status_t *mp;
13920   f64 timeout = ~0;
13921
13922   if (!vam->json_output)
13923     {
13924       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13925     }
13926
13927   M (SHOW_LISP_STATUS, show_lisp_status);
13928   /* send it... */
13929   S;
13930   /* Wait for a reply... */
13931   W;
13932
13933   /* NOTREACHED */
13934   return 0;
13935 }
13936
13937 static int
13938 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13939 {
13940   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13941   f64 timeout = ~0;
13942
13943   if (!vam->json_output)
13944     {
13945       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13946     }
13947
13948   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13949   /* send it... */
13950   S;
13951   /* Wait for a reply... */
13952   W;
13953
13954   /* NOTREACHED */
13955   return 0;
13956 }
13957
13958 static int
13959 api_af_packet_create (vat_main_t * vam)
13960 {
13961   unformat_input_t *i = vam->input;
13962   vl_api_af_packet_create_t *mp;
13963   f64 timeout;
13964   u8 *host_if_name = 0;
13965   u8 hw_addr[6];
13966   u8 random_hw_addr = 1;
13967
13968   memset (hw_addr, 0, sizeof (hw_addr));
13969
13970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13971     {
13972       if (unformat (i, "name %s", &host_if_name))
13973         vec_add1 (host_if_name, 0);
13974       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13975         random_hw_addr = 0;
13976       else
13977         break;
13978     }
13979
13980   if (!vec_len (host_if_name))
13981     {
13982       errmsg ("host-interface name must be specified");
13983       return -99;
13984     }
13985
13986   if (vec_len (host_if_name) > 64)
13987     {
13988       errmsg ("host-interface name too long");
13989       return -99;
13990     }
13991
13992   M (AF_PACKET_CREATE, af_packet_create);
13993
13994   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13995   clib_memcpy (mp->hw_addr, hw_addr, 6);
13996   mp->use_random_hw_addr = random_hw_addr;
13997   vec_free (host_if_name);
13998
13999   S;
14000   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14001   /* NOTREACHED */
14002   return 0;
14003 }
14004
14005 static int
14006 api_af_packet_delete (vat_main_t * vam)
14007 {
14008   unformat_input_t *i = vam->input;
14009   vl_api_af_packet_delete_t *mp;
14010   f64 timeout;
14011   u8 *host_if_name = 0;
14012
14013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14014     {
14015       if (unformat (i, "name %s", &host_if_name))
14016         vec_add1 (host_if_name, 0);
14017       else
14018         break;
14019     }
14020
14021   if (!vec_len (host_if_name))
14022     {
14023       errmsg ("host-interface name must be specified");
14024       return -99;
14025     }
14026
14027   if (vec_len (host_if_name) > 64)
14028     {
14029       errmsg ("host-interface name too long");
14030       return -99;
14031     }
14032
14033   M (AF_PACKET_DELETE, af_packet_delete);
14034
14035   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14036   vec_free (host_if_name);
14037
14038   S;
14039   W;
14040   /* NOTREACHED */
14041   return 0;
14042 }
14043
14044 static int
14045 api_policer_add_del (vat_main_t * vam)
14046 {
14047   unformat_input_t *i = vam->input;
14048   vl_api_policer_add_del_t *mp;
14049   f64 timeout;
14050   u8 is_add = 1;
14051   u8 *name = 0;
14052   u32 cir = 0;
14053   u32 eir = 0;
14054   u64 cb = 0;
14055   u64 eb = 0;
14056   u8 rate_type = 0;
14057   u8 round_type = 0;
14058   u8 type = 0;
14059   u8 color_aware = 0;
14060   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14061
14062   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14063   conform_action.dscp = 0;
14064   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14065   exceed_action.dscp = 0;
14066   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14067   violate_action.dscp = 0;
14068
14069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14070     {
14071       if (unformat (i, "del"))
14072         is_add = 0;
14073       else if (unformat (i, "name %s", &name))
14074         vec_add1 (name, 0);
14075       else if (unformat (i, "cir %u", &cir))
14076         ;
14077       else if (unformat (i, "eir %u", &eir))
14078         ;
14079       else if (unformat (i, "cb %u", &cb))
14080         ;
14081       else if (unformat (i, "eb %u", &eb))
14082         ;
14083       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14084                          &rate_type))
14085         ;
14086       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14087                          &round_type))
14088         ;
14089       else if (unformat (i, "type %U", unformat_policer_type, &type))
14090         ;
14091       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14092                          &conform_action))
14093         ;
14094       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14095                          &exceed_action))
14096         ;
14097       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14098                          &violate_action))
14099         ;
14100       else if (unformat (i, "color-aware"))
14101         color_aware = 1;
14102       else
14103         break;
14104     }
14105
14106   if (!vec_len (name))
14107     {
14108       errmsg ("policer name must be specified");
14109       return -99;
14110     }
14111
14112   if (vec_len (name) > 64)
14113     {
14114       errmsg ("policer name too long");
14115       return -99;
14116     }
14117
14118   M (POLICER_ADD_DEL, policer_add_del);
14119
14120   clib_memcpy (mp->name, name, vec_len (name));
14121   vec_free (name);
14122   mp->is_add = is_add;
14123   mp->cir = cir;
14124   mp->eir = eir;
14125   mp->cb = cb;
14126   mp->eb = eb;
14127   mp->rate_type = rate_type;
14128   mp->round_type = round_type;
14129   mp->type = type;
14130   mp->conform_action_type = conform_action.action_type;
14131   mp->conform_dscp = conform_action.dscp;
14132   mp->exceed_action_type = exceed_action.action_type;
14133   mp->exceed_dscp = exceed_action.dscp;
14134   mp->violate_action_type = violate_action.action_type;
14135   mp->violate_dscp = violate_action.dscp;
14136   mp->color_aware = color_aware;
14137
14138   S;
14139   W;
14140   /* NOTREACHED */
14141   return 0;
14142 }
14143
14144 static int
14145 api_policer_dump (vat_main_t * vam)
14146 {
14147   unformat_input_t *i = vam->input;
14148   vl_api_policer_dump_t *mp;
14149   f64 timeout = ~0;
14150   u8 *match_name = 0;
14151   u8 match_name_valid = 0;
14152
14153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14154     {
14155       if (unformat (i, "name %s", &match_name))
14156         {
14157           vec_add1 (match_name, 0);
14158           match_name_valid = 1;
14159         }
14160       else
14161         break;
14162     }
14163
14164   M (POLICER_DUMP, policer_dump);
14165   mp->match_name_valid = match_name_valid;
14166   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14167   vec_free (match_name);
14168   /* send it... */
14169   S;
14170
14171   /* Use a control ping for synchronization */
14172   {
14173     vl_api_control_ping_t *mp;
14174     M (CONTROL_PING, control_ping);
14175     S;
14176   }
14177   /* Wait for a reply... */
14178   W;
14179
14180   /* NOTREACHED */
14181   return 0;
14182 }
14183
14184 static int
14185 api_policer_classify_set_interface (vat_main_t * vam)
14186 {
14187   unformat_input_t *i = vam->input;
14188   vl_api_policer_classify_set_interface_t *mp;
14189   f64 timeout;
14190   u32 sw_if_index;
14191   int sw_if_index_set;
14192   u32 ip4_table_index = ~0;
14193   u32 ip6_table_index = ~0;
14194   u32 l2_table_index = ~0;
14195   u8 is_add = 1;
14196
14197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14198     {
14199       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14200         sw_if_index_set = 1;
14201       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14202         sw_if_index_set = 1;
14203       else if (unformat (i, "del"))
14204         is_add = 0;
14205       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14206         ;
14207       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14208         ;
14209       else if (unformat (i, "l2-table %d", &l2_table_index))
14210         ;
14211       else
14212         {
14213           clib_warning ("parse error '%U'", format_unformat_error, i);
14214           return -99;
14215         }
14216     }
14217
14218   if (sw_if_index_set == 0)
14219     {
14220       errmsg ("missing interface name or sw_if_index\n");
14221       return -99;
14222     }
14223
14224   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14225
14226   mp->sw_if_index = ntohl (sw_if_index);
14227   mp->ip4_table_index = ntohl (ip4_table_index);
14228   mp->ip6_table_index = ntohl (ip6_table_index);
14229   mp->l2_table_index = ntohl (l2_table_index);
14230   mp->is_add = is_add;
14231
14232   S;
14233   W;
14234   /* NOTREACHED */
14235   return 0;
14236 }
14237
14238 static int
14239 api_policer_classify_dump (vat_main_t * vam)
14240 {
14241   unformat_input_t *i = vam->input;
14242   vl_api_policer_classify_dump_t *mp;
14243   f64 timeout = ~0;
14244   u8 type = POLICER_CLASSIFY_N_TABLES;
14245
14246   if (unformat (i, "type %U", unformat_classify_table_type, &type))
14247     ;
14248   else
14249     {
14250       errmsg ("classify table type must be specified\n");
14251       return -99;
14252     }
14253
14254   if (!vam->json_output)
14255     {
14256       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14257     }
14258
14259   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14260   mp->type = type;
14261   /* send it... */
14262   S;
14263
14264   /* Use a control ping for synchronization */
14265   {
14266     vl_api_control_ping_t *mp;
14267     M (CONTROL_PING, control_ping);
14268     S;
14269   }
14270   /* Wait for a reply... */
14271   W;
14272
14273   /* NOTREACHED */
14274   return 0;
14275 }
14276
14277 static int
14278 api_netmap_create (vat_main_t * vam)
14279 {
14280   unformat_input_t *i = vam->input;
14281   vl_api_netmap_create_t *mp;
14282   f64 timeout;
14283   u8 *if_name = 0;
14284   u8 hw_addr[6];
14285   u8 random_hw_addr = 1;
14286   u8 is_pipe = 0;
14287   u8 is_master = 0;
14288
14289   memset (hw_addr, 0, sizeof (hw_addr));
14290
14291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14292     {
14293       if (unformat (i, "name %s", &if_name))
14294         vec_add1 (if_name, 0);
14295       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14296         random_hw_addr = 0;
14297       else if (unformat (i, "pipe"))
14298         is_pipe = 1;
14299       else if (unformat (i, "master"))
14300         is_master = 1;
14301       else if (unformat (i, "slave"))
14302         is_master = 0;
14303       else
14304         break;
14305     }
14306
14307   if (!vec_len (if_name))
14308     {
14309       errmsg ("interface name must be specified");
14310       return -99;
14311     }
14312
14313   if (vec_len (if_name) > 64)
14314     {
14315       errmsg ("interface name too long");
14316       return -99;
14317     }
14318
14319   M (NETMAP_CREATE, netmap_create);
14320
14321   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14322   clib_memcpy (mp->hw_addr, hw_addr, 6);
14323   mp->use_random_hw_addr = random_hw_addr;
14324   mp->is_pipe = is_pipe;
14325   mp->is_master = is_master;
14326   vec_free (if_name);
14327
14328   S;
14329   W;
14330   /* NOTREACHED */
14331   return 0;
14332 }
14333
14334 static int
14335 api_netmap_delete (vat_main_t * vam)
14336 {
14337   unformat_input_t *i = vam->input;
14338   vl_api_netmap_delete_t *mp;
14339   f64 timeout;
14340   u8 *if_name = 0;
14341
14342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14343     {
14344       if (unformat (i, "name %s", &if_name))
14345         vec_add1 (if_name, 0);
14346       else
14347         break;
14348     }
14349
14350   if (!vec_len (if_name))
14351     {
14352       errmsg ("interface name must be specified");
14353       return -99;
14354     }
14355
14356   if (vec_len (if_name) > 64)
14357     {
14358       errmsg ("interface name too long");
14359       return -99;
14360     }
14361
14362   M (NETMAP_DELETE, netmap_delete);
14363
14364   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14365   vec_free (if_name);
14366
14367   S;
14368   W;
14369   /* NOTREACHED */
14370   return 0;
14371 }
14372
14373 static void vl_api_mpls_gre_tunnel_details_t_handler
14374   (vl_api_mpls_gre_tunnel_details_t * mp)
14375 {
14376   vat_main_t *vam = &vat_main;
14377   i32 i;
14378   i32 len = ntohl (mp->nlabels);
14379
14380   if (mp->l2_only == 0)
14381     {
14382       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14383                ntohl (mp->tunnel_index),
14384                format_ip4_address, &mp->tunnel_src,
14385                format_ip4_address, &mp->tunnel_dst,
14386                format_ip4_address, &mp->intfc_address,
14387                ntohl (mp->mask_width));
14388       for (i = 0; i < len; i++)
14389         {
14390           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14391         }
14392       fformat (vam->ofp, "\n");
14393       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14394                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14395     }
14396   else
14397     {
14398       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14399                ntohl (mp->tunnel_index),
14400                format_ip4_address, &mp->tunnel_src,
14401                format_ip4_address, &mp->tunnel_dst,
14402                format_ip4_address, &mp->intfc_address);
14403       for (i = 0; i < len; i++)
14404         {
14405           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14406         }
14407       fformat (vam->ofp, "\n");
14408       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14409                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14410     }
14411 }
14412
14413 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14414   (vl_api_mpls_gre_tunnel_details_t * mp)
14415 {
14416   vat_main_t *vam = &vat_main;
14417   vat_json_node_t *node = NULL;
14418   struct in_addr ip4;
14419   i32 i;
14420   i32 len = ntohl (mp->nlabels);
14421
14422   if (VAT_JSON_ARRAY != vam->json_tree.type)
14423     {
14424       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14425       vat_json_init_array (&vam->json_tree);
14426     }
14427   node = vat_json_array_add (&vam->json_tree);
14428
14429   vat_json_init_object (node);
14430   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14431   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14432   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14433   vat_json_object_add_uint (node, "inner_fib_index",
14434                             ntohl (mp->inner_fib_index));
14435   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14436   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14437   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14438   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14439   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14440   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14441   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14442   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14443   vat_json_object_add_uint (node, "outer_fib_index",
14444                             ntohl (mp->outer_fib_index));
14445   vat_json_object_add_uint (node, "label_count", len);
14446   for (i = 0; i < len; i++)
14447     {
14448       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14449     }
14450 }
14451
14452 static int
14453 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14454 {
14455   vl_api_mpls_gre_tunnel_dump_t *mp;
14456   f64 timeout;
14457   i32 index = -1;
14458
14459   /* Parse args required to build the message */
14460   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14461     {
14462       if (!unformat (vam->input, "tunnel_index %d", &index))
14463         {
14464           index = -1;
14465           break;
14466         }
14467     }
14468
14469   fformat (vam->ofp, "  tunnel_index %d\n", index);
14470
14471   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14472   mp->tunnel_index = htonl (index);
14473   S;
14474
14475   /* Use a control ping for synchronization */
14476   {
14477     vl_api_control_ping_t *mp;
14478     M (CONTROL_PING, control_ping);
14479     S;
14480   }
14481   W;
14482 }
14483
14484 static void vl_api_mpls_eth_tunnel_details_t_handler
14485   (vl_api_mpls_eth_tunnel_details_t * mp)
14486 {
14487   vat_main_t *vam = &vat_main;
14488   i32 i;
14489   i32 len = ntohl (mp->nlabels);
14490
14491   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14492            ntohl (mp->tunnel_index),
14493            format_ethernet_address, &mp->tunnel_dst_mac,
14494            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14495   for (i = 0; i < len; i++)
14496     {
14497       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14498     }
14499   fformat (vam->ofp, "\n");
14500   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14501            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14502 }
14503
14504 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14505   (vl_api_mpls_eth_tunnel_details_t * mp)
14506 {
14507   vat_main_t *vam = &vat_main;
14508   vat_json_node_t *node = NULL;
14509   struct in_addr ip4;
14510   i32 i;
14511   i32 len = ntohl (mp->nlabels);
14512
14513   if (VAT_JSON_ARRAY != vam->json_tree.type)
14514     {
14515       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14516       vat_json_init_array (&vam->json_tree);
14517     }
14518   node = vat_json_array_add (&vam->json_tree);
14519
14520   vat_json_init_object (node);
14521   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14522   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14523   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14524   vat_json_object_add_uint (node, "inner_fib_index",
14525                             ntohl (mp->inner_fib_index));
14526   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14527   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14528   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14529   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14530   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14531                                    format (0, "%U", format_ethernet_address,
14532                                            &mp->tunnel_dst_mac));
14533   vat_json_object_add_uint (node, "tx_sw_if_index",
14534                             ntohl (mp->tx_sw_if_index));
14535   vat_json_object_add_uint (node, "label_count", len);
14536   for (i = 0; i < len; i++)
14537     {
14538       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14539     }
14540 }
14541
14542 static int
14543 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14544 {
14545   vl_api_mpls_eth_tunnel_dump_t *mp;
14546   f64 timeout;
14547   i32 index = -1;
14548
14549   /* Parse args required to build the message */
14550   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14551     {
14552       if (!unformat (vam->input, "tunnel_index %d", &index))
14553         {
14554           index = -1;
14555           break;
14556         }
14557     }
14558
14559   fformat (vam->ofp, "  tunnel_index %d\n", index);
14560
14561   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14562   mp->tunnel_index = htonl (index);
14563   S;
14564
14565   /* Use a control ping for synchronization */
14566   {
14567     vl_api_control_ping_t *mp;
14568     M (CONTROL_PING, control_ping);
14569     S;
14570   }
14571   W;
14572 }
14573
14574 static void vl_api_mpls_fib_encap_details_t_handler
14575   (vl_api_mpls_fib_encap_details_t * mp)
14576 {
14577   vat_main_t *vam = &vat_main;
14578   i32 i;
14579   i32 len = ntohl (mp->nlabels);
14580
14581   fformat (vam->ofp, "table %d, dest %U, label ",
14582            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14583   for (i = 0; i < len; i++)
14584     {
14585       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14586     }
14587   fformat (vam->ofp, "\n");
14588 }
14589
14590 static void vl_api_mpls_fib_encap_details_t_handler_json
14591   (vl_api_mpls_fib_encap_details_t * mp)
14592 {
14593   vat_main_t *vam = &vat_main;
14594   vat_json_node_t *node = NULL;
14595   i32 i;
14596   i32 len = ntohl (mp->nlabels);
14597   struct in_addr ip4;
14598
14599   if (VAT_JSON_ARRAY != vam->json_tree.type)
14600     {
14601       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14602       vat_json_init_array (&vam->json_tree);
14603     }
14604   node = vat_json_array_add (&vam->json_tree);
14605
14606   vat_json_init_object (node);
14607   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14608   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14609   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14610   vat_json_object_add_ip4 (node, "dest", ip4);
14611   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14612   vat_json_object_add_uint (node, "label_count", len);
14613   for (i = 0; i < len; i++)
14614     {
14615       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14616     }
14617 }
14618
14619 static int
14620 api_mpls_fib_encap_dump (vat_main_t * vam)
14621 {
14622   vl_api_mpls_fib_encap_dump_t *mp;
14623   f64 timeout;
14624
14625   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14626   S;
14627
14628   /* Use a control ping for synchronization */
14629   {
14630     vl_api_control_ping_t *mp;
14631     M (CONTROL_PING, control_ping);
14632     S;
14633   }
14634   W;
14635 }
14636
14637 static void vl_api_mpls_fib_decap_details_t_handler
14638   (vl_api_mpls_fib_decap_details_t * mp)
14639 {
14640   vat_main_t *vam = &vat_main;
14641
14642   fformat (vam->ofp,
14643            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14644            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14645            ntohl (mp->label), ntohl (mp->s_bit));
14646 }
14647
14648 static void vl_api_mpls_fib_decap_details_t_handler_json
14649   (vl_api_mpls_fib_decap_details_t * mp)
14650 {
14651   vat_main_t *vam = &vat_main;
14652   vat_json_node_t *node = NULL;
14653   struct in_addr ip4;
14654
14655   if (VAT_JSON_ARRAY != vam->json_tree.type)
14656     {
14657       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14658       vat_json_init_array (&vam->json_tree);
14659     }
14660   node = vat_json_array_add (&vam->json_tree);
14661
14662   vat_json_init_object (node);
14663   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14664   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14665   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14666   vat_json_object_add_ip4 (node, "dest", ip4);
14667   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14668   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14669   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14670   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14671   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14672 }
14673
14674 static int
14675 api_mpls_fib_decap_dump (vat_main_t * vam)
14676 {
14677   vl_api_mpls_fib_decap_dump_t *mp;
14678   f64 timeout;
14679
14680   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14681   S;
14682
14683   /* Use a control ping for synchronization */
14684   {
14685     vl_api_control_ping_t *mp;
14686     M (CONTROL_PING, control_ping);
14687     S;
14688   }
14689   W;
14690 }
14691
14692 int
14693 api_classify_table_ids (vat_main_t * vam)
14694 {
14695   vl_api_classify_table_ids_t *mp;
14696   f64 timeout;
14697
14698   /* Construct the API message */
14699   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14700   mp->context = 0;
14701
14702   S;
14703   W;
14704   /* NOTREACHED */
14705   return 0;
14706 }
14707
14708 int
14709 api_classify_table_by_interface (vat_main_t * vam)
14710 {
14711   unformat_input_t *input = vam->input;
14712   vl_api_classify_table_by_interface_t *mp;
14713   f64 timeout;
14714
14715   u32 sw_if_index = ~0;
14716   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14717     {
14718       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14719         ;
14720       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14721         ;
14722       else
14723         break;
14724     }
14725   if (sw_if_index == ~0)
14726     {
14727       errmsg ("missing interface name or sw_if_index\n");
14728       return -99;
14729     }
14730
14731   /* Construct the API message */
14732   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14733   mp->context = 0;
14734   mp->sw_if_index = ntohl (sw_if_index);
14735
14736   S;
14737   W;
14738   /* NOTREACHED */
14739   return 0;
14740 }
14741
14742 int
14743 api_classify_table_info (vat_main_t * vam)
14744 {
14745   unformat_input_t *input = vam->input;
14746   vl_api_classify_table_info_t *mp;
14747   f64 timeout;
14748
14749   u32 table_id = ~0;
14750   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14751     {
14752       if (unformat (input, "table_id %d", &table_id))
14753         ;
14754       else
14755         break;
14756     }
14757   if (table_id == ~0)
14758     {
14759       errmsg ("missing table id\n");
14760       return -99;
14761     }
14762
14763   /* Construct the API message */
14764   M (CLASSIFY_TABLE_INFO, classify_table_info);
14765   mp->context = 0;
14766   mp->table_id = ntohl (table_id);
14767
14768   S;
14769   W;
14770   /* NOTREACHED */
14771   return 0;
14772 }
14773
14774 int
14775 api_classify_session_dump (vat_main_t * vam)
14776 {
14777   unformat_input_t *input = vam->input;
14778   vl_api_classify_session_dump_t *mp;
14779   f64 timeout;
14780
14781   u32 table_id = ~0;
14782   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14783     {
14784       if (unformat (input, "table_id %d", &table_id))
14785         ;
14786       else
14787         break;
14788     }
14789   if (table_id == ~0)
14790     {
14791       errmsg ("missing table id\n");
14792       return -99;
14793     }
14794
14795   /* Construct the API message */
14796   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14797   mp->context = 0;
14798   mp->table_id = ntohl (table_id);
14799   S;
14800
14801   /* Use a control ping for synchronization */
14802   {
14803     vl_api_control_ping_t *mp;
14804     M (CONTROL_PING, control_ping);
14805     S;
14806   }
14807   W;
14808   /* NOTREACHED */
14809   return 0;
14810 }
14811
14812 static void
14813 vl_api_ipfix_details_t_handler (vl_api_ipfix_details_t * mp)
14814 {
14815   vat_main_t *vam = &vat_main;
14816
14817   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14818            "src_address %U, fib_index %u, path_mtu %u, "
14819            "template_interval %u\n",
14820            format_ip4_address, mp->collector_address,
14821            ntohs (mp->collector_port),
14822            format_ip4_address, mp->src_address,
14823            ntohl (mp->fib_index),
14824            ntohl (mp->path_mtu), ntohl (mp->template_interval));
14825
14826   vam->retval = 0;
14827   vam->result_ready = 1;
14828 }
14829
14830 static void
14831 vl_api_ipfix_details_t_handler_json (vl_api_ipfix_details_t * mp)
14832 {
14833   vat_main_t *vam = &vat_main;
14834   vat_json_node_t node;
14835   struct in_addr collector_address;
14836   struct in_addr src_address;
14837
14838   vat_json_init_object (&node);
14839   clib_memcpy (&collector_address, &mp->collector_address,
14840                sizeof (collector_address));
14841   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14842   vat_json_object_add_uint (&node, "collector_port",
14843                             ntohs (mp->collector_port));
14844   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14845   vat_json_object_add_ip4 (&node, "src_address", src_address);
14846   vat_json_object_add_uint (&node, "fib_index", ntohl (mp->fib_index));
14847   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14848   vat_json_object_add_uint (&node, "template_interval",
14849                             ntohl (mp->template_interval));
14850
14851   vat_json_print (vam->ofp, &node);
14852   vat_json_free (&node);
14853   vam->retval = 0;
14854   vam->result_ready = 1;
14855 }
14856
14857 int
14858 api_ipfix_dump (vat_main_t * vam)
14859 {
14860   vl_api_ipfix_dump_t *mp;
14861   f64 timeout;
14862
14863   /* Construct the API message */
14864   M (IPFIX_DUMP, ipfix_dump);
14865   mp->context = 0;
14866
14867   S;
14868   W;
14869   /* NOTREACHED */
14870   return 0;
14871 }
14872
14873 int
14874 api_pg_create_interface (vat_main_t * vam)
14875 {
14876   unformat_input_t *input = vam->input;
14877   vl_api_pg_create_interface_t *mp;
14878   f64 timeout;
14879
14880   u32 if_id = ~0;
14881   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14882     {
14883       if (unformat (input, "if_id %d", &if_id))
14884         ;
14885       else
14886         break;
14887     }
14888   if (if_id == ~0)
14889     {
14890       errmsg ("missing pg interface index\n");
14891       return -99;
14892     }
14893
14894   /* Construct the API message */
14895   M (PG_CREATE_INTERFACE, pg_create_interface);
14896   mp->context = 0;
14897   mp->interface_id = ntohl (if_id);
14898
14899   S;
14900   W;
14901   /* NOTREACHED */
14902   return 0;
14903 }
14904
14905 int
14906 api_pg_capture (vat_main_t * vam)
14907 {
14908   unformat_input_t *input = vam->input;
14909   vl_api_pg_capture_t *mp;
14910   f64 timeout;
14911
14912   u32 if_id = ~0;
14913   u8 enable = 1;
14914   u32 count = 1;
14915   u8 pcap_file_set = 0;
14916   u8 *pcap_file = 0;
14917   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14918     {
14919       if (unformat (input, "if_id %d", &if_id))
14920         ;
14921       else if (unformat (input, "pcap %s", &pcap_file))
14922         pcap_file_set = 1;
14923       else if (unformat (input, "count %d", &count))
14924         ;
14925       else if (unformat (input, "disable"))
14926         enable = 0;
14927       else
14928         break;
14929     }
14930   if (if_id == ~0)
14931     {
14932       errmsg ("missing pg interface index\n");
14933       return -99;
14934     }
14935   if (pcap_file_set > 0)
14936     {
14937       if (vec_len (pcap_file) > 255)
14938         {
14939           errmsg ("pcap file name is too long\n");
14940           return -99;
14941         }
14942     }
14943
14944   u32 name_len = vec_len (pcap_file);
14945   /* Construct the API message */
14946   M (PG_CAPTURE, pg_capture);
14947   mp->context = 0;
14948   mp->interface_id = ntohl (if_id);
14949   mp->is_enabled = enable;
14950   mp->count = ntohl (count);
14951   mp->pcap_name_length = ntohl (name_len);
14952   if (pcap_file_set != 0)
14953     {
14954       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
14955     }
14956   vec_free (pcap_file);
14957
14958   S;
14959   W;
14960   /* NOTREACHED */
14961   return 0;
14962 }
14963
14964 int
14965 api_pg_enable_disable (vat_main_t * vam)
14966 {
14967   unformat_input_t *input = vam->input;
14968   vl_api_pg_enable_disable_t *mp;
14969   f64 timeout;
14970
14971   u8 enable = 1;
14972   u8 stream_name_set = 0;
14973   u8 *stream_name = 0;
14974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14975     {
14976       if (unformat (input, "stream %s", &stream_name))
14977         stream_name_set = 1;
14978       else if (unformat (input, "disable"))
14979         enable = 0;
14980       else
14981         break;
14982     }
14983
14984   if (stream_name_set > 0)
14985     {
14986       if (vec_len (stream_name) > 255)
14987         {
14988           errmsg ("stream name too long\n");
14989           return -99;
14990         }
14991     }
14992
14993   u32 name_len = vec_len (stream_name);
14994   /* Construct the API message */
14995   M (PG_ENABLE_DISABLE, pg_enable_disable);
14996   mp->context = 0;
14997   mp->is_enabled = enable;
14998   if (stream_name_set != 0)
14999     {
15000       mp->stream_name_length = ntohl (name_len);
15001       clib_memcpy (mp->stream_name, stream_name, name_len);
15002     }
15003   vec_free (stream_name);
15004
15005   S;
15006   W;
15007   /* NOTREACHED */
15008   return 0;
15009 }
15010
15011 int
15012 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15013 {
15014   unformat_input_t *input = vam->input;
15015   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15016   f64 timeout;
15017
15018   u16 *low_ports = 0;
15019   u16 *high_ports = 0;
15020   u16 this_low;
15021   u16 this_hi;
15022   ip4_address_t ip4_addr;
15023   ip6_address_t ip6_addr;
15024   u32 length;
15025   u32 tmp, tmp2;
15026   u8 prefix_set = 0;
15027   u32 vrf_id = ~0;
15028   u8 is_add = 1;
15029   u8 is_ipv6 = 0;
15030
15031   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15032     {
15033       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15034         {
15035           prefix_set = 1;
15036         }
15037       else
15038         if (unformat
15039             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15040         {
15041           prefix_set = 1;
15042           is_ipv6 = 1;
15043         }
15044       else if (unformat (input, "vrf %d", &vrf_id))
15045         ;
15046       else if (unformat (input, "del"))
15047         is_add = 0;
15048       else if (unformat (input, "port %d", &tmp))
15049         {
15050           if (tmp == 0 || tmp > 65535)
15051             {
15052               errmsg ("port %d out of range", tmp);
15053               return -99;
15054             }
15055           this_low = tmp;
15056           this_hi = this_low + 1;
15057           vec_add1 (low_ports, this_low);
15058           vec_add1 (high_ports, this_hi);
15059         }
15060       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15061         {
15062           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15063             {
15064               errmsg ("incorrect range parameters\n");
15065               return -99;
15066             }
15067           this_low = tmp;
15068           /* Note: in debug CLI +1 is added to high before
15069              passing to real fn that does "the work"
15070              (ip_source_and_port_range_check_add_del).
15071              This fn is a wrapper around the binary API fn a
15072              control plane will call, which expects this increment
15073              to have occurred. Hence letting the binary API control
15074              plane fn do the increment for consistency between VAT
15075              and other control planes.
15076            */
15077           this_hi = tmp2;
15078           vec_add1 (low_ports, this_low);
15079           vec_add1 (high_ports, this_hi);
15080         }
15081       else
15082         break;
15083     }
15084
15085   if (prefix_set == 0)
15086     {
15087       errmsg ("<address>/<mask> not specified\n");
15088       return -99;
15089     }
15090
15091   if (vrf_id == ~0)
15092     {
15093       errmsg ("VRF ID required, not specified\n");
15094       return -99;
15095     }
15096
15097   if (vrf_id == 0)
15098     {
15099       errmsg
15100         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15101       return -99;
15102     }
15103
15104   if (vec_len (low_ports) == 0)
15105     {
15106       errmsg ("At least one port or port range required\n");
15107       return -99;
15108     }
15109
15110   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15111      ip_source_and_port_range_check_add_del);
15112
15113   mp->is_add = is_add;
15114
15115   if (is_ipv6)
15116     {
15117       mp->is_ipv6 = 1;
15118       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15119     }
15120   else
15121     {
15122       mp->is_ipv6 = 0;
15123       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15124     }
15125
15126   mp->mask_length = length;
15127   mp->number_of_ranges = vec_len (low_ports);
15128
15129   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15130   vec_free (low_ports);
15131
15132   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15133   vec_free (high_ports);
15134
15135   mp->vrf_id = ntohl (vrf_id);
15136
15137   S;
15138   W;
15139   /* NOTREACHED */
15140   return 0;
15141 }
15142
15143 int
15144 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15145 {
15146   unformat_input_t *input = vam->input;
15147   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15148   f64 timeout;
15149   u32 sw_if_index = ~0;
15150   int vrf_set = 0;
15151   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15152   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15153   u8 is_add = 1;
15154
15155   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15156     {
15157       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15158         ;
15159       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15160         ;
15161       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15162         vrf_set = 1;
15163       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15164         vrf_set = 1;
15165       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15166         vrf_set = 1;
15167       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15168         vrf_set = 1;
15169       else if (unformat (input, "del"))
15170         is_add = 0;
15171       else
15172         break;
15173     }
15174
15175   if (sw_if_index == ~0)
15176     {
15177       errmsg ("Interface required but not specified\n");
15178       return -99;
15179     }
15180
15181   if (vrf_set == 0)
15182     {
15183       errmsg ("VRF ID required but not specified\n");
15184       return -99;
15185     }
15186
15187   if (tcp_out_vrf_id == 0
15188       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15189     {
15190       errmsg
15191         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15192       return -99;
15193     }
15194
15195   /* Construct the API message */
15196   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15197      ip_source_and_port_range_check_interface_add_del);
15198
15199   mp->sw_if_index = ntohl (sw_if_index);
15200   mp->is_add = is_add;
15201   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15202   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15203   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15204   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15205
15206   /* send it... */
15207   S;
15208
15209   /* Wait for a reply... */
15210   W;
15211 }
15212
15213 static int
15214 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15215 {
15216   unformat_input_t *i = vam->input;
15217   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15218   f64 timeout;
15219   u32 local_sa_id = 0;
15220   u32 remote_sa_id = 0;
15221   ip4_address_t src_address;
15222   ip4_address_t dst_address;
15223   u8 is_add = 1;
15224
15225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15226     {
15227       if (unformat (i, "local_sa %d", &local_sa_id))
15228         ;
15229       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15230         ;
15231       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15232         ;
15233       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15234         ;
15235       else if (unformat (i, "del"))
15236         is_add = 0;
15237       else
15238         {
15239           clib_warning ("parse error '%U'", format_unformat_error, i);
15240           return -99;
15241         }
15242     }
15243
15244   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15245
15246   mp->local_sa_id = ntohl (local_sa_id);
15247   mp->remote_sa_id = ntohl (remote_sa_id);
15248   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15249   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15250   mp->is_add = is_add;
15251
15252   S;
15253   W;
15254   /* NOTREACHED */
15255   return 0;
15256 }
15257
15258 static void vl_api_ipsec_gre_tunnel_details_t_handler
15259   (vl_api_ipsec_gre_tunnel_details_t * mp)
15260 {
15261   vat_main_t *vam = &vat_main;
15262
15263   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15264            ntohl (mp->sw_if_index),
15265            format_ip4_address, &mp->src_address,
15266            format_ip4_address, &mp->dst_address,
15267            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15268 }
15269
15270 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15271   (vl_api_ipsec_gre_tunnel_details_t * mp)
15272 {
15273   vat_main_t *vam = &vat_main;
15274   vat_json_node_t *node = NULL;
15275   struct in_addr ip4;
15276
15277   if (VAT_JSON_ARRAY != vam->json_tree.type)
15278     {
15279       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15280       vat_json_init_array (&vam->json_tree);
15281     }
15282   node = vat_json_array_add (&vam->json_tree);
15283
15284   vat_json_init_object (node);
15285   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15286   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15287   vat_json_object_add_ip4 (node, "src_address", ip4);
15288   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15289   vat_json_object_add_ip4 (node, "dst_address", ip4);
15290   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15291   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15292 }
15293
15294 static int
15295 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15296 {
15297   unformat_input_t *i = vam->input;
15298   vl_api_ipsec_gre_tunnel_dump_t *mp;
15299   f64 timeout;
15300   u32 sw_if_index;
15301   u8 sw_if_index_set = 0;
15302
15303   /* Parse args required to build the message */
15304   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15305     {
15306       if (unformat (i, "sw_if_index %d", &sw_if_index))
15307         sw_if_index_set = 1;
15308       else
15309         break;
15310     }
15311
15312   if (sw_if_index_set == 0)
15313     {
15314       sw_if_index = ~0;
15315     }
15316
15317   if (!vam->json_output)
15318     {
15319       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15320                "sw_if_index", "src_address", "dst_address",
15321                "local_sa_id", "remote_sa_id");
15322     }
15323
15324   /* Get list of gre-tunnel interfaces */
15325   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15326
15327   mp->sw_if_index = htonl (sw_if_index);
15328
15329   S;
15330
15331   /* Use a control ping for synchronization */
15332   {
15333     vl_api_control_ping_t *mp;
15334     M (CONTROL_PING, control_ping);
15335     S;
15336   }
15337   W;
15338 }
15339
15340 static int
15341 api_delete_subif (vat_main_t * vam)
15342 {
15343   unformat_input_t *i = vam->input;
15344   vl_api_delete_subif_t *mp;
15345   f64 timeout;
15346   u32 sw_if_index = ~0;
15347
15348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15349     {
15350       if (unformat (i, "sw_if_index %d", &sw_if_index))
15351         ;
15352       else
15353         break;
15354     }
15355
15356   if (sw_if_index == ~0)
15357     {
15358       errmsg ("missing sw_if_index\n");
15359       return -99;
15360     }
15361
15362   /* Construct the API message */
15363   M (DELETE_SUBIF, delete_subif);
15364   mp->sw_if_index = ntohl (sw_if_index);
15365
15366   S;
15367   W;
15368 }
15369
15370 static int
15371 q_or_quit (vat_main_t * vam)
15372 {
15373   longjmp (vam->jump_buf, 1);
15374   return 0;                     /* not so much */
15375 }
15376
15377 static int
15378 q (vat_main_t * vam)
15379 {
15380   return q_or_quit (vam);
15381 }
15382
15383 static int
15384 quit (vat_main_t * vam)
15385 {
15386   return q_or_quit (vam);
15387 }
15388
15389 static int
15390 comment (vat_main_t * vam)
15391 {
15392   return 0;
15393 }
15394
15395 static int
15396 cmd_cmp (void *a1, void *a2)
15397 {
15398   u8 **c1 = a1;
15399   u8 **c2 = a2;
15400
15401   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15402 }
15403
15404 static int
15405 help (vat_main_t * vam)
15406 {
15407   u8 **cmds = 0;
15408   u8 *name = 0;
15409   hash_pair_t *p;
15410   unformat_input_t *i = vam->input;
15411   int j;
15412
15413   if (unformat (i, "%s", &name))
15414     {
15415       uword *hs;
15416
15417       vec_add1 (name, 0);
15418
15419       hs = hash_get_mem (vam->help_by_name, name);
15420       if (hs)
15421         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15422       else
15423         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15424       vec_free (name);
15425       return 0;
15426     }
15427
15428   fformat (vam->ofp, "Help is available for the following:\n");
15429
15430     /* *INDENT-OFF* */
15431     hash_foreach_pair (p, vam->function_by_name,
15432     ({
15433       vec_add1 (cmds, (u8 *)(p->key));
15434     }));
15435     /* *INDENT-ON* */
15436
15437   vec_sort_with_function (cmds, cmd_cmp);
15438
15439   for (j = 0; j < vec_len (cmds); j++)
15440     fformat (vam->ofp, "%s\n", cmds[j]);
15441
15442   vec_free (cmds);
15443   return 0;
15444 }
15445
15446 static int
15447 set (vat_main_t * vam)
15448 {
15449   u8 *name = 0, *value = 0;
15450   unformat_input_t *i = vam->input;
15451
15452   if (unformat (i, "%s", &name))
15453     {
15454       /* The input buffer is a vector, not a string. */
15455       value = vec_dup (i->buffer);
15456       vec_delete (value, i->index, 0);
15457       /* Almost certainly has a trailing newline */
15458       if (value[vec_len (value) - 1] == '\n')
15459         value[vec_len (value) - 1] = 0;
15460       /* Make sure it's a proper string, one way or the other */
15461       vec_add1 (value, 0);
15462       (void) clib_macro_set_value (&vam->macro_main,
15463                                    (char *) name, (char *) value);
15464     }
15465   else
15466     errmsg ("usage: set <name> <value>\n");
15467
15468   vec_free (name);
15469   vec_free (value);
15470   return 0;
15471 }
15472
15473 static int
15474 unset (vat_main_t * vam)
15475 {
15476   u8 *name = 0;
15477
15478   if (unformat (vam->input, "%s", &name))
15479     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15480       errmsg ("unset: %s wasn't set\n", name);
15481   vec_free (name);
15482   return 0;
15483 }
15484
15485 typedef struct
15486 {
15487   u8 *name;
15488   u8 *value;
15489 } macro_sort_t;
15490
15491
15492 static int
15493 macro_sort_cmp (void *a1, void *a2)
15494 {
15495   macro_sort_t *s1 = a1;
15496   macro_sort_t *s2 = a2;
15497
15498   return strcmp ((char *) (s1->name), (char *) (s2->name));
15499 }
15500
15501 static int
15502 dump_macro_table (vat_main_t * vam)
15503 {
15504   macro_sort_t *sort_me = 0, *sm;
15505   int i;
15506   hash_pair_t *p;
15507
15508     /* *INDENT-OFF* */
15509     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15510     ({
15511       vec_add2 (sort_me, sm, 1);
15512       sm->name = (u8 *)(p->key);
15513       sm->value = (u8 *) (p->value[0]);
15514     }));
15515     /* *INDENT-ON* */
15516
15517   vec_sort_with_function (sort_me, macro_sort_cmp);
15518
15519   if (vec_len (sort_me))
15520     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15521   else
15522     fformat (vam->ofp, "The macro table is empty...\n");
15523
15524   for (i = 0; i < vec_len (sort_me); i++)
15525     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15526   return 0;
15527 }
15528
15529 static int
15530 dump_node_table (vat_main_t * vam)
15531 {
15532   int i, j;
15533   vlib_node_t *node, *next_node;
15534
15535   if (vec_len (vam->graph_nodes) == 0)
15536     {
15537       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15538       return 0;
15539     }
15540
15541   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15542     {
15543       node = vam->graph_nodes[i];
15544       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15545       for (j = 0; j < vec_len (node->next_nodes); j++)
15546         {
15547           if (node->next_nodes[j] != ~0)
15548             {
15549               next_node = vam->graph_nodes[node->next_nodes[j]];
15550               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15551             }
15552         }
15553     }
15554   return 0;
15555 }
15556
15557 static int
15558 search_node_table (vat_main_t * vam)
15559 {
15560   unformat_input_t *line_input = vam->input;
15561   u8 *node_to_find;
15562   int j;
15563   vlib_node_t *node, *next_node;
15564   uword *p;
15565
15566   if (vam->graph_node_index_by_name == 0)
15567     {
15568       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15569       return 0;
15570     }
15571
15572   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15573     {
15574       if (unformat (line_input, "%s", &node_to_find))
15575         {
15576           vec_add1 (node_to_find, 0);
15577           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15578           if (p == 0)
15579             {
15580               fformat (vam->ofp, "%s not found...\n", node_to_find);
15581               goto out;
15582             }
15583           node = vam->graph_nodes[p[0]];
15584           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15585           for (j = 0; j < vec_len (node->next_nodes); j++)
15586             {
15587               if (node->next_nodes[j] != ~0)
15588                 {
15589                   next_node = vam->graph_nodes[node->next_nodes[j]];
15590                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15591                 }
15592             }
15593         }
15594
15595       else
15596         {
15597           clib_warning ("parse error '%U'", format_unformat_error,
15598                         line_input);
15599           return -99;
15600         }
15601
15602     out:
15603       vec_free (node_to_find);
15604
15605     }
15606
15607   return 0;
15608 }
15609
15610
15611 static int
15612 script (vat_main_t * vam)
15613 {
15614   u8 *s = 0;
15615   char *save_current_file;
15616   unformat_input_t save_input;
15617   jmp_buf save_jump_buf;
15618   u32 save_line_number;
15619
15620   FILE *new_fp, *save_ifp;
15621
15622   if (unformat (vam->input, "%s", &s))
15623     {
15624       new_fp = fopen ((char *) s, "r");
15625       if (new_fp == 0)
15626         {
15627           errmsg ("Couldn't open script file %s\n", s);
15628           vec_free (s);
15629           return -99;
15630         }
15631     }
15632   else
15633     {
15634       errmsg ("Missing script name\n");
15635       return -99;
15636     }
15637
15638   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15639   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15640   save_ifp = vam->ifp;
15641   save_line_number = vam->input_line_number;
15642   save_current_file = (char *) vam->current_file;
15643
15644   vam->input_line_number = 0;
15645   vam->ifp = new_fp;
15646   vam->current_file = s;
15647   do_one_file (vam);
15648
15649   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15650   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15651   vam->ifp = save_ifp;
15652   vam->input_line_number = save_line_number;
15653   vam->current_file = (u8 *) save_current_file;
15654   vec_free (s);
15655
15656   return 0;
15657 }
15658
15659 static int
15660 echo (vat_main_t * vam)
15661 {
15662   fformat (vam->ofp, "%v", vam->input->buffer);
15663   return 0;
15664 }
15665
15666 /* List of API message constructors, CLI names map to api_xxx */
15667 #define foreach_vpe_api_msg                                             \
15668 _(create_loopback,"[mac <mac-addr>]")                                   \
15669 _(sw_interface_dump,"")                                                 \
15670 _(sw_interface_set_flags,                                               \
15671   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15672 _(sw_interface_add_del_address,                                         \
15673   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15674 _(sw_interface_set_table,                                               \
15675   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15676 _(sw_interface_set_vpath,                                               \
15677   "<intfc> | sw_if_index <id> enable | disable")                        \
15678 _(sw_interface_set_l2_xconnect,                                         \
15679   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15680   "enable | disable")                                                   \
15681 _(sw_interface_set_l2_bridge,                                           \
15682   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15683   "[shg <split-horizon-group>] [bvi]\n"                                 \
15684   "enable | disable")                                                   \
15685 _(bridge_domain_add_del,                                                \
15686   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15687 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15688 _(l2fib_add_del,                                                        \
15689   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15690 _(l2_flags,                                                             \
15691   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15692 _(bridge_flags,                                                         \
15693   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15694 _(tap_connect,                                                          \
15695   "tapname <name> mac <mac-addr> | random-mac")                         \
15696 _(tap_modify,                                                           \
15697   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15698 _(tap_delete,                                                           \
15699   "<vpp-if-name> | sw_if_index <id>")                                   \
15700 _(sw_interface_tap_dump, "")                                            \
15701 _(ip_add_del_route,                                                     \
15702   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15703   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15704   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15705   "[multipath] [count <n>]")                                            \
15706 _(proxy_arp_add_del,                                                    \
15707   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15708 _(proxy_arp_intfc_enable_disable,                                       \
15709   "<intfc> | sw_if_index <id> enable | disable")                        \
15710 _(mpls_add_del_encap,                                                   \
15711   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15712 _(mpls_add_del_decap,                                                   \
15713   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15714 _(mpls_gre_add_del_tunnel,                                              \
15715   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15716   "adj <ip4-address>/<mask-width> [del]")                               \
15717 _(sw_interface_set_unnumbered,                                          \
15718   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15719 _(ip_neighbor_add_del,                                                  \
15720   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15721   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15722 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15723 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15724 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15725   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15726   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15727   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15728 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15729 _(reset_fib, "vrf <n> [ipv6]")                                          \
15730 _(dhcp_proxy_config,                                                    \
15731   "svr <v46-address> src <v46-address>\n"                               \
15732    "insert-cid <n> [del]")                                              \
15733 _(dhcp_proxy_config_2,                                                  \
15734   "svr <v46-address> src <v46-address>\n"                               \
15735    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15736 _(dhcp_proxy_set_vss,                                                   \
15737   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15738 _(dhcp_client_config,                                                   \
15739   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15740 _(set_ip_flow_hash,                                                     \
15741   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15742 _(sw_interface_ip6_enable_disable,                                      \
15743   "<intfc> | sw_if_index <id> enable | disable")                        \
15744 _(sw_interface_ip6_set_link_local_address,                              \
15745   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15746 _(sw_interface_ip6nd_ra_prefix,                                         \
15747   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15748   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15749   "[nolink] [isno]")                                                    \
15750 _(sw_interface_ip6nd_ra_config,                                         \
15751   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15752   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15753   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15754 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15755 _(l2_patch_add_del,                                                     \
15756   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15757   "enable | disable")                                                   \
15758 _(mpls_ethernet_add_del_tunnel,                                         \
15759   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15760   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15761 _(mpls_ethernet_add_del_tunnel_2,                                       \
15762   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15763   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15764 _(sr_tunnel_add_del,                                                    \
15765   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15766   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15767   "[policy <policy_name>]")                                             \
15768 _(sr_policy_add_del,                                                    \
15769   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15770 _(sr_multicast_map_add_del,                                             \
15771   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15772 _(classify_add_del_table,                                               \
15773   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15774   "[del] mask <mask-value>\n"                                           \
15775   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15776 _(classify_add_del_session,                                             \
15777   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15778   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15779   "  [l3 [ip4|ip6]]")                                                   \
15780 _(classify_set_interface_ip_table,                                      \
15781   "<intfc> | sw_if_index <nn> table <nn>")                              \
15782 _(classify_set_interface_l2_tables,                                     \
15783   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15784   "  [other-table <nn>]")                                               \
15785 _(get_node_index, "node <node-name")                                    \
15786 _(add_node_next, "node <node-name> next <next-node-name>")              \
15787 _(l2tpv3_create_tunnel,                                                 \
15788   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15789   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15790   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15791 _(l2tpv3_set_tunnel_cookies,                                            \
15792   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15793   "[new_remote_cookie <nn>]\n")                                         \
15794 _(l2tpv3_interface_enable_disable,                                      \
15795   "<intfc> | sw_if_index <nn> enable | disable")                        \
15796 _(l2tpv3_set_lookup_key,                                                \
15797   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15798 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15799 _(vxlan_add_del_tunnel,                                                 \
15800   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15801   " [decap-next l2|ip4|ip6] [del]")                                     \
15802 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15803 _(gre_add_del_tunnel,                                                   \
15804   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n")          \
15805 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15806 _(l2_fib_clear_table, "")                                               \
15807 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15808 _(l2_interface_vlan_tag_rewrite,                                        \
15809   "<intfc> | sw_if_index <nn> \n"                                       \
15810   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15811   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15812 _(create_vhost_user_if,                                                 \
15813         "socket <filename> [server] [renumber <dev_instance>] "         \
15814         "[mac <mac_address>]")                                          \
15815 _(modify_vhost_user_if,                                                 \
15816         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15817         "[server] [renumber <dev_instance>]")                           \
15818 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15819 _(sw_interface_vhost_user_dump, "")                                     \
15820 _(show_version, "")                                                     \
15821 _(vxlan_gpe_add_del_tunnel,                                             \
15822   "local <addr> remote <addr> vni <nn>\n"                               \
15823     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15824   "[next-ethernet] [next-nsh]\n")                                       \
15825 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15826 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15827 _(interface_name_renumber,                                              \
15828   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15829 _(input_acl_set_interface,                                              \
15830   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15831   "  [l2-table <nn>] [del]")                                            \
15832 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15833 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
15834 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15835 _(ip_dump, "ipv4 | ipv6")                                               \
15836 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15837 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15838   "  spid_id <n> ")                                                     \
15839 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15840   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15841   "  integ_alg <alg> integ_key <hex>")                                  \
15842 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15843   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15844   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15845   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15846 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15847 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15848 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15849   "(auth_data 0x<data> | auth_data <data>)")                            \
15850 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15851   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15852 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15853   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15854   "(local|remote)")                                                     \
15855 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15856 _(delete_loopback,"sw_if_index <nn>")                                   \
15857 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15858 _(map_add_domain,                                                       \
15859   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
15860   "ip6-src <ip6addr> "                                                  \
15861   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
15862 _(map_del_domain, "index <n>")                                          \
15863 _(map_add_del_rule,                                                     \
15864   "index <n> psid <n> dst <ip6addr> [del]")                             \
15865 _(map_domain_dump, "")                                                  \
15866 _(map_rule_dump, "index <map-domain>")                                  \
15867 _(want_interface_events,  "enable|disable")                             \
15868 _(want_stats,"enable|disable")                                          \
15869 _(get_first_msg_id, "client <name>")                                    \
15870 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15871 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15872   "fib-id <nn> [ip4][ip6][default]")                                    \
15873 _(get_node_graph, " ")                                                  \
15874 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15875 _(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> "     \
15876   "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> "       \
15877   "app-data <app_data in hex> [pow] [ppc <encap|decap>]")               \
15878 _(trace_profile_apply, "id <nn> <ip6-address>/<width>"                  \
15879   " vrf_id <nn>  add | pop | none")                                     \
15880 _(trace_profile_del, "")                                                \
15881 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
15882                             " sw_if_index <sw_if_index> p <priority> "  \
15883                             "w <weight>] [del]")                        \
15884 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
15885                         "iface <intf> | sw_if_index <sw_if_index> "     \
15886                         "p <priority> w <weight> [del]")                \
15887 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
15888                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
15889                           "locator-set <locator_name> [del]")           \
15890 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
15891   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
15892 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
15893 _(lisp_gpe_enable_disable, "enable|disable")                            \
15894 _(lisp_enable_disable, "enable|disable")                                \
15895 _(lisp_gpe_add_del_iface, "up|down")                                    \
15896 _(lisp_add_del_remote_mapping, "add|del vni <vni> deid <dest-eid> "     \
15897                                "rloc <locator> p <prio> "               \
15898                                "w <weight> [rloc <loc> ... ] "          \
15899                                "action <action> [del-all]")             \
15900 _(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid "     \
15901                           "<src-eid> rloc <locator> p <prio> w <weight>"\
15902                           "[rloc <loc> ... ] action <action>")          \
15903 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
15904 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
15905 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
15906 _(lisp_locator_set_dump, "[locator-set-index <ls-index> | "             \
15907                          "locator-set <loc-set-name>] [local | remote]")\
15908 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
15909                        "[local] | [remote]")                            \
15910 _(lisp_eid_table_vni_dump, "")                                          \
15911 _(lisp_eid_table_map_dump, "l2|l3")                                     \
15912 _(lisp_gpe_tunnel_dump, "")                                             \
15913 _(lisp_map_resolver_dump, "")                                           \
15914 _(show_lisp_status, "")                                                 \
15915 _(lisp_get_map_request_itr_rlocs, "")                                   \
15916 _(show_lisp_pitr, "")                                                   \
15917 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15918 _(af_packet_delete, "name <host interface name>")                       \
15919 _(policer_add_del, "name <policer name> <params> [del]")                \
15920 _(policer_dump, "[name <policer name>]")                                \
15921 _(policer_classify_set_interface,                                       \
15922   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15923   "  [l2-table <nn>] [del]")                                            \
15924 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15925 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
15926     "[master|slave]")                                                   \
15927 _(netmap_delete, "name <interface name>")                               \
15928 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15929 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15930 _(mpls_fib_encap_dump, "")                                              \
15931 _(mpls_fib_decap_dump, "")                                              \
15932 _(classify_table_ids, "")                                               \
15933 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15934 _(classify_table_info, "table_id <nn>")                                 \
15935 _(classify_session_dump, "table_id <nn>")                               \
15936 _(ipfix_enable, "collector_address <ip4> [collector_port <nn>] "        \
15937                 "src_address <ip4> [fib_id <nn>] [path_mtu <nn>] "      \
15938                 "[template_interval <nn>]")                             \
15939 _(ipfix_dump, "")                                                       \
15940 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15941 _(pg_create_interface, "if_id <nn>")                                    \
15942 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15943 _(pg_enable_disable, "[stream <id>] disable")                           \
15944 _(ip_source_and_port_range_check_add_del,                               \
15945   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15946 _(ip_source_and_port_range_check_interface_add_del,                     \
15947   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15948   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
15949 _(ipsec_gre_add_del_tunnel,                                             \
15950   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
15951 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
15952 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")
15953
15954 /* List of command functions, CLI names map directly to functions */
15955 #define foreach_cli_function                                    \
15956 _(comment, "usage: comment <ignore-rest-of-line>")              \
15957 _(dump_interface_table, "usage: dump_interface_table")          \
15958 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15959 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15960 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15961 _(dump_stats_table, "usage: dump_stats_table")                  \
15962 _(dump_macro_table, "usage: dump_macro_table ")                 \
15963 _(dump_node_table, "usage: dump_node_table")                    \
15964 _(echo, "usage: echo <message>")                                \
15965 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15966 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
15967 _(help, "usage: help")                                          \
15968 _(q, "usage: quit")                                             \
15969 _(quit, "usage: quit")                                          \
15970 _(search_node_table, "usage: search_node_table <name>...")      \
15971 _(set, "usage: set <variable-name> <value>")                    \
15972 _(script, "usage: script <file-name>")                          \
15973 _(unset, "usage: unset <variable-name>")
15974
15975 #define _(N,n)                                  \
15976     static void vl_api_##n##_t_handler_uni      \
15977     (vl_api_##n##_t * mp)                       \
15978     {                                           \
15979         vat_main_t * vam = &vat_main;           \
15980         if (vam->json_output) {                 \
15981             vl_api_##n##_t_handler_json(mp);    \
15982         } else {                                \
15983             vl_api_##n##_t_handler(mp);         \
15984         }                                       \
15985     }
15986 foreach_vpe_api_reply_msg;
15987 #undef _
15988
15989 void
15990 vat_api_hookup (vat_main_t * vam)
15991 {
15992 #define _(N,n)                                                  \
15993     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15994                            vl_api_##n##_t_handler_uni,          \
15995                            vl_noop_handler,                     \
15996                            vl_api_##n##_t_endian,               \
15997                            vl_api_##n##_t_print,                \
15998                            sizeof(vl_api_##n##_t), 1);
15999   foreach_vpe_api_reply_msg;
16000 #undef _
16001
16002   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
16003
16004   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
16005
16006   vam->function_by_name = hash_create_string (0, sizeof (uword));
16007
16008   vam->help_by_name = hash_create_string (0, sizeof (uword));
16009
16010   /* API messages we can send */
16011 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
16012   foreach_vpe_api_msg;
16013 #undef _
16014
16015   /* Help strings */
16016 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16017   foreach_vpe_api_msg;
16018 #undef _
16019
16020   /* CLI functions */
16021 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
16022   foreach_cli_function;
16023 #undef _
16024
16025   /* Help strings */
16026 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16027   foreach_cli_function;
16028 #undef _
16029 }
16030
16031 #undef vl_api_version
16032 #define vl_api_version(n,v) static u32 vpe_api_version = v;
16033 #include <vpp-api/vpe.api.h>
16034 #undef vl_api_version
16035
16036 void
16037 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
16038 {
16039   /*
16040    * Send the main API signature in slot 0. This bit of code must
16041    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
16042    */
16043   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
16044 }
16045
16046 /*
16047  * fd.io coding-style-patch-verification: ON
16048  *
16049  * Local Variables:
16050  * eval: (c-set-style "gnu")
16051  * End:
16052  */