VPP-204 Rework and finish IPFIX implementation
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/mpls-gre/mpls.h>
39 #if DPDK > 0
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #else
43 #include <inttypes.h>
44 #endif
45 #include <vnet/map/map.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52
53 #include "vat/json_format.h"
54
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248 #if DPDK > 0
249   u32 *r = va_arg (*args, u32 *);
250
251   if (0);
252 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
253   foreach_ipsec_policy_action
254 #undef _
255     else
256     return 0;
257   return 1;
258 #else
259   return 0;
260 #endif
261 }
262
263 uword
264 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
265 {
266 #if DPDK > 0
267   u32 *r = va_arg (*args, u32 *);
268
269   if (0);
270 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
271   foreach_ipsec_crypto_alg
272 #undef _
273     else
274     return 0;
275   return 1;
276 #else
277   return 0;
278 #endif
279 }
280
281 u8 *
282 format_ipsec_crypto_alg (u8 * s, va_list * args)
283 {
284 #if DPDK > 0
285   u32 i = va_arg (*args, u32);
286   u8 *t = 0;
287
288   switch (i)
289     {
290 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
291       foreach_ipsec_crypto_alg
292 #undef _
293     default:
294       return format (s, "unknown");
295     }
296   return format (s, "%s", t);
297 #else
298   return format (s, "Unimplemented");
299 #endif
300 }
301
302 uword
303 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
304 {
305 #if DPDK > 0
306   u32 *r = va_arg (*args, u32 *);
307
308   if (0);
309 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
310   foreach_ipsec_integ_alg
311 #undef _
312     else
313     return 0;
314   return 1;
315 #else
316   return 0;
317 #endif
318 }
319
320 u8 *
321 format_ipsec_integ_alg (u8 * s, va_list * args)
322 {
323 #if DPDK > 0
324   u32 i = va_arg (*args, u32);
325   u8 *t = 0;
326
327   switch (i)
328     {
329 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
330       foreach_ipsec_integ_alg
331 #undef _
332     default:
333       return format (s, "unknown");
334     }
335   return format (s, "%s", t);
336 #else
337   return format (s, "Unsupported");
338 #endif
339 }
340
341 uword
342 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
343 {
344 #if DPDK > 0
345   u32 *r = va_arg (*args, u32 *);
346
347   if (0);
348 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
349   foreach_ikev2_auth_method
350 #undef _
351     else
352     return 0;
353   return 1;
354 #else
355   return 0;
356 #endif
357 }
358
359 uword
360 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
361 {
362 #if DPDK > 0
363   u32 *r = va_arg (*args, u32 *);
364
365   if (0);
366 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
367   foreach_ikev2_id_type
368 #undef _
369     else
370     return 0;
371   return 1;
372 #else
373   return 0;
374 #endif
375 }
376
377 uword
378 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
379 {
380   u8 *r = va_arg (*args, u8 *);
381
382   if (unformat (input, "kbps"))
383     *r = SSE2_QOS_RATE_KBPS;
384   else if (unformat (input, "pps"))
385     *r = SSE2_QOS_RATE_PPS;
386   else
387     return 0;
388   return 1;
389 }
390
391 uword
392 unformat_policer_round_type (unformat_input_t * input, va_list * args)
393 {
394   u8 *r = va_arg (*args, u8 *);
395
396   if (unformat (input, "closest"))
397     *r = SSE2_QOS_ROUND_TO_CLOSEST;
398   else if (unformat (input, "up"))
399     *r = SSE2_QOS_ROUND_TO_UP;
400   else if (unformat (input, "down"))
401     *r = SSE2_QOS_ROUND_TO_DOWN;
402   else
403     return 0;
404   return 1;
405 }
406
407 uword
408 unformat_policer_type (unformat_input_t * input, va_list * args)
409 {
410   u8 *r = va_arg (*args, u8 *);
411
412   if (unformat (input, "1r2c"))
413     *r = SSE2_QOS_POLICER_TYPE_1R2C;
414   else if (unformat (input, "1r3c"))
415     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
416   else if (unformat (input, "2r3c-2698"))
417     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
418   else if (unformat (input, "2r3c-4115"))
419     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
420   else if (unformat (input, "2r3c-mef5cf1"))
421     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
422   else
423     return 0;
424   return 1;
425 }
426
427 uword
428 unformat_dscp (unformat_input_t * input, va_list * va)
429 {
430   u8 *r = va_arg (*va, u8 *);
431
432   if (0);
433 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
434   foreach_vnet_dscp
435 #undef _
436     else
437     return 0;
438   return 1;
439 }
440
441 uword
442 unformat_policer_action_type (unformat_input_t * input, va_list * va)
443 {
444   sse2_qos_pol_action_params_st *a
445     = va_arg (*va, sse2_qos_pol_action_params_st *);
446
447   if (unformat (input, "drop"))
448     a->action_type = SSE2_QOS_ACTION_DROP;
449   else if (unformat (input, "transmit"))
450     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
451   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
452     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
453   else
454     return 0;
455   return 1;
456 }
457
458 uword
459 unformat_classify_table_type (unformat_input_t * input, va_list * va)
460 {
461   u32 *r = va_arg (*va, u32 *);
462   u32 tid;
463
464   if (unformat (input, "ip4"))
465     tid = POLICER_CLASSIFY_TABLE_IP4;
466   else if (unformat (input, "ip6"))
467     tid = POLICER_CLASSIFY_TABLE_IP6;
468   else if (unformat (input, "l2"))
469     tid = POLICER_CLASSIFY_TABLE_L2;
470   else
471     return 0;
472
473   *r = tid;
474   return 1;
475 }
476
477 u8 *
478 format_ip4_address (u8 * s, va_list * args)
479 {
480   u8 *a = va_arg (*args, u8 *);
481   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
482 }
483
484 u8 *
485 format_ip6_address (u8 * s, va_list * args)
486 {
487   ip6_address_t *a = va_arg (*args, ip6_address_t *);
488   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
489
490   i_max_n_zero = ARRAY_LEN (a->as_u16);
491   max_n_zeros = 0;
492   i_first_zero = i_max_n_zero;
493   n_zeros = 0;
494   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
495     {
496       u32 is_zero = a->as_u16[i] == 0;
497       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
498         {
499           i_first_zero = i;
500           n_zeros = 0;
501         }
502       n_zeros += is_zero;
503       if ((!is_zero && n_zeros > max_n_zeros)
504           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
505         {
506           i_max_n_zero = i_first_zero;
507           max_n_zeros = n_zeros;
508           i_first_zero = ARRAY_LEN (a->as_u16);
509           n_zeros = 0;
510         }
511     }
512
513   last_double_colon = 0;
514   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
515     {
516       if (i == i_max_n_zero && max_n_zeros > 1)
517         {
518           s = format (s, "::");
519           i += max_n_zeros - 1;
520           last_double_colon = 1;
521         }
522       else
523         {
524           s = format (s, "%s%x",
525                       (last_double_colon || i == 0) ? "" : ":",
526                       clib_net_to_host_u16 (a->as_u16[i]));
527           last_double_colon = 0;
528         }
529     }
530
531   return s;
532 }
533
534 /* Format an IP46 address. */
535 u8 *
536 format_ip46_address (u8 * s, va_list * args)
537 {
538   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
539   ip46_type_t type = va_arg (*args, ip46_type_t);
540   int is_ip4 = 1;
541
542   switch (type)
543     {
544     case IP46_TYPE_ANY:
545       is_ip4 = ip46_address_is_ip4 (ip46);
546       break;
547     case IP46_TYPE_IP4:
548       is_ip4 = 1;
549       break;
550     case IP46_TYPE_IP6:
551       is_ip4 = 0;
552       break;
553     }
554
555   return is_ip4 ?
556     format (s, "%U", format_ip4_address, &ip46->ip4) :
557     format (s, "%U", format_ip6_address, &ip46->ip6);
558 }
559
560 u8 *
561 format_ethernet_address (u8 * s, va_list * args)
562 {
563   u8 *a = va_arg (*args, u8 *);
564
565   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
566                  a[0], a[1], a[2], a[3], a[4], a[5]);
567 }
568
569 void
570 increment_v4_address (ip4_address_t * a)
571 {
572   u32 v;
573
574   v = ntohl (a->as_u32) + 1;
575   a->as_u32 = ntohl (v);
576 }
577
578 void
579 increment_v6_address (ip6_address_t * a)
580 {
581   u64 v0, v1;
582
583   v0 = clib_net_to_host_u64 (a->as_u64[0]);
584   v1 = clib_net_to_host_u64 (a->as_u64[1]);
585
586   v1 += 1;
587   if (v1 == 0)
588     v0 += 1;
589   a->as_u64[0] = clib_net_to_host_u64 (v0);
590   a->as_u64[1] = clib_net_to_host_u64 (v1);
591 }
592
593 void
594 increment_mac_address (u64 * mac)
595 {
596   u64 tmp = *mac;
597
598   tmp = clib_net_to_host_u64 (tmp);
599   tmp += 1 << 16;               /* skip unused (least significant) octets */
600   tmp = clib_host_to_net_u64 (tmp);
601   *mac = tmp;
602 }
603
604 static void vl_api_create_loopback_reply_t_handler
605   (vl_api_create_loopback_reply_t * mp)
606 {
607   vat_main_t *vam = &vat_main;
608   i32 retval = ntohl (mp->retval);
609
610   vam->retval = retval;
611   vam->regenerate_interface_table = 1;
612   vam->sw_if_index = ntohl (mp->sw_if_index);
613   vam->result_ready = 1;
614 }
615
616 static void vl_api_create_loopback_reply_t_handler_json
617   (vl_api_create_loopback_reply_t * mp)
618 {
619   vat_main_t *vam = &vat_main;
620   vat_json_node_t node;
621
622   vat_json_init_object (&node);
623   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
624   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
625
626   vat_json_print (vam->ofp, &node);
627   vat_json_free (&node);
628   vam->retval = ntohl (mp->retval);
629   vam->result_ready = 1;
630 }
631
632 static void vl_api_af_packet_create_reply_t_handler
633   (vl_api_af_packet_create_reply_t * mp)
634 {
635   vat_main_t *vam = &vat_main;
636   i32 retval = ntohl (mp->retval);
637
638   vam->retval = retval;
639   vam->regenerate_interface_table = 1;
640   vam->sw_if_index = ntohl (mp->sw_if_index);
641   vam->result_ready = 1;
642 }
643
644 static void vl_api_af_packet_create_reply_t_handler_json
645   (vl_api_af_packet_create_reply_t * mp)
646 {
647   vat_main_t *vam = &vat_main;
648   vat_json_node_t node;
649
650   vat_json_init_object (&node);
651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
652   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
653
654   vat_json_print (vam->ofp, &node);
655   vat_json_free (&node);
656
657   vam->retval = ntohl (mp->retval);
658   vam->result_ready = 1;
659 }
660
661 static void vl_api_create_vlan_subif_reply_t_handler
662   (vl_api_create_vlan_subif_reply_t * mp)
663 {
664   vat_main_t *vam = &vat_main;
665   i32 retval = ntohl (mp->retval);
666
667   vam->retval = retval;
668   vam->regenerate_interface_table = 1;
669   vam->sw_if_index = ntohl (mp->sw_if_index);
670   vam->result_ready = 1;
671 }
672
673 static void vl_api_create_vlan_subif_reply_t_handler_json
674   (vl_api_create_vlan_subif_reply_t * mp)
675 {
676   vat_main_t *vam = &vat_main;
677   vat_json_node_t node;
678
679   vat_json_init_object (&node);
680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
681   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
682
683   vat_json_print (vam->ofp, &node);
684   vat_json_free (&node);
685
686   vam->retval = ntohl (mp->retval);
687   vam->result_ready = 1;
688 }
689
690 static void vl_api_create_subif_reply_t_handler
691   (vl_api_create_subif_reply_t * mp)
692 {
693   vat_main_t *vam = &vat_main;
694   i32 retval = ntohl (mp->retval);
695
696   vam->retval = retval;
697   vam->regenerate_interface_table = 1;
698   vam->sw_if_index = ntohl (mp->sw_if_index);
699   vam->result_ready = 1;
700 }
701
702 static void vl_api_create_subif_reply_t_handler_json
703   (vl_api_create_subif_reply_t * mp)
704 {
705   vat_main_t *vam = &vat_main;
706   vat_json_node_t node;
707
708   vat_json_init_object (&node);
709   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
710   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
711
712   vat_json_print (vam->ofp, &node);
713   vat_json_free (&node);
714
715   vam->retval = ntohl (mp->retval);
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   i32 retval = ntohl (mp->retval);
724
725   vam->retval = retval;
726   vam->regenerate_interface_table = 1;
727   vam->result_ready = 1;
728 }
729
730 static void vl_api_interface_name_renumber_reply_t_handler_json
731   (vl_api_interface_name_renumber_reply_t * mp)
732 {
733   vat_main_t *vam = &vat_main;
734   vat_json_node_t node;
735
736   vat_json_init_object (&node);
737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
738
739   vat_json_print (vam->ofp, &node);
740   vat_json_free (&node);
741
742   vam->retval = ntohl (mp->retval);
743   vam->result_ready = 1;
744 }
745
746 /*
747  * Special-case: build the interface table, maintain
748  * the next loopback sw_if_index vbl.
749  */
750 static void vl_api_sw_interface_details_t_handler
751   (vl_api_sw_interface_details_t * mp)
752 {
753   vat_main_t *vam = &vat_main;
754   u8 *s = format (0, "%s%c", mp->interface_name, 0);
755
756   hash_set_mem (vam->sw_if_index_by_interface_name, s,
757                 ntohl (mp->sw_if_index));
758
759   /* In sub interface case, fill the sub interface table entry */
760   if (mp->sw_if_index != mp->sup_sw_if_index)
761     {
762       sw_interface_subif_t *sub = NULL;
763
764       vec_add2 (vam->sw_if_subif_table, sub, 1);
765
766       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
767       strncpy ((char *) sub->interface_name, (char *) s,
768                vec_len (sub->interface_name));
769       sub->sw_if_index = ntohl (mp->sw_if_index);
770       sub->sub_id = ntohl (mp->sub_id);
771
772       sub->sub_dot1ad = mp->sub_dot1ad;
773       sub->sub_number_of_tags = mp->sub_number_of_tags;
774       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
775       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
776       sub->sub_exact_match = mp->sub_exact_match;
777       sub->sub_default = mp->sub_default;
778       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
779       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
780
781       /* vlan tag rewrite */
782       sub->vtr_op = ntohl (mp->vtr_op);
783       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
784       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
785       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
786     }
787 }
788
789 static void vl_api_sw_interface_details_t_handler_json
790   (vl_api_sw_interface_details_t * mp)
791 {
792   vat_main_t *vam = &vat_main;
793   vat_json_node_t *node = NULL;
794
795   if (VAT_JSON_ARRAY != vam->json_tree.type)
796     {
797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
798       vat_json_init_array (&vam->json_tree);
799     }
800   node = vat_json_array_add (&vam->json_tree);
801
802   vat_json_init_object (node);
803   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
804   vat_json_object_add_uint (node, "sup_sw_if_index",
805                             ntohl (mp->sup_sw_if_index));
806   vat_json_object_add_uint (node, "l2_address_length",
807                             ntohl (mp->l2_address_length));
808   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
809                              sizeof (mp->l2_address));
810   vat_json_object_add_string_copy (node, "interface_name",
811                                    mp->interface_name);
812   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
813   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
814   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
815   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
816   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
817   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
818   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
819   vat_json_object_add_uint (node, "sub_number_of_tags",
820                             mp->sub_number_of_tags);
821   vat_json_object_add_uint (node, "sub_outer_vlan_id",
822                             ntohs (mp->sub_outer_vlan_id));
823   vat_json_object_add_uint (node, "sub_inner_vlan_id",
824                             ntohs (mp->sub_inner_vlan_id));
825   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
826   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
827   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
828                             mp->sub_outer_vlan_id_any);
829   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
830                             mp->sub_inner_vlan_id_any);
831   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
832   vat_json_object_add_uint (node, "vtr_push_dot1q",
833                             ntohl (mp->vtr_push_dot1q));
834   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
835   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   vat_main_t *vam = &vat_main;
842   if (vam->interface_event_display)
843     errmsg ("interface flags: sw_if_index %d %s %s\n",
844             ntohl (mp->sw_if_index),
845             mp->admin_up_down ? "admin-up" : "admin-down",
846             mp->link_up_down ? "link-up" : "link-down");
847 }
848
849 static void vl_api_sw_interface_set_flags_t_handler_json
850   (vl_api_sw_interface_set_flags_t * mp)
851 {
852   /* JSON output not supported */
853 }
854
855 static void
856 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->shmem_result = (u8 *) mp->reply_in_shmem;
863   vam->result_ready = 1;
864 }
865
866 static void
867 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
868 {
869   vat_main_t *vam = &vat_main;
870   vat_json_node_t node;
871   api_main_t *am = &api_main;
872   void *oldheap;
873   u8 *reply;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "reply_in_shmem",
878                             ntohl (mp->reply_in_shmem));
879   /* Toss the shared-memory original... */
880   pthread_mutex_lock (&am->vlib_rp->mutex);
881   oldheap = svm_push_data_heap (am->vlib_rp);
882
883   reply = (u8 *) (mp->reply_in_shmem);
884   vec_free (reply);
885
886   svm_pop_heap (oldheap);
887   pthread_mutex_unlock (&am->vlib_rp->mutex);
888
889   vat_json_print (vam->ofp, &node);
890   vat_json_free (&node);
891
892   vam->retval = ntohl (mp->retval);
893   vam->result_ready = 1;
894 }
895
896 static void
897 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   i32 retval = ntohl (mp->retval);
901
902   vam->retval = retval;
903   vam->cmd_reply = mp->reply;
904   vam->result_ready = 1;
905 }
906
907 static void
908 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
909 {
910   vat_main_t *vam = &vat_main;
911   vat_json_node_t node;
912
913   vat_json_init_object (&node);
914   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
915   vat_json_object_add_string_copy (&node, "reply", mp->reply);
916
917   vat_json_print (vam->ofp, &node);
918   vat_json_free (&node);
919
920   vam->retval = ntohl (mp->retval);
921   vam->result_ready = 1;
922 }
923
924 static void vl_api_classify_add_del_table_reply_t_handler
925   (vl_api_classify_add_del_table_reply_t * mp)
926 {
927   vat_main_t *vam = &vat_main;
928   i32 retval = ntohl (mp->retval);
929   if (vam->async_mode)
930     {
931       vam->async_errors += (retval < 0);
932     }
933   else
934     {
935       vam->retval = retval;
936       if (retval == 0 &&
937           ((mp->new_table_index != 0xFFFFFFFF) ||
938            (mp->skip_n_vectors != 0xFFFFFFFF) ||
939            (mp->match_n_vectors != 0xFFFFFFFF)))
940         /*
941          * Note: this is just barely thread-safe, depends on
942          * the main thread spinning waiting for an answer...
943          */
944         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
945                 ntohl (mp->new_table_index),
946                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
947       vam->result_ready = 1;
948     }
949 }
950
951 static void vl_api_classify_add_del_table_reply_t_handler_json
952   (vl_api_classify_add_del_table_reply_t * mp)
953 {
954   vat_main_t *vam = &vat_main;
955   vat_json_node_t node;
956
957   vat_json_init_object (&node);
958   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
959   vat_json_object_add_uint (&node, "new_table_index",
960                             ntohl (mp->new_table_index));
961   vat_json_object_add_uint (&node, "skip_n_vectors",
962                             ntohl (mp->skip_n_vectors));
963   vat_json_object_add_uint (&node, "match_n_vectors",
964                             ntohl (mp->match_n_vectors));
965
966   vat_json_print (vam->ofp, &node);
967   vat_json_free (&node);
968
969   vam->retval = ntohl (mp->retval);
970   vam->result_ready = 1;
971 }
972
973 static void vl_api_get_node_index_reply_t_handler
974   (vl_api_get_node_index_reply_t * mp)
975 {
976   vat_main_t *vam = &vat_main;
977   i32 retval = ntohl (mp->retval);
978   if (vam->async_mode)
979     {
980       vam->async_errors += (retval < 0);
981     }
982   else
983     {
984       vam->retval = retval;
985       if (retval == 0)
986         errmsg ("node index %d\n", ntohl (mp->node_index));
987       vam->result_ready = 1;
988     }
989 }
990
991 static void vl_api_get_node_index_reply_t_handler_json
992   (vl_api_get_node_index_reply_t * mp)
993 {
994   vat_main_t *vam = &vat_main;
995   vat_json_node_t node;
996
997   vat_json_init_object (&node);
998   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
999   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1000
1001   vat_json_print (vam->ofp, &node);
1002   vat_json_free (&node);
1003
1004   vam->retval = ntohl (mp->retval);
1005   vam->result_ready = 1;
1006 }
1007
1008 static void vl_api_get_next_index_reply_t_handler
1009   (vl_api_get_next_index_reply_t * mp)
1010 {
1011   vat_main_t *vam = &vat_main;
1012   i32 retval = ntohl (mp->retval);
1013   if (vam->async_mode)
1014     {
1015       vam->async_errors += (retval < 0);
1016     }
1017   else
1018     {
1019       vam->retval = retval;
1020       if (retval == 0)
1021         errmsg ("next node index %d\n", ntohl (mp->next_index));
1022       vam->result_ready = 1;
1023     }
1024 }
1025
1026 static void vl_api_get_next_index_reply_t_handler_json
1027   (vl_api_get_next_index_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   vat_json_node_t node;
1031
1032   vat_json_init_object (&node);
1033   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1034   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1035
1036   vat_json_print (vam->ofp, &node);
1037   vat_json_free (&node);
1038
1039   vam->retval = ntohl (mp->retval);
1040   vam->result_ready = 1;
1041 }
1042
1043 static void vl_api_add_node_next_reply_t_handler
1044   (vl_api_add_node_next_reply_t * mp)
1045 {
1046   vat_main_t *vam = &vat_main;
1047   i32 retval = ntohl (mp->retval);
1048   if (vam->async_mode)
1049     {
1050       vam->async_errors += (retval < 0);
1051     }
1052   else
1053     {
1054       vam->retval = retval;
1055       if (retval == 0)
1056         errmsg ("next index %d\n", ntohl (mp->next_index));
1057       vam->result_ready = 1;
1058     }
1059 }
1060
1061 static void vl_api_add_node_next_reply_t_handler_json
1062   (vl_api_add_node_next_reply_t * mp)
1063 {
1064   vat_main_t *vam = &vat_main;
1065   vat_json_node_t node;
1066
1067   vat_json_init_object (&node);
1068   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1069   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1070
1071   vat_json_print (vam->ofp, &node);
1072   vat_json_free (&node);
1073
1074   vam->retval = ntohl (mp->retval);
1075   vam->result_ready = 1;
1076 }
1077
1078 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
1079   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1080 {
1081   vat_main_t *vam = &vat_main;
1082   i32 retval = ntohl (mp->retval);
1083   u32 sw_if_index = ntohl (mp->tunnel_sw_if_index);
1084
1085   if (retval >= 0 && sw_if_index != (u32) ~ 0)
1086     {
1087       errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1088     }
1089   vam->retval = retval;
1090   vam->result_ready = 1;
1091 }
1092
1093 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1094   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1095 {
1096   vat_main_t *vam = &vat_main;
1097   vat_json_node_t node;
1098
1099   vat_json_init_object (&node);
1100   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1101   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1102                             ntohl (mp->tunnel_sw_if_index));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111
1112 static void vl_api_show_version_reply_t_handler
1113   (vl_api_show_version_reply_t * mp)
1114 {
1115   vat_main_t *vam = &vat_main;
1116   i32 retval = ntohl (mp->retval);
1117
1118   if (retval >= 0)
1119     {
1120       errmsg ("        program: %s\n", mp->program);
1121       errmsg ("        version: %s\n", mp->version);
1122       errmsg ("     build date: %s\n", mp->build_date);
1123       errmsg ("build directory: %s\n", mp->build_directory);
1124     }
1125   vam->retval = retval;
1126   vam->result_ready = 1;
1127 }
1128
1129 static void vl_api_show_version_reply_t_handler_json
1130   (vl_api_show_version_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_string_copy (&node, "program", mp->program);
1138   vat_json_object_add_string_copy (&node, "version", mp->version);
1139   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1140   vat_json_object_add_string_copy (&node, "build_directory",
1141                                    mp->build_directory);
1142
1143   vat_json_print (vam->ofp, &node);
1144   vat_json_free (&node);
1145
1146   vam->retval = ntohl (mp->retval);
1147   vam->result_ready = 1;
1148 }
1149
1150 static void
1151 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1152 {
1153   vat_main_t *vam = &vat_main;
1154   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1155           mp->mac_ip ? "mac/ip binding" : "address resolution",
1156           format_ip4_address, &mp->address,
1157           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1158 }
1159
1160 static void
1161 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1162 {
1163   /* JSON output not supported */
1164 }
1165
1166 static void
1167 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1168 {
1169   vat_main_t *vam = &vat_main;
1170   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1171           mp->mac_ip ? "mac/ip binding" : "address resolution",
1172           format_ip6_address, mp->address,
1173           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1174 }
1175
1176 static void
1177 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1178 {
1179   /* JSON output not supported */
1180 }
1181
1182 /*
1183  * Special-case: build the bridge domain table, maintain
1184  * the next bd id vbl.
1185  */
1186 static void vl_api_bridge_domain_details_t_handler
1187   (vl_api_bridge_domain_details_t * mp)
1188 {
1189   vat_main_t *vam = &vat_main;
1190   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1191
1192   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1193            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1194
1195   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1196            ntohl (mp->bd_id), mp->learn, mp->forward,
1197            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1198
1199   if (n_sw_ifs)
1200     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1201              "Interface Name");
1202 }
1203
1204 static void vl_api_bridge_domain_details_t_handler_json
1205   (vl_api_bridge_domain_details_t * mp)
1206 {
1207   vat_main_t *vam = &vat_main;
1208   vat_json_node_t *node, *array = NULL;
1209
1210   if (VAT_JSON_ARRAY != vam->json_tree.type)
1211     {
1212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1213       vat_json_init_array (&vam->json_tree);
1214     }
1215   node = vat_json_array_add (&vam->json_tree);
1216
1217   vat_json_init_object (node);
1218   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1219   vat_json_object_add_uint (node, "flood", mp->flood);
1220   vat_json_object_add_uint (node, "forward", mp->forward);
1221   vat_json_object_add_uint (node, "learn", mp->learn);
1222   vat_json_object_add_uint (node, "bvi_sw_if_index",
1223                             ntohl (mp->bvi_sw_if_index));
1224   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1225   array = vat_json_object_add (node, "sw_if");
1226   vat_json_init_array (array);
1227 }
1228
1229 /*
1230  * Special-case: build the bridge domain sw if table.
1231  */
1232 static void vl_api_bridge_domain_sw_if_details_t_handler
1233   (vl_api_bridge_domain_sw_if_details_t * mp)
1234 {
1235   vat_main_t *vam = &vat_main;
1236   hash_pair_t *p;
1237   u8 *sw_if_name = 0;
1238   u32 sw_if_index;
1239
1240   sw_if_index = ntohl (mp->sw_if_index);
1241   /* *INDENT-OFF* */
1242   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1243   ({
1244     if ((u32) p->value[0] == sw_if_index)
1245       {
1246         sw_if_name = (u8 *)(p->key);
1247         break;
1248       }
1249   }));
1250   /* *INDENT-ON* */
1251
1252   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1253            mp->shg, sw_if_name ? (char *) sw_if_name :
1254            "sw_if_index not found!");
1255 }
1256
1257 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1258   (vl_api_bridge_domain_sw_if_details_t * mp)
1259 {
1260   vat_main_t *vam = &vat_main;
1261   vat_json_node_t *node = NULL;
1262   uword last_index = 0;
1263
1264   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1265   ASSERT (vec_len (vam->json_tree.array) >= 1);
1266   last_index = vec_len (vam->json_tree.array) - 1;
1267   node = &vam->json_tree.array[last_index];
1268   node = vat_json_object_get_element (node, "sw_if");
1269   ASSERT (NULL != node);
1270   node = vat_json_array_add (node);
1271
1272   vat_json_init_object (node);
1273   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1274   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1275   vat_json_object_add_uint (node, "shg", mp->shg);
1276 }
1277
1278 static void vl_api_control_ping_reply_t_handler
1279   (vl_api_control_ping_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   i32 retval = ntohl (mp->retval);
1283   if (vam->async_mode)
1284     {
1285       vam->async_errors += (retval < 0);
1286     }
1287   else
1288     {
1289       vam->retval = retval;
1290       vam->result_ready = 1;
1291     }
1292 }
1293
1294 static void vl_api_control_ping_reply_t_handler_json
1295   (vl_api_control_ping_reply_t * mp)
1296 {
1297   vat_main_t *vam = &vat_main;
1298   i32 retval = ntohl (mp->retval);
1299
1300   if (VAT_JSON_NONE != vam->json_tree.type)
1301     {
1302       vat_json_print (vam->ofp, &vam->json_tree);
1303       vat_json_free (&vam->json_tree);
1304       vam->json_tree.type = VAT_JSON_NONE;
1305     }
1306   else
1307     {
1308       /* just print [] */
1309       vat_json_init_array (&vam->json_tree);
1310       vat_json_print (vam->ofp, &vam->json_tree);
1311       vam->json_tree.type = VAT_JSON_NONE;
1312     }
1313
1314   vam->retval = retval;
1315   vam->result_ready = 1;
1316 }
1317
1318 static void vl_api_noprint_control_ping_reply_t_handler
1319   (vl_api_noprint_control_ping_reply_t * mp)
1320 {
1321   vat_main_t *vam = &vat_main;
1322   i32 retval = ntohl (mp->retval);
1323   if (vam->async_mode)
1324     {
1325       vam->async_errors += (retval < 0);
1326     }
1327   else
1328     {
1329       vam->retval = retval;
1330       vam->result_ready = 1;
1331     }
1332 }
1333
1334 static void vl_api_noprint_control_ping_reply_t_handler_json
1335   (vl_api_noprint_control_ping_reply_t * mp)
1336 {
1337   vat_main_t *vam = &vat_main;
1338   i32 retval = ntohl (mp->retval);
1339
1340   if (vam->noprint_msg)
1341     {
1342       vam->retval = retval;
1343       vam->result_ready = 1;
1344       return;
1345     }
1346
1347   if (VAT_JSON_NONE != vam->json_tree.type)
1348     {
1349       vat_json_print (vam->ofp, &vam->json_tree);
1350       vat_json_free (&vam->json_tree);
1351       vam->json_tree.type = VAT_JSON_NONE;
1352     }
1353   else
1354     {
1355       /* just print [] */
1356       vat_json_init_array (&vam->json_tree);
1357       vat_json_print (vam->ofp, &vam->json_tree);
1358       vam->json_tree.type = VAT_JSON_NONE;
1359     }
1360
1361   vam->retval = retval;
1362   vam->result_ready = 1;
1363 }
1364
1365 static void
1366 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1367 {
1368   vat_main_t *vam = &vat_main;
1369   i32 retval = ntohl (mp->retval);
1370   if (vam->async_mode)
1371     {
1372       vam->async_errors += (retval < 0);
1373     }
1374   else
1375     {
1376       vam->retval = retval;
1377       vam->result_ready = 1;
1378     }
1379 }
1380
1381 static void vl_api_l2_flags_reply_t_handler_json
1382   (vl_api_l2_flags_reply_t * mp)
1383 {
1384   vat_main_t *vam = &vat_main;
1385   vat_json_node_t node;
1386
1387   vat_json_init_object (&node);
1388   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1389   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1390                             ntohl (mp->resulting_feature_bitmap));
1391
1392   vat_json_print (vam->ofp, &node);
1393   vat_json_free (&node);
1394
1395   vam->retval = ntohl (mp->retval);
1396   vam->result_ready = 1;
1397 }
1398
1399 static void vl_api_bridge_flags_reply_t_handler
1400   (vl_api_bridge_flags_reply_t * mp)
1401 {
1402   vat_main_t *vam = &vat_main;
1403   i32 retval = ntohl (mp->retval);
1404   if (vam->async_mode)
1405     {
1406       vam->async_errors += (retval < 0);
1407     }
1408   else
1409     {
1410       vam->retval = retval;
1411       vam->result_ready = 1;
1412     }
1413 }
1414
1415 static void vl_api_bridge_flags_reply_t_handler_json
1416   (vl_api_bridge_flags_reply_t * mp)
1417 {
1418   vat_main_t *vam = &vat_main;
1419   vat_json_node_t node;
1420
1421   vat_json_init_object (&node);
1422   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1423   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1424                             ntohl (mp->resulting_feature_bitmap));
1425
1426   vat_json_print (vam->ofp, &node);
1427   vat_json_free (&node);
1428
1429   vam->retval = ntohl (mp->retval);
1430   vam->result_ready = 1;
1431 }
1432
1433 static void vl_api_tap_connect_reply_t_handler
1434   (vl_api_tap_connect_reply_t * mp)
1435 {
1436   vat_main_t *vam = &vat_main;
1437   i32 retval = ntohl (mp->retval);
1438   if (vam->async_mode)
1439     {
1440       vam->async_errors += (retval < 0);
1441     }
1442   else
1443     {
1444       vam->retval = retval;
1445       vam->sw_if_index = ntohl (mp->sw_if_index);
1446       vam->result_ready = 1;
1447     }
1448
1449 }
1450
1451 static void vl_api_tap_connect_reply_t_handler_json
1452   (vl_api_tap_connect_reply_t * mp)
1453 {
1454   vat_main_t *vam = &vat_main;
1455   vat_json_node_t node;
1456
1457   vat_json_init_object (&node);
1458   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1459   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1460
1461   vat_json_print (vam->ofp, &node);
1462   vat_json_free (&node);
1463
1464   vam->retval = ntohl (mp->retval);
1465   vam->result_ready = 1;
1466
1467 }
1468
1469 static void
1470 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1471 {
1472   vat_main_t *vam = &vat_main;
1473   i32 retval = ntohl (mp->retval);
1474   if (vam->async_mode)
1475     {
1476       vam->async_errors += (retval < 0);
1477     }
1478   else
1479     {
1480       vam->retval = retval;
1481       vam->sw_if_index = ntohl (mp->sw_if_index);
1482       vam->result_ready = 1;
1483     }
1484 }
1485
1486 static void vl_api_tap_modify_reply_t_handler_json
1487   (vl_api_tap_modify_reply_t * mp)
1488 {
1489   vat_main_t *vam = &vat_main;
1490   vat_json_node_t node;
1491
1492   vat_json_init_object (&node);
1493   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1494   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1495
1496   vat_json_print (vam->ofp, &node);
1497   vat_json_free (&node);
1498
1499   vam->retval = ntohl (mp->retval);
1500   vam->result_ready = 1;
1501 }
1502
1503 static void
1504 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1505 {
1506   vat_main_t *vam = &vat_main;
1507   i32 retval = ntohl (mp->retval);
1508   if (vam->async_mode)
1509     {
1510       vam->async_errors += (retval < 0);
1511     }
1512   else
1513     {
1514       vam->retval = retval;
1515       vam->result_ready = 1;
1516     }
1517 }
1518
1519 static void vl_api_tap_delete_reply_t_handler_json
1520   (vl_api_tap_delete_reply_t * mp)
1521 {
1522   vat_main_t *vam = &vat_main;
1523   vat_json_node_t node;
1524
1525   vat_json_init_object (&node);
1526   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1527
1528   vat_json_print (vam->ofp, &node);
1529   vat_json_free (&node);
1530
1531   vam->retval = ntohl (mp->retval);
1532   vam->result_ready = 1;
1533 }
1534
1535 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1536   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1537 {
1538   vat_main_t *vam = &vat_main;
1539   i32 retval = ntohl (mp->retval);
1540   if (vam->async_mode)
1541     {
1542       vam->async_errors += (retval < 0);
1543     }
1544   else
1545     {
1546       vam->retval = retval;
1547       vam->result_ready = 1;
1548     }
1549 }
1550
1551 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1552   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1553 {
1554   vat_main_t *vam = &vat_main;
1555   vat_json_node_t node;
1556
1557   vat_json_init_object (&node);
1558   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1559   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1560                             ntohl (mp->tunnel_sw_if_index));
1561
1562   vat_json_print (vam->ofp, &node);
1563   vat_json_free (&node);
1564
1565   vam->retval = ntohl (mp->retval);
1566   vam->result_ready = 1;
1567 }
1568
1569 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1570   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1571 {
1572   vat_main_t *vam = &vat_main;
1573   i32 retval = ntohl (mp->retval);
1574   if (vam->async_mode)
1575     {
1576       vam->async_errors += (retval < 0);
1577     }
1578   else
1579     {
1580       vam->retval = retval;
1581       vam->sw_if_index = ntohl (mp->sw_if_index);
1582       vam->result_ready = 1;
1583     }
1584 }
1585
1586 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1587   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1588 {
1589   vat_main_t *vam = &vat_main;
1590   vat_json_node_t node;
1591
1592   vat_json_init_object (&node);
1593   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1594   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1595
1596   vat_json_print (vam->ofp, &node);
1597   vat_json_free (&node);
1598
1599   vam->retval = ntohl (mp->retval);
1600   vam->result_ready = 1;
1601 }
1602
1603
1604 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1605   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1606 {
1607   vat_main_t *vam = &vat_main;
1608   i32 retval = ntohl (mp->retval);
1609   if (vam->async_mode)
1610     {
1611       vam->async_errors += (retval < 0);
1612     }
1613   else
1614     {
1615       vam->retval = retval;
1616       vam->result_ready = 1;
1617     }
1618 }
1619
1620 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1621   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1622 {
1623   vat_main_t *vam = &vat_main;
1624   vat_json_node_t node;
1625
1626   vat_json_init_object (&node);
1627   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1628   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1629
1630   vat_json_print (vam->ofp, &node);
1631   vat_json_free (&node);
1632
1633   vam->retval = ntohl (mp->retval);
1634   vam->result_ready = 1;
1635 }
1636
1637 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1638   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1639 {
1640   vat_main_t *vam = &vat_main;
1641   i32 retval = ntohl (mp->retval);
1642   if (vam->async_mode)
1643     {
1644       vam->async_errors += (retval < 0);
1645     }
1646   else
1647     {
1648       vam->retval = retval;
1649       vam->sw_if_index = ntohl (mp->sw_if_index);
1650       vam->result_ready = 1;
1651     }
1652 }
1653
1654 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1655   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1656 {
1657   vat_main_t *vam = &vat_main;
1658   vat_json_node_t node;
1659
1660   vat_json_init_object (&node);
1661   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1662   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1663
1664   vat_json_print (vam->ofp, &node);
1665   vat_json_free (&node);
1666
1667   vam->retval = ntohl (mp->retval);
1668   vam->result_ready = 1;
1669 }
1670
1671 static void vl_api_gre_add_del_tunnel_reply_t_handler
1672   (vl_api_gre_add_del_tunnel_reply_t * mp)
1673 {
1674   vat_main_t *vam = &vat_main;
1675   i32 retval = ntohl (mp->retval);
1676   if (vam->async_mode)
1677     {
1678       vam->async_errors += (retval < 0);
1679     }
1680   else
1681     {
1682       vam->retval = retval;
1683       vam->sw_if_index = ntohl (mp->sw_if_index);
1684       vam->result_ready = 1;
1685     }
1686 }
1687
1688 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1689   (vl_api_gre_add_del_tunnel_reply_t * mp)
1690 {
1691   vat_main_t *vam = &vat_main;
1692   vat_json_node_t node;
1693
1694   vat_json_init_object (&node);
1695   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1696   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1697
1698   vat_json_print (vam->ofp, &node);
1699   vat_json_free (&node);
1700
1701   vam->retval = ntohl (mp->retval);
1702   vam->result_ready = 1;
1703 }
1704
1705 static void vl_api_create_vhost_user_if_reply_t_handler
1706   (vl_api_create_vhost_user_if_reply_t * mp)
1707 {
1708   vat_main_t *vam = &vat_main;
1709   i32 retval = ntohl (mp->retval);
1710   if (vam->async_mode)
1711     {
1712       vam->async_errors += (retval < 0);
1713     }
1714   else
1715     {
1716       vam->retval = retval;
1717       vam->sw_if_index = ntohl (mp->sw_if_index);
1718       vam->result_ready = 1;
1719     }
1720 }
1721
1722 static void vl_api_create_vhost_user_if_reply_t_handler_json
1723   (vl_api_create_vhost_user_if_reply_t * mp)
1724 {
1725   vat_main_t *vam = &vat_main;
1726   vat_json_node_t node;
1727
1728   vat_json_init_object (&node);
1729   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1730   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1731
1732   vat_json_print (vam->ofp, &node);
1733   vat_json_free (&node);
1734
1735   vam->retval = ntohl (mp->retval);
1736   vam->result_ready = 1;
1737 }
1738
1739 static void vl_api_ip_address_details_t_handler
1740   (vl_api_ip_address_details_t * mp)
1741 {
1742   vat_main_t *vam = &vat_main;
1743   static ip_address_details_t empty_ip_address_details = { {0} };
1744   ip_address_details_t *address = NULL;
1745   ip_details_t *current_ip_details = NULL;
1746   ip_details_t *details = NULL;
1747
1748   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1749
1750   if (!details || vam->current_sw_if_index >= vec_len (details)
1751       || !details[vam->current_sw_if_index].present)
1752     {
1753       errmsg ("ip address details arrived but not stored\n");
1754       errmsg ("ip_dump should be called first\n");
1755       return;
1756     }
1757
1758   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1759
1760 #define addresses (current_ip_details->addr)
1761
1762   vec_validate_init_empty (addresses, vec_len (addresses),
1763                            empty_ip_address_details);
1764
1765   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1766
1767   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1768   address->prefix_length = mp->prefix_length;
1769 #undef addresses
1770 }
1771
1772 static void vl_api_ip_address_details_t_handler_json
1773   (vl_api_ip_address_details_t * mp)
1774 {
1775   vat_main_t *vam = &vat_main;
1776   vat_json_node_t *node = NULL;
1777   struct in6_addr ip6;
1778   struct in_addr ip4;
1779
1780   if (VAT_JSON_ARRAY != vam->json_tree.type)
1781     {
1782       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1783       vat_json_init_array (&vam->json_tree);
1784     }
1785   node = vat_json_array_add (&vam->json_tree);
1786
1787   vat_json_init_object (node);
1788   if (vam->is_ipv6)
1789     {
1790       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1791       vat_json_object_add_ip6 (node, "ip", ip6);
1792     }
1793   else
1794     {
1795       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1796       vat_json_object_add_ip4 (node, "ip", ip4);
1797     }
1798   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1799 }
1800
1801 static void
1802 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1803 {
1804   vat_main_t *vam = &vat_main;
1805   static ip_details_t empty_ip_details = { 0 };
1806   ip_details_t *ip = NULL;
1807   u32 sw_if_index = ~0;
1808
1809   sw_if_index = ntohl (mp->sw_if_index);
1810
1811   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1812                            sw_if_index, empty_ip_details);
1813
1814   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1815                          sw_if_index);
1816
1817   ip->present = 1;
1818 }
1819
1820 static void
1821 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1822 {
1823   vat_main_t *vam = &vat_main;
1824
1825   if (VAT_JSON_ARRAY != vam->json_tree.type)
1826     {
1827       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1828       vat_json_init_array (&vam->json_tree);
1829     }
1830   vat_json_array_add_uint (&vam->json_tree,
1831                            clib_net_to_host_u32 (mp->sw_if_index));
1832 }
1833
1834 static void vl_api_map_domain_details_t_handler_json
1835   (vl_api_map_domain_details_t * mp)
1836 {
1837   vat_json_node_t *node = NULL;
1838   vat_main_t *vam = &vat_main;
1839   struct in6_addr ip6;
1840   struct in_addr ip4;
1841
1842   if (VAT_JSON_ARRAY != vam->json_tree.type)
1843     {
1844       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1845       vat_json_init_array (&vam->json_tree);
1846     }
1847
1848   node = vat_json_array_add (&vam->json_tree);
1849   vat_json_init_object (node);
1850
1851   vat_json_object_add_uint (node, "domain_index",
1852                             clib_net_to_host_u32 (mp->domain_index));
1853   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1854   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1855   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1856   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1857   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1858   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1859   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1860   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1861   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1862   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1863   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1864   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1865   vat_json_object_add_uint (node, "flags", mp->flags);
1866   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1867   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1868 }
1869
1870 static void vl_api_map_domain_details_t_handler
1871   (vl_api_map_domain_details_t * mp)
1872 {
1873   vat_main_t *vam = &vat_main;
1874
1875   if (mp->is_translation)
1876     {
1877       fformat (vam->ofp,
1878                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1879                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1880                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1881                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1882                clib_net_to_host_u32 (mp->domain_index));
1883     }
1884   else
1885     {
1886       fformat (vam->ofp,
1887                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1888                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1889                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1890                format_ip6_address, mp->ip6_src,
1891                clib_net_to_host_u32 (mp->domain_index));
1892     }
1893   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1894            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1895            mp->is_translation ? "map-t" : "");
1896 }
1897
1898 static void vl_api_map_rule_details_t_handler_json
1899   (vl_api_map_rule_details_t * mp)
1900 {
1901   struct in6_addr ip6;
1902   vat_json_node_t *node = NULL;
1903   vat_main_t *vam = &vat_main;
1904
1905   if (VAT_JSON_ARRAY != vam->json_tree.type)
1906     {
1907       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1908       vat_json_init_array (&vam->json_tree);
1909     }
1910
1911   node = vat_json_array_add (&vam->json_tree);
1912   vat_json_init_object (node);
1913
1914   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1915   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1916   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1917 }
1918
1919 static void
1920 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1921 {
1922   vat_main_t *vam = &vat_main;
1923   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1924            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1925 }
1926
1927 static void
1928 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1929 {
1930   vat_main_t *vam = &vat_main;
1931   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1932           "router_addr %U host_mac %U\n",
1933           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1934           format_ip4_address, &mp->host_address,
1935           format_ip4_address, &mp->router_address,
1936           format_ethernet_address, mp->host_mac);
1937 }
1938
1939 static void vl_api_dhcp_compl_event_t_handler_json
1940   (vl_api_dhcp_compl_event_t * mp)
1941 {
1942   /* JSON output not supported */
1943 }
1944
1945 static void
1946 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1947                               u32 counter)
1948 {
1949   vat_main_t *vam = &vat_main;
1950   static u64 default_counter = 0;
1951
1952   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1953                            NULL);
1954   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1955                            sw_if_index, default_counter);
1956   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1957 }
1958
1959 static void
1960 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1961                                 interface_counter_t counter)
1962 {
1963   vat_main_t *vam = &vat_main;
1964   static interface_counter_t default_counter = { 0, };
1965
1966   vec_validate_init_empty (vam->combined_interface_counters,
1967                            vnet_counter_type, NULL);
1968   vec_validate_init_empty (vam->combined_interface_counters
1969                            [vnet_counter_type], sw_if_index, default_counter);
1970   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1971 }
1972
1973 static void vl_api_vnet_interface_counters_t_handler
1974   (vl_api_vnet_interface_counters_t * mp)
1975 {
1976   /* not supported */
1977 }
1978
1979 static void vl_api_vnet_interface_counters_t_handler_json
1980   (vl_api_vnet_interface_counters_t * mp)
1981 {
1982   interface_counter_t counter;
1983   vlib_counter_t *v;
1984   u64 *v_packets;
1985   u64 packets;
1986   u32 count;
1987   u32 first_sw_if_index;
1988   int i;
1989
1990   count = ntohl (mp->count);
1991   first_sw_if_index = ntohl (mp->first_sw_if_index);
1992
1993   if (!mp->is_combined)
1994     {
1995       v_packets = (u64 *) & mp->data;
1996       for (i = 0; i < count; i++)
1997         {
1998           packets =
1999             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2000           set_simple_interface_counter (mp->vnet_counter_type,
2001                                         first_sw_if_index + i, packets);
2002           v_packets++;
2003         }
2004     }
2005   else
2006     {
2007       v = (vlib_counter_t *) & mp->data;
2008       for (i = 0; i < count; i++)
2009         {
2010           counter.packets =
2011             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2012           counter.bytes =
2013             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2014           set_combined_interface_counter (mp->vnet_counter_type,
2015                                           first_sw_if_index + i, counter);
2016           v++;
2017         }
2018     }
2019 }
2020
2021 static u32
2022 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2023 {
2024   vat_main_t *vam = &vat_main;
2025   u32 i;
2026
2027   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2028     {
2029       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2030         {
2031           return i;
2032         }
2033     }
2034   return ~0;
2035 }
2036
2037 static u32
2038 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2039 {
2040   vat_main_t *vam = &vat_main;
2041   u32 i;
2042
2043   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2044     {
2045       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2046         {
2047           return i;
2048         }
2049     }
2050   return ~0;
2051 }
2052
2053 static void vl_api_vnet_ip4_fib_counters_t_handler
2054   (vl_api_vnet_ip4_fib_counters_t * mp)
2055 {
2056   /* not supported */
2057 }
2058
2059 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2060   (vl_api_vnet_ip4_fib_counters_t * mp)
2061 {
2062   vat_main_t *vam = &vat_main;
2063   vl_api_ip4_fib_counter_t *v;
2064   ip4_fib_counter_t *counter;
2065   struct in_addr ip4;
2066   u32 vrf_id;
2067   u32 vrf_index;
2068   u32 count;
2069   int i;
2070
2071   vrf_id = ntohl (mp->vrf_id);
2072   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2073   if (~0 == vrf_index)
2074     {
2075       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2076       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2077       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2078       vec_validate (vam->ip4_fib_counters, vrf_index);
2079       vam->ip4_fib_counters[vrf_index] = NULL;
2080     }
2081
2082   vec_free (vam->ip4_fib_counters[vrf_index]);
2083   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2084   count = ntohl (mp->count);
2085   for (i = 0; i < count; i++)
2086     {
2087       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2088       counter = &vam->ip4_fib_counters[vrf_index][i];
2089       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2090       counter->address = ip4;
2091       counter->address_length = v->address_length;
2092       counter->packets = clib_net_to_host_u64 (v->packets);
2093       counter->bytes = clib_net_to_host_u64 (v->bytes);
2094       v++;
2095     }
2096 }
2097
2098 static void vl_api_vnet_ip6_fib_counters_t_handler
2099   (vl_api_vnet_ip6_fib_counters_t * mp)
2100 {
2101   /* not supported */
2102 }
2103
2104 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2105   (vl_api_vnet_ip6_fib_counters_t * mp)
2106 {
2107   vat_main_t *vam = &vat_main;
2108   vl_api_ip6_fib_counter_t *v;
2109   ip6_fib_counter_t *counter;
2110   struct in6_addr ip6;
2111   u32 vrf_id;
2112   u32 vrf_index;
2113   u32 count;
2114   int i;
2115
2116   vrf_id = ntohl (mp->vrf_id);
2117   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2118   if (~0 == vrf_index)
2119     {
2120       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2121       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2122       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2123       vec_validate (vam->ip6_fib_counters, vrf_index);
2124       vam->ip6_fib_counters[vrf_index] = NULL;
2125     }
2126
2127   vec_free (vam->ip6_fib_counters[vrf_index]);
2128   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2129   count = ntohl (mp->count);
2130   for (i = 0; i < count; i++)
2131     {
2132       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2133       counter = &vam->ip6_fib_counters[vrf_index][i];
2134       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2135       counter->address = ip6;
2136       counter->address_length = v->address_length;
2137       counter->packets = clib_net_to_host_u64 (v->packets);
2138       counter->bytes = clib_net_to_host_u64 (v->bytes);
2139       v++;
2140     }
2141 }
2142
2143 static void vl_api_get_first_msg_id_reply_t_handler
2144   (vl_api_get_first_msg_id_reply_t * mp)
2145 {
2146   vat_main_t *vam = &vat_main;
2147   i32 retval = ntohl (mp->retval);
2148
2149   if (vam->async_mode)
2150     {
2151       vam->async_errors += (retval < 0);
2152     }
2153   else
2154     {
2155       vam->retval = retval;
2156       vam->result_ready = 1;
2157     }
2158   if (retval >= 0)
2159     {
2160       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2161     }
2162 }
2163
2164 static void vl_api_get_first_msg_id_reply_t_handler_json
2165   (vl_api_get_first_msg_id_reply_t * mp)
2166 {
2167   vat_main_t *vam = &vat_main;
2168   vat_json_node_t node;
2169
2170   vat_json_init_object (&node);
2171   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2172   vat_json_object_add_uint (&node, "first_msg_id",
2173                             (uint) ntohs (mp->first_msg_id));
2174
2175   vat_json_print (vam->ofp, &node);
2176   vat_json_free (&node);
2177
2178   vam->retval = ntohl (mp->retval);
2179   vam->result_ready = 1;
2180 }
2181
2182 static void vl_api_get_node_graph_reply_t_handler
2183   (vl_api_get_node_graph_reply_t * mp)
2184 {
2185   vat_main_t *vam = &vat_main;
2186   api_main_t *am = &api_main;
2187   i32 retval = ntohl (mp->retval);
2188   u8 *pvt_copy, *reply;
2189   void *oldheap;
2190   vlib_node_t *node;
2191   int i;
2192
2193   if (vam->async_mode)
2194     {
2195       vam->async_errors += (retval < 0);
2196     }
2197   else
2198     {
2199       vam->retval = retval;
2200       vam->result_ready = 1;
2201     }
2202
2203   /* "Should never happen..." */
2204   if (retval != 0)
2205     return;
2206
2207   reply = (u8 *) (mp->reply_in_shmem);
2208   pvt_copy = vec_dup (reply);
2209
2210   /* Toss the shared-memory original... */
2211   pthread_mutex_lock (&am->vlib_rp->mutex);
2212   oldheap = svm_push_data_heap (am->vlib_rp);
2213
2214   vec_free (reply);
2215
2216   svm_pop_heap (oldheap);
2217   pthread_mutex_unlock (&am->vlib_rp->mutex);
2218
2219   if (vam->graph_nodes)
2220     {
2221       hash_free (vam->graph_node_index_by_name);
2222
2223       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2224         {
2225           node = vam->graph_nodes[i];
2226           vec_free (node->name);
2227           vec_free (node->next_nodes);
2228           vec_free (node);
2229         }
2230       vec_free (vam->graph_nodes);
2231     }
2232
2233   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2234   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2235   vec_free (pvt_copy);
2236
2237   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2238     {
2239       node = vam->graph_nodes[i];
2240       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2241     }
2242 }
2243
2244 static void vl_api_get_node_graph_reply_t_handler_json
2245   (vl_api_get_node_graph_reply_t * mp)
2246 {
2247   vat_main_t *vam = &vat_main;
2248   api_main_t *am = &api_main;
2249   void *oldheap;
2250   vat_json_node_t node;
2251   u8 *reply;
2252
2253   /* $$$$ make this real? */
2254   vat_json_init_object (&node);
2255   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2256   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2257
2258   reply = (u8 *) (mp->reply_in_shmem);
2259
2260   /* Toss the shared-memory original... */
2261   pthread_mutex_lock (&am->vlib_rp->mutex);
2262   oldheap = svm_push_data_heap (am->vlib_rp);
2263
2264   vec_free (reply);
2265
2266   svm_pop_heap (oldheap);
2267   pthread_mutex_unlock (&am->vlib_rp->mutex);
2268
2269   vat_json_print (vam->ofp, &node);
2270   vat_json_free (&node);
2271
2272   vam->retval = ntohl (mp->retval);
2273   vam->result_ready = 1;
2274 }
2275
2276 static void
2277 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2278 {
2279   vat_main_t *vam = &vat_main;
2280   locator_msg_t loc;
2281   u8 *tmp_str = 0;
2282
2283   memset (&loc, 0, sizeof (loc));
2284   if (vam->noprint_msg)
2285     {
2286       loc.local = mp->local;
2287       loc.priority = mp->priority;
2288       loc.weight = mp->weight;
2289       if (loc.local)
2290         {
2291           loc.sw_if_index = ntohl (mp->sw_if_index);
2292         }
2293       else
2294         {
2295           loc.is_ipv6 = mp->is_ipv6;
2296           clib_memcpy (loc.ip_address, mp->ip_address,
2297                        sizeof (loc.ip_address));
2298         }
2299       vec_add1 (vam->locator_msg, loc);
2300     }
2301   else
2302     {
2303       if (mp->local)
2304         {
2305           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
2306                             ntohl (mp->sw_if_index),
2307                             mp->priority, mp->weight);
2308         }
2309       else
2310         {
2311           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
2312                             mp->is_ipv6 ? format_ip6_address :
2313                             format_ip4_address,
2314                             mp->ip_address, mp->priority, mp->weight);
2315         }
2316
2317       fformat (vam->ofp, "%s", tmp_str);
2318
2319       vec_free (tmp_str);
2320     }
2321 }
2322
2323 static void
2324 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2325                                             mp)
2326 {
2327   vat_main_t *vam = &vat_main;
2328   vat_json_node_t *node = NULL;
2329   locator_msg_t loc;
2330   struct in6_addr ip6;
2331   struct in_addr ip4;
2332
2333   memset (&loc, 0, sizeof (loc));
2334   if (vam->noprint_msg)
2335     {
2336       loc.local = mp->local;
2337       loc.priority = mp->priority;
2338       loc.weight = mp->weight;
2339       if (loc.local)
2340         {
2341           loc.sw_if_index = ntohl (mp->sw_if_index);
2342         }
2343       else
2344         {
2345           loc.is_ipv6 = mp->is_ipv6;
2346           clib_memcpy (loc.ip_address, mp->ip_address,
2347                        sizeof (loc.ip_address));
2348         }
2349       vec_add1 (vam->locator_msg, loc);
2350       return;
2351     }
2352
2353   if (VAT_JSON_ARRAY != vam->json_tree.type)
2354     {
2355       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2356       vat_json_init_array (&vam->json_tree);
2357     }
2358   node = vat_json_array_add (&vam->json_tree);
2359
2360   vat_json_init_object (node);
2361
2362   if (mp->local)
2363     {
2364       vat_json_object_add_uint (node, "locator_index",
2365                                 ntohl (mp->sw_if_index));
2366     }
2367   else
2368     {
2369       if (mp->is_ipv6)
2370         {
2371           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2372           vat_json_object_add_ip6 (node, "locator", ip6);
2373         }
2374       else
2375         {
2376           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2377           vat_json_object_add_ip4 (node, "locator", ip4);
2378         }
2379     }
2380   vat_json_object_add_uint (node, "priority", mp->priority);
2381   vat_json_object_add_uint (node, "weight", mp->weight);
2382 }
2383
2384 static void
2385 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2386                                            mp)
2387 {
2388   vat_main_t *vam = &vat_main;
2389   locator_set_msg_t ls;
2390
2391   ls.locator_set_index = ntohl (mp->locator_set_index);
2392   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2393   vec_add1 (vam->locator_set_msg, ls);
2394 }
2395
2396 static void
2397   vl_api_lisp_locator_set_details_t_handler_json
2398   (vl_api_lisp_locator_set_details_t * mp)
2399 {
2400   vat_main_t *vam = &vat_main;
2401   locator_set_msg_t ls;
2402
2403   ls.locator_set_index = ntohl (mp->locator_set_index);
2404   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2405   vec_add1 (vam->locator_set_msg, ls);
2406 }
2407
2408 static void
2409 add_lisp_eid_table_entry (vat_main_t * vam,
2410                           vl_api_lisp_eid_table_details_t * mp)
2411 {
2412   eid_table_t eid_table;
2413
2414   memset (&eid_table, 0, sizeof (eid_table));
2415   eid_table.is_local = mp->is_local;
2416   eid_table.locator_set_index = clib_net_to_host_u32 (mp->locator_set_index);
2417   eid_table.eid_type = mp->eid_type;
2418   eid_table.vni = clib_net_to_host_u32 (mp->vni);
2419   eid_table.eid_prefix_len = mp->eid_prefix_len;
2420   eid_table.ttl = clib_net_to_host_u32 (mp->ttl);
2421   eid_table.action = mp->action;
2422   eid_table.authoritative = mp->authoritative;
2423   clib_memcpy (eid_table.eid, mp->eid, sizeof (eid_table.eid));
2424   vec_add1 (vam->eid_tables, eid_table);
2425 }
2426
2427 static void
2428 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2429 {
2430   vat_main_t *vam = &vat_main;
2431   add_lisp_eid_table_entry (vam, mp);
2432 }
2433
2434 static void
2435 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2436                                               * mp)
2437 {
2438   vat_main_t *vam = &vat_main;
2439   add_lisp_eid_table_entry (vam, mp);
2440 }
2441
2442 static void
2443   vl_api_lisp_eid_table_map_details_t_handler
2444   (vl_api_lisp_eid_table_map_details_t * mp)
2445 {
2446   vat_main_t *vam = &vat_main;
2447
2448   u8 *line = format (0, "%=10d%=10d",
2449                      clib_net_to_host_u32 (mp->vni),
2450                      clib_net_to_host_u32 (mp->dp_table));
2451   fformat (vam->ofp, "%v\n", line);
2452   vec_free (line);
2453 }
2454
2455 static void
2456   vl_api_lisp_eid_table_map_details_t_handler_json
2457   (vl_api_lisp_eid_table_map_details_t * mp)
2458 {
2459   vat_main_t *vam = &vat_main;
2460   vat_json_node_t *node = NULL;
2461
2462   if (VAT_JSON_ARRAY != vam->json_tree.type)
2463     {
2464       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2465       vat_json_init_array (&vam->json_tree);
2466     }
2467   node = vat_json_array_add (&vam->json_tree);
2468   vat_json_init_object (node);
2469   vat_json_object_add_uint (node, "dp_table",
2470                             clib_net_to_host_u32 (mp->dp_table));
2471   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2472 }
2473
2474 static void
2475   vl_api_lisp_eid_table_vni_details_t_handler
2476   (vl_api_lisp_eid_table_vni_details_t * mp)
2477 {
2478   vat_main_t *vam = &vat_main;
2479
2480   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2481   fformat (vam->ofp, "%v\n", line);
2482   vec_free (line);
2483 }
2484
2485 static void
2486   vl_api_lisp_eid_table_vni_details_t_handler_json
2487   (vl_api_lisp_eid_table_vni_details_t * mp)
2488 {
2489   vat_main_t *vam = &vat_main;
2490   vat_json_node_t *node = NULL;
2491
2492   if (VAT_JSON_ARRAY != vam->json_tree.type)
2493     {
2494       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2495       vat_json_init_array (&vam->json_tree);
2496     }
2497   node = vat_json_array_add (&vam->json_tree);
2498   vat_json_init_object (node);
2499   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2500 }
2501
2502 static u8 *
2503 format_decap_next (u8 * s, va_list * args)
2504 {
2505   u32 next_index = va_arg (*args, u32);
2506
2507   switch (next_index)
2508     {
2509     case LISP_GPE_INPUT_NEXT_DROP:
2510       return format (s, "drop");
2511     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2512       return format (s, "ip4");
2513     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2514       return format (s, "ip6");
2515     default:
2516       return format (s, "unknown %d", next_index);
2517     }
2518   return s;
2519 }
2520
2521 static void
2522 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2523                                           mp)
2524 {
2525   vat_main_t *vam = &vat_main;
2526   u8 *iid_str;
2527   u8 *flag_str = NULL;
2528
2529   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2530
2531 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2532   foreach_lisp_gpe_flag_bit;
2533 #undef _
2534
2535   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2536            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2537            mp->tunnels,
2538            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2539            mp->source_ip,
2540            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2541            mp->destination_ip,
2542            ntohl (mp->encap_fib_id),
2543            ntohl (mp->decap_fib_id),
2544            format_decap_next, ntohl (mp->dcap_next),
2545            mp->ver_res >> 6,
2546            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2547
2548   vec_free (iid_str);
2549 }
2550
2551 static void
2552   vl_api_lisp_gpe_tunnel_details_t_handler_json
2553   (vl_api_lisp_gpe_tunnel_details_t * mp)
2554 {
2555   vat_main_t *vam = &vat_main;
2556   vat_json_node_t *node = NULL;
2557   struct in6_addr ip6;
2558   struct in_addr ip4;
2559   u8 *next_decap_str;
2560
2561   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2562
2563   if (VAT_JSON_ARRAY != vam->json_tree.type)
2564     {
2565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2566       vat_json_init_array (&vam->json_tree);
2567     }
2568   node = vat_json_array_add (&vam->json_tree);
2569
2570   vat_json_init_object (node);
2571   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2572   if (mp->is_ipv6)
2573     {
2574       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2575       vat_json_object_add_ip6 (node, "source address", ip6);
2576       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2577       vat_json_object_add_ip6 (node, "destination address", ip6);
2578     }
2579   else
2580     {
2581       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2582       vat_json_object_add_ip4 (node, "source address", ip4);
2583       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2584       vat_json_object_add_ip4 (node, "destination address", ip4);
2585     }
2586   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2587   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2588   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2589   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2590   vat_json_object_add_uint (node, "flags", mp->flags);
2591   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2592   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2593   vat_json_object_add_uint (node, "res", mp->res);
2594   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2595
2596   vec_free (next_decap_str);
2597 }
2598
2599 static void
2600 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2601                                             * mp)
2602 {
2603   vat_main_t *vam = &vat_main;
2604
2605   fformat (vam->ofp, "%=20U\n",
2606            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2607            mp->ip_address);
2608 }
2609
2610 static void
2611   vl_api_lisp_map_resolver_details_t_handler_json
2612   (vl_api_lisp_map_resolver_details_t * mp)
2613 {
2614   vat_main_t *vam = &vat_main;
2615   vat_json_node_t *node = NULL;
2616   struct in6_addr ip6;
2617   struct in_addr ip4;
2618
2619   if (VAT_JSON_ARRAY != vam->json_tree.type)
2620     {
2621       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2622       vat_json_init_array (&vam->json_tree);
2623     }
2624   node = vat_json_array_add (&vam->json_tree);
2625
2626   vat_json_init_object (node);
2627   if (mp->is_ipv6)
2628     {
2629       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2630       vat_json_object_add_ip6 (node, "map resolver", ip6);
2631     }
2632   else
2633     {
2634       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2635       vat_json_object_add_ip4 (node, "map resolver", ip4);
2636     }
2637 }
2638
2639 static void
2640   vl_api_show_lisp_status_reply_t_handler
2641   (vl_api_show_lisp_status_reply_t * mp)
2642 {
2643   vat_main_t *vam = &vat_main;
2644   i32 retval = ntohl (mp->retval);
2645
2646   if (0 <= retval)
2647     {
2648       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2649                mp->feature_status ? "enabled" : "disabled",
2650                mp->gpe_status ? "enabled" : "disabled");
2651     }
2652
2653   vam->retval = retval;
2654   vam->result_ready = 1;
2655 }
2656
2657 static void
2658   vl_api_show_lisp_status_reply_t_handler_json
2659   (vl_api_show_lisp_status_reply_t * mp)
2660 {
2661   vat_main_t *vam = &vat_main;
2662   vat_json_node_t node;
2663   u8 *gpe_status = NULL;
2664   u8 *feature_status = NULL;
2665
2666   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2667   feature_status = format (0, "%s",
2668                            mp->feature_status ? "enabled" : "disabled");
2669   vec_add1 (gpe_status, 0);
2670   vec_add1 (feature_status, 0);
2671
2672   vat_json_init_object (&node);
2673   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2674   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2675
2676   vec_free (gpe_status);
2677   vec_free (feature_status);
2678
2679   vat_json_print (vam->ofp, &node);
2680   vat_json_free (&node);
2681
2682   vam->retval = ntohl (mp->retval);
2683   vam->result_ready = 1;
2684 }
2685
2686 static void
2687   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2688   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2689 {
2690   vat_main_t *vam = &vat_main;
2691   i32 retval = ntohl (mp->retval);
2692
2693   if (retval >= 0)
2694     {
2695       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2696     }
2697
2698   vam->retval = retval;
2699   vam->result_ready = 1;
2700 }
2701
2702 static void
2703   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2704   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   vat_json_node_t *node = NULL;
2708
2709   if (VAT_JSON_ARRAY != vam->json_tree.type)
2710     {
2711       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2712       vat_json_init_array (&vam->json_tree);
2713     }
2714   node = vat_json_array_add (&vam->json_tree);
2715
2716   vat_json_init_object (node);
2717   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2718
2719   vat_json_print (vam->ofp, node);
2720   vat_json_free (node);
2721
2722   vam->retval = ntohl (mp->retval);
2723   vam->result_ready = 1;
2724 }
2725
2726 static void
2727 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2728 {
2729   vat_main_t *vam = &vat_main;
2730   i32 retval = ntohl (mp->retval);
2731
2732   if (0 <= retval)
2733     {
2734       fformat (vam->ofp, "%-20s%-16s\n",
2735                mp->status ? "enabled" : "disabled",
2736                mp->status ? (char *) mp->locator_set_name : "");
2737     }
2738
2739   vam->retval = retval;
2740   vam->result_ready = 1;
2741 }
2742
2743 static void
2744 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2745                                             mp)
2746 {
2747   vat_main_t *vam = &vat_main;
2748   vat_json_node_t node;
2749   u8 *status = 0;
2750
2751   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2752   vec_add1 (status, 0);
2753
2754   vat_json_init_object (&node);
2755   vat_json_object_add_string_copy (&node, "status", status);
2756   if (mp->status)
2757     {
2758       vat_json_object_add_string_copy (&node, "locator_set",
2759                                        mp->locator_set_name);
2760     }
2761
2762   vec_free (status);
2763
2764   vat_json_print (vam->ofp, &node);
2765   vat_json_free (&node);
2766
2767   vam->retval = ntohl (mp->retval);
2768   vam->result_ready = 1;
2769 }
2770
2771 static u8 *
2772 format_policer_type (u8 * s, va_list * va)
2773 {
2774   u32 i = va_arg (*va, u32);
2775
2776   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2777     s = format (s, "1r2c");
2778   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2779     s = format (s, "1r3c");
2780   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2781     s = format (s, "2r3c-2698");
2782   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2783     s = format (s, "2r3c-4115");
2784   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2785     s = format (s, "2r3c-mef5cf1");
2786   else
2787     s = format (s, "ILLEGAL");
2788   return s;
2789 }
2790
2791 static u8 *
2792 format_policer_rate_type (u8 * s, va_list * va)
2793 {
2794   u32 i = va_arg (*va, u32);
2795
2796   if (i == SSE2_QOS_RATE_KBPS)
2797     s = format (s, "kbps");
2798   else if (i == SSE2_QOS_RATE_PPS)
2799     s = format (s, "pps");
2800   else
2801     s = format (s, "ILLEGAL");
2802   return s;
2803 }
2804
2805 static u8 *
2806 format_policer_round_type (u8 * s, va_list * va)
2807 {
2808   u32 i = va_arg (*va, u32);
2809
2810   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2811     s = format (s, "closest");
2812   else if (i == SSE2_QOS_ROUND_TO_UP)
2813     s = format (s, "up");
2814   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2815     s = format (s, "down");
2816   else
2817     s = format (s, "ILLEGAL");
2818   return s;
2819 }
2820
2821 static u8 *
2822 format_policer_action_type (u8 * s, va_list * va)
2823 {
2824   u32 i = va_arg (*va, u32);
2825
2826   if (i == SSE2_QOS_ACTION_DROP)
2827     s = format (s, "drop");
2828   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2829     s = format (s, "transmit");
2830   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2831     s = format (s, "mark-and-transmit");
2832   else
2833     s = format (s, "ILLEGAL");
2834   return s;
2835 }
2836
2837 static u8 *
2838 format_dscp (u8 * s, va_list * va)
2839 {
2840   u32 i = va_arg (*va, u32);
2841   char *t = 0;
2842
2843   switch (i)
2844     {
2845 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2846       foreach_vnet_dscp
2847 #undef _
2848     default:
2849       return format (s, "ILLEGAL");
2850     }
2851   s = format (s, "%s", t);
2852   return s;
2853 }
2854
2855 static void
2856 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2857 {
2858   vat_main_t *vam = &vat_main;
2859   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2860
2861   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2862     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2863   else
2864     conform_dscp_str = format (0, "");
2865
2866   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2867     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2868   else
2869     exceed_dscp_str = format (0, "");
2870
2871   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2872     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2873   else
2874     violate_dscp_str = format (0, "");
2875
2876   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2877            "rate type %U, round type %U, %s rate, %s color-aware, "
2878            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2879            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2880            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2881            mp->name,
2882            format_policer_type, mp->type,
2883            ntohl (mp->cir),
2884            ntohl (mp->eir),
2885            clib_net_to_host_u64 (mp->cb),
2886            clib_net_to_host_u64 (mp->eb),
2887            format_policer_rate_type, mp->rate_type,
2888            format_policer_round_type, mp->round_type,
2889            mp->single_rate ? "single" : "dual",
2890            mp->color_aware ? "is" : "not",
2891            ntohl (mp->cir_tokens_per_period),
2892            ntohl (mp->pir_tokens_per_period),
2893            ntohl (mp->scale),
2894            ntohl (mp->current_limit),
2895            ntohl (mp->current_bucket),
2896            ntohl (mp->extended_limit),
2897            ntohl (mp->extended_bucket),
2898            clib_net_to_host_u64 (mp->last_update_time),
2899            format_policer_action_type, mp->conform_action_type,
2900            conform_dscp_str,
2901            format_policer_action_type, mp->exceed_action_type,
2902            exceed_dscp_str,
2903            format_policer_action_type, mp->violate_action_type,
2904            violate_dscp_str);
2905
2906   vec_free (conform_dscp_str);
2907   vec_free (exceed_dscp_str);
2908   vec_free (violate_dscp_str);
2909 }
2910
2911 static void vl_api_policer_details_t_handler_json
2912   (vl_api_policer_details_t * mp)
2913 {
2914   vat_main_t *vam = &vat_main;
2915   vat_json_node_t *node;
2916   u8 *rate_type_str, *round_type_str, *type_str;
2917   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2918
2919   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2920   round_type_str =
2921     format (0, "%U", format_policer_round_type, mp->round_type);
2922   type_str = format (0, "%U", format_policer_type, mp->type);
2923   conform_action_str = format (0, "%U", format_policer_action_type,
2924                                mp->conform_action_type);
2925   exceed_action_str = format (0, "%U", format_policer_action_type,
2926                               mp->exceed_action_type);
2927   violate_action_str = format (0, "%U", format_policer_action_type,
2928                                mp->violate_action_type);
2929
2930   if (VAT_JSON_ARRAY != vam->json_tree.type)
2931     {
2932       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2933       vat_json_init_array (&vam->json_tree);
2934     }
2935   node = vat_json_array_add (&vam->json_tree);
2936
2937   vat_json_init_object (node);
2938   vat_json_object_add_string_copy (node, "name", mp->name);
2939   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2940   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2941   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
2942   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
2943   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2944   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2945   vat_json_object_add_string_copy (node, "type", type_str);
2946   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2947   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2948   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2949   vat_json_object_add_uint (node, "cir_tokens_per_period",
2950                             ntohl (mp->cir_tokens_per_period));
2951   vat_json_object_add_uint (node, "eir_tokens_per_period",
2952                             ntohl (mp->pir_tokens_per_period));
2953   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2954   vat_json_object_add_uint (node, "current_bucket",
2955                             ntohl (mp->current_bucket));
2956   vat_json_object_add_uint (node, "extended_limit",
2957                             ntohl (mp->extended_limit));
2958   vat_json_object_add_uint (node, "extended_bucket",
2959                             ntohl (mp->extended_bucket));
2960   vat_json_object_add_uint (node, "last_update_time",
2961                             ntohl (mp->last_update_time));
2962   vat_json_object_add_string_copy (node, "conform_action",
2963                                    conform_action_str);
2964   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2965     {
2966       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2967       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2968       vec_free (dscp_str);
2969     }
2970   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
2971   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2972     {
2973       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2974       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2975       vec_free (dscp_str);
2976     }
2977   vat_json_object_add_string_copy (node, "violate_action",
2978                                    violate_action_str);
2979   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2980     {
2981       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2982       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2983       vec_free (dscp_str);
2984     }
2985
2986   vec_free (rate_type_str);
2987   vec_free (round_type_str);
2988   vec_free (type_str);
2989   vec_free (conform_action_str);
2990   vec_free (exceed_action_str);
2991   vec_free (violate_action_str);
2992 }
2993
2994 static void
2995 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2996                                            mp)
2997 {
2998   vat_main_t *vam = &vat_main;
2999   int i, count = ntohl (mp->count);
3000
3001   if (count > 0)
3002     fformat (vam->ofp, "classify table ids (%d) : ", count);
3003   for (i = 0; i < count; i++)
3004     {
3005       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3006       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3007     }
3008   vam->retval = ntohl (mp->retval);
3009   vam->result_ready = 1;
3010 }
3011
3012 static void
3013   vl_api_classify_table_ids_reply_t_handler_json
3014   (vl_api_classify_table_ids_reply_t * mp)
3015 {
3016   vat_main_t *vam = &vat_main;
3017   int i, count = ntohl (mp->count);
3018
3019   if (count > 0)
3020     {
3021       vat_json_node_t node;
3022
3023       vat_json_init_object (&node);
3024       for (i = 0; i < count; i++)
3025         {
3026           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3027         }
3028       vat_json_print (vam->ofp, &node);
3029       vat_json_free (&node);
3030     }
3031   vam->retval = ntohl (mp->retval);
3032   vam->result_ready = 1;
3033 }
3034
3035 static void
3036   vl_api_classify_table_by_interface_reply_t_handler
3037   (vl_api_classify_table_by_interface_reply_t * mp)
3038 {
3039   vat_main_t *vam = &vat_main;
3040   u32 table_id;
3041
3042   table_id = ntohl (mp->l2_table_id);
3043   if (table_id != ~0)
3044     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3045   else
3046     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3047   table_id = ntohl (mp->ip4_table_id);
3048   if (table_id != ~0)
3049     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3050   else
3051     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3052   table_id = ntohl (mp->ip6_table_id);
3053   if (table_id != ~0)
3054     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3055   else
3056     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3057   vam->retval = ntohl (mp->retval);
3058   vam->result_ready = 1;
3059 }
3060
3061 static void
3062   vl_api_classify_table_by_interface_reply_t_handler_json
3063   (vl_api_classify_table_by_interface_reply_t * mp)
3064 {
3065   vat_main_t *vam = &vat_main;
3066   vat_json_node_t node;
3067
3068   vat_json_init_object (&node);
3069
3070   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3071   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3072   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3073
3074   vat_json_print (vam->ofp, &node);
3075   vat_json_free (&node);
3076
3077   vam->retval = ntohl (mp->retval);
3078   vam->result_ready = 1;
3079 }
3080
3081 static void vl_api_policer_add_del_reply_t_handler
3082   (vl_api_policer_add_del_reply_t * mp)
3083 {
3084   vat_main_t *vam = &vat_main;
3085   i32 retval = ntohl (mp->retval);
3086   if (vam->async_mode)
3087     {
3088       vam->async_errors += (retval < 0);
3089     }
3090   else
3091     {
3092       vam->retval = retval;
3093       vam->result_ready = 1;
3094       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3095         /*
3096          * Note: this is just barely thread-safe, depends on
3097          * the main thread spinning waiting for an answer...
3098          */
3099         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3100     }
3101 }
3102
3103 static void vl_api_policer_add_del_reply_t_handler_json
3104   (vl_api_policer_add_del_reply_t * mp)
3105 {
3106   vat_main_t *vam = &vat_main;
3107   vat_json_node_t node;
3108
3109   vat_json_init_object (&node);
3110   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3111   vat_json_object_add_uint (&node, "policer_index",
3112                             ntohl (mp->policer_index));
3113
3114   vat_json_print (vam->ofp, &node);
3115   vat_json_free (&node);
3116
3117   vam->retval = ntohl (mp->retval);
3118   vam->result_ready = 1;
3119 }
3120
3121 /* Format hex dump. */
3122 u8 *
3123 format_hex_bytes (u8 * s, va_list * va)
3124 {
3125   u8 *bytes = va_arg (*va, u8 *);
3126   int n_bytes = va_arg (*va, int);
3127   uword i;
3128
3129   /* Print short or long form depending on byte count. */
3130   uword short_form = n_bytes <= 32;
3131   uword indent = format_get_indent (s);
3132
3133   if (n_bytes == 0)
3134     return s;
3135
3136   for (i = 0; i < n_bytes; i++)
3137     {
3138       if (!short_form && (i % 32) == 0)
3139         s = format (s, "%08x: ", i);
3140       s = format (s, "%02x", bytes[i]);
3141       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3142         s = format (s, "\n%U", format_white_space, indent);
3143     }
3144
3145   return s;
3146 }
3147
3148 static void
3149 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3150                                             * mp)
3151 {
3152   vat_main_t *vam = &vat_main;
3153   i32 retval = ntohl (mp->retval);
3154   if (retval == 0)
3155     {
3156       fformat (vam->ofp, "classify table info :\n");
3157       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3158                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3159                ntohl (mp->miss_next_index));
3160       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3161                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3162                ntohl (mp->match_n_vectors));
3163       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3164                ntohl (mp->mask_length));
3165     }
3166   vam->retval = retval;
3167   vam->result_ready = 1;
3168 }
3169
3170 static void
3171   vl_api_classify_table_info_reply_t_handler_json
3172   (vl_api_classify_table_info_reply_t * mp)
3173 {
3174   vat_main_t *vam = &vat_main;
3175   vat_json_node_t node;
3176
3177   i32 retval = ntohl (mp->retval);
3178   if (retval == 0)
3179     {
3180       vat_json_init_object (&node);
3181
3182       vat_json_object_add_int (&node, "sessions",
3183                                ntohl (mp->active_sessions));
3184       vat_json_object_add_int (&node, "nexttbl",
3185                                ntohl (mp->next_table_index));
3186       vat_json_object_add_int (&node, "nextnode",
3187                                ntohl (mp->miss_next_index));
3188       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3189       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3190       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3191       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3192                       ntohl (mp->mask_length), 0);
3193       vat_json_object_add_string_copy (&node, "mask", s);
3194
3195       vat_json_print (vam->ofp, &node);
3196       vat_json_free (&node);
3197     }
3198   vam->retval = ntohl (mp->retval);
3199   vam->result_ready = 1;
3200 }
3201
3202 static void
3203 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3204                                            mp)
3205 {
3206   vat_main_t *vam = &vat_main;
3207
3208   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3209            ntohl (mp->hit_next_index), ntohl (mp->advance),
3210            ntohl (mp->opaque_index));
3211   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3212            ntohl (mp->match_length));
3213 }
3214
3215 static void
3216   vl_api_classify_session_details_t_handler_json
3217   (vl_api_classify_session_details_t * mp)
3218 {
3219   vat_main_t *vam = &vat_main;
3220   vat_json_node_t *node = NULL;
3221
3222   if (VAT_JSON_ARRAY != vam->json_tree.type)
3223     {
3224       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3225       vat_json_init_array (&vam->json_tree);
3226     }
3227   node = vat_json_array_add (&vam->json_tree);
3228
3229   vat_json_init_object (node);
3230   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3231   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3232   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3233   u8 *s =
3234     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3235             0);
3236   vat_json_object_add_string_copy (node, "match", s);
3237 }
3238
3239 static void vl_api_pg_create_interface_reply_t_handler
3240   (vl_api_pg_create_interface_reply_t * mp)
3241 {
3242   vat_main_t *vam = &vat_main;
3243
3244   vam->retval = ntohl (mp->retval);
3245   vam->result_ready = 1;
3246 }
3247
3248 static void vl_api_pg_create_interface_reply_t_handler_json
3249   (vl_api_pg_create_interface_reply_t * mp)
3250 {
3251   vat_main_t *vam = &vat_main;
3252   vat_json_node_t node;
3253
3254   i32 retval = ntohl (mp->retval);
3255   if (retval == 0)
3256     {
3257       vat_json_init_object (&node);
3258
3259       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3260
3261       vat_json_print (vam->ofp, &node);
3262       vat_json_free (&node);
3263     }
3264   vam->retval = ntohl (mp->retval);
3265   vam->result_ready = 1;
3266 }
3267
3268 static void vl_api_policer_classify_details_t_handler
3269   (vl_api_policer_classify_details_t * mp)
3270 {
3271   vat_main_t *vam = &vat_main;
3272
3273   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3274            ntohl (mp->table_index));
3275 }
3276
3277 static void vl_api_policer_classify_details_t_handler_json
3278   (vl_api_policer_classify_details_t * mp)
3279 {
3280   vat_main_t *vam = &vat_main;
3281   vat_json_node_t *node;
3282
3283   if (VAT_JSON_ARRAY != vam->json_tree.type)
3284     {
3285       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3286       vat_json_init_array (&vam->json_tree);
3287     }
3288   node = vat_json_array_add (&vam->json_tree);
3289
3290   vat_json_init_object (node);
3291   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3292   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3293 }
3294
3295 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3296   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3297 {
3298   vat_main_t *vam = &vat_main;
3299   i32 retval = ntohl (mp->retval);
3300   if (vam->async_mode)
3301     {
3302       vam->async_errors += (retval < 0);
3303     }
3304   else
3305     {
3306       vam->retval = retval;
3307       vam->sw_if_index = ntohl (mp->sw_if_index);
3308       vam->result_ready = 1;
3309     }
3310 }
3311
3312 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3313   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3314 {
3315   vat_main_t *vam = &vat_main;
3316   vat_json_node_t node;
3317
3318   vat_json_init_object (&node);
3319   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3320   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3321
3322   vat_json_print (vam->ofp, &node);
3323   vat_json_free (&node);
3324
3325   vam->retval = ntohl (mp->retval);
3326   vam->result_ready = 1;
3327 }
3328
3329 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3330 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3331 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3332 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3333
3334 /*
3335  * Generate boilerplate reply handlers, which
3336  * dig the return value out of the xxx_reply_t API message,
3337  * stick it into vam->retval, and set vam->result_ready
3338  *
3339  * Could also do this by pointing N message decode slots at
3340  * a single function, but that could break in subtle ways.
3341  */
3342
3343 #define foreach_standard_reply_retval_handler           \
3344 _(sw_interface_set_flags_reply)                         \
3345 _(sw_interface_add_del_address_reply)                   \
3346 _(sw_interface_set_table_reply)                         \
3347 _(sw_interface_set_vpath_reply)                         \
3348 _(sw_interface_set_l2_bridge_reply)                     \
3349 _(bridge_domain_add_del_reply)                          \
3350 _(sw_interface_set_l2_xconnect_reply)                   \
3351 _(l2fib_add_del_reply)                                  \
3352 _(ip_add_del_route_reply)                               \
3353 _(proxy_arp_add_del_reply)                              \
3354 _(proxy_arp_intfc_enable_disable_reply)                 \
3355 _(mpls_add_del_encap_reply)                             \
3356 _(mpls_add_del_decap_reply)                             \
3357 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3358 _(sw_interface_set_unnumbered_reply)                    \
3359 _(ip_neighbor_add_del_reply)                            \
3360 _(reset_vrf_reply)                                      \
3361 _(oam_add_del_reply)                                    \
3362 _(reset_fib_reply)                                      \
3363 _(dhcp_proxy_config_reply)                              \
3364 _(dhcp_proxy_config_2_reply)                            \
3365 _(dhcp_proxy_set_vss_reply)                             \
3366 _(dhcp_client_config_reply)                             \
3367 _(set_ip_flow_hash_reply)                               \
3368 _(sw_interface_ip6_enable_disable_reply)                \
3369 _(sw_interface_ip6_set_link_local_address_reply)        \
3370 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3371 _(sw_interface_ip6nd_ra_config_reply)                   \
3372 _(set_arp_neighbor_limit_reply)                         \
3373 _(l2_patch_add_del_reply)                               \
3374 _(sr_tunnel_add_del_reply)                              \
3375 _(sr_policy_add_del_reply)                              \
3376 _(sr_multicast_map_add_del_reply)                       \
3377 _(classify_add_del_session_reply)                       \
3378 _(classify_set_interface_ip_table_reply)                \
3379 _(classify_set_interface_l2_tables_reply)               \
3380 _(l2tpv3_set_tunnel_cookies_reply)                      \
3381 _(l2tpv3_interface_enable_disable_reply)                \
3382 _(l2tpv3_set_lookup_key_reply)                          \
3383 _(l2_fib_clear_table_reply)                             \
3384 _(l2_interface_efp_filter_reply)                        \
3385 _(l2_interface_vlan_tag_rewrite_reply)                  \
3386 _(modify_vhost_user_if_reply)                           \
3387 _(delete_vhost_user_if_reply)                           \
3388 _(want_ip4_arp_events_reply)                            \
3389 _(want_ip6_nd_events_reply)                             \
3390 _(input_acl_set_interface_reply)                        \
3391 _(ipsec_spd_add_del_reply)                              \
3392 _(ipsec_interface_add_del_spd_reply)                    \
3393 _(ipsec_spd_add_del_entry_reply)                        \
3394 _(ipsec_sad_add_del_entry_reply)                        \
3395 _(ipsec_sa_set_key_reply)                               \
3396 _(ikev2_profile_add_del_reply)                          \
3397 _(ikev2_profile_set_auth_reply)                         \
3398 _(ikev2_profile_set_id_reply)                           \
3399 _(ikev2_profile_set_ts_reply)                           \
3400 _(ikev2_set_local_key_reply)                            \
3401 _(delete_loopback_reply)                                \
3402 _(bd_ip_mac_add_del_reply)                              \
3403 _(map_del_domain_reply)                                 \
3404 _(map_add_del_rule_reply)                               \
3405 _(want_interface_events_reply)                          \
3406 _(want_stats_reply)                                     \
3407 _(cop_interface_enable_disable_reply)                   \
3408 _(cop_whitelist_enable_disable_reply)                   \
3409 _(sw_interface_clear_stats_reply)                       \
3410 _(ioam_enable_reply)                              \
3411 _(ioam_disable_reply)                              \
3412 _(lisp_add_del_locator_reply)                           \
3413 _(lisp_add_del_local_eid_reply)                         \
3414 _(lisp_add_del_remote_mapping_reply)                    \
3415 _(lisp_add_del_adjacency_reply)                         \
3416 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3417 _(lisp_add_del_map_resolver_reply)                      \
3418 _(lisp_gpe_enable_disable_reply)                        \
3419 _(lisp_gpe_add_del_iface_reply)                         \
3420 _(lisp_enable_disable_reply)                            \
3421 _(lisp_pitr_set_locator_set_reply)                      \
3422 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3423 _(lisp_eid_table_add_del_map_reply)                     \
3424 _(vxlan_gpe_add_del_tunnel_reply)                       \
3425 _(af_packet_delete_reply)                               \
3426 _(policer_classify_set_interface_reply)                 \
3427 _(netmap_create_reply)                                  \
3428 _(netmap_delete_reply)                                  \
3429 _(set_ipfix_exporter_reply)                             \
3430 _(set_ipfix_classify_stream_reply)                      \
3431 _(ipfix_classify_table_add_del_reply)                   \
3432 _(pg_capture_reply)                                     \
3433 _(pg_enable_disable_reply)                              \
3434 _(ip_source_and_port_range_check_add_del_reply)         \
3435 _(ip_source_and_port_range_check_interface_add_del_reply)\
3436 _(delete_subif_reply)
3437
3438 #define _(n)                                    \
3439     static void vl_api_##n##_t_handler          \
3440     (vl_api_##n##_t * mp)                       \
3441     {                                           \
3442         vat_main_t * vam = &vat_main;           \
3443         i32 retval = ntohl(mp->retval);         \
3444         if (vam->async_mode) {                  \
3445             vam->async_errors += (retval < 0);  \
3446         } else {                                \
3447             vam->retval = retval;               \
3448             vam->result_ready = 1;              \
3449         }                                       \
3450     }
3451 foreach_standard_reply_retval_handler;
3452 #undef _
3453
3454 #define _(n)                                    \
3455     static void vl_api_##n##_t_handler_json     \
3456     (vl_api_##n##_t * mp)                       \
3457     {                                           \
3458         vat_main_t * vam = &vat_main;           \
3459         vat_json_node_t node;                   \
3460         vat_json_init_object(&node);            \
3461         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3462         vat_json_print(vam->ofp, &node);        \
3463         vam->retval = ntohl(mp->retval);        \
3464         vam->result_ready = 1;                  \
3465     }
3466 foreach_standard_reply_retval_handler;
3467 #undef _
3468
3469 /*
3470  * Table of message reply handlers, must include boilerplate handlers
3471  * we just generated
3472  */
3473
3474 #define foreach_vpe_api_reply_msg                                       \
3475 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3476 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3477 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3478 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3479 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3480 _(NOPRINT_CONTROL_PING_REPLY, noprint_control_ping_reply)               \
3481 _(CLI_REPLY, cli_reply)                                                 \
3482 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3483 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3484   sw_interface_add_del_address_reply)                                   \
3485 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3486 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3487 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3488   sw_interface_set_l2_xconnect_reply)                                   \
3489 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3490   sw_interface_set_l2_bridge_reply)                                     \
3491 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3492 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3493 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3494 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3495 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3496 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3497 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3498 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3499 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3500 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3501 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3502 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3503 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3504   proxy_arp_intfc_enable_disable_reply)                                 \
3505 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3506 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3507 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3508 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3509   mpls_ethernet_add_del_tunnel_reply)                                   \
3510 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3511   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3512 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3513   sw_interface_set_unnumbered_reply)                                    \
3514 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3515 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3516 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3517 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3518 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3519 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3520 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3521 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3522 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3523 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3524 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3525 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3526   sw_interface_ip6_enable_disable_reply)                                \
3527 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3528   sw_interface_ip6_set_link_local_address_reply)                        \
3529 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3530   sw_interface_ip6nd_ra_prefix_reply)                                   \
3531 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3532   sw_interface_ip6nd_ra_config_reply)                                   \
3533 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3534 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3535 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3536 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3537 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3538 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3539 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3540 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3541 classify_set_interface_ip_table_reply)                                  \
3542 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3543   classify_set_interface_l2_tables_reply)                               \
3544 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3545 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3546 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3547 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3548 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3549   l2tpv3_interface_enable_disable_reply)                                \
3550 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3551 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3552 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3553 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3554 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3555 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3556 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3557 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3558 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3559 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3560 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3561 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3562 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3563 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3564 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3565 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3566 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3567 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3568 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3569 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3570 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3571 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3572 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3573 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3574 _(IP_DETAILS, ip_details)                                               \
3575 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3576 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3577 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3578 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3579 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3580 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3581 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3582 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3583 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3584 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3585 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3586 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3587 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3588 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3589 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3590 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3591 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3592 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3593 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3594 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3595 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3596 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3597 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3598 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3599 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3600 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3601 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3602 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3603 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3604 _(IOAM_DISABLE_REPLY, ioam_disable_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 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3647 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3648 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3649 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3650 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3651 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3652 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3653 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3654 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3655 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3656 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3657  ip_source_and_port_range_check_add_del_reply)                          \
3658 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3659  ip_source_and_port_range_check_interface_add_del_reply)                \
3660 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3661 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3662 _(DELETE_SUBIF_REPLY, delete_subif_reply)
3663
3664 /* M: construct, but don't yet send a message */
3665
3666 #define M(T,t)                                  \
3667 do {                                            \
3668     vam->result_ready = 0;                      \
3669     mp = vl_msg_api_alloc(sizeof(*mp));         \
3670     memset (mp, 0, sizeof (*mp));               \
3671     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3672     mp->client_index = vam->my_client_index;    \
3673 } while(0);
3674
3675 #define M2(T,t,n)                               \
3676 do {                                            \
3677     vam->result_ready = 0;                      \
3678     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3679     memset (mp, 0, sizeof (*mp));               \
3680     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3681     mp->client_index = vam->my_client_index;    \
3682 } while(0);
3683
3684
3685 /* S: send a message */
3686 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3687
3688 /* W: wait for results, with timeout */
3689 #define W                                       \
3690 do {                                            \
3691     timeout = vat_time_now (vam) + 1.0;         \
3692                                                 \
3693     while (vat_time_now (vam) < timeout) {      \
3694         if (vam->result_ready == 1) {           \
3695             return (vam->retval);               \
3696         }                                       \
3697     }                                           \
3698     return -99;                                 \
3699 } while(0);
3700
3701 /* W2: wait for results, with timeout */
3702 #define W2(body)                                \
3703 do {                                            \
3704     timeout = vat_time_now (vam) + 1.0;         \
3705                                                 \
3706     while (vat_time_now (vam) < timeout) {      \
3707         if (vam->result_ready == 1) {           \
3708           (body);                               \
3709           return (vam->retval);                 \
3710         }                                       \
3711     }                                           \
3712     return -99;                                 \
3713 } while(0);
3714
3715 /* W_L: wait for results, with timeout */
3716 #define W_L(body)                               \
3717 do {                                            \
3718     timeout = vat_time_now (vam) + 1.0;         \
3719                                                 \
3720     while (vat_time_now (vam) < timeout) {      \
3721         if (vam->result_ready == 1) {           \
3722           (body);                               \
3723           return (vam->retval);                 \
3724         }                                       \
3725     }                                           \
3726     vam->noprint_msg = 0;     \
3727     return -99;                                 \
3728 } while(0);
3729
3730 typedef struct
3731 {
3732   u8 *name;
3733   u32 value;
3734 } name_sort_t;
3735
3736
3737 #define STR_VTR_OP_CASE(op)     \
3738     case L2_VTR_ ## op:         \
3739         return "" # op;
3740
3741 static const char *
3742 str_vtr_op (u32 vtr_op)
3743 {
3744   switch (vtr_op)
3745     {
3746       STR_VTR_OP_CASE (DISABLED);
3747       STR_VTR_OP_CASE (PUSH_1);
3748       STR_VTR_OP_CASE (PUSH_2);
3749       STR_VTR_OP_CASE (POP_1);
3750       STR_VTR_OP_CASE (POP_2);
3751       STR_VTR_OP_CASE (TRANSLATE_1_1);
3752       STR_VTR_OP_CASE (TRANSLATE_1_2);
3753       STR_VTR_OP_CASE (TRANSLATE_2_1);
3754       STR_VTR_OP_CASE (TRANSLATE_2_2);
3755     }
3756
3757   return "UNKNOWN";
3758 }
3759
3760 static int
3761 dump_sub_interface_table (vat_main_t * vam)
3762 {
3763   const sw_interface_subif_t *sub = NULL;
3764
3765   if (vam->json_output)
3766     {
3767       clib_warning
3768         ("JSON output supported only for VPE API calls and dump_stats_table");
3769       return -99;
3770     }
3771
3772   fformat (vam->ofp,
3773            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3774            "Interface", "sw_if_index",
3775            "sub id", "dot1ad", "tags", "outer id",
3776            "inner id", "exact", "default", "outer any", "inner any");
3777
3778   vec_foreach (sub, vam->sw_if_subif_table)
3779   {
3780     fformat (vam->ofp,
3781              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3782              sub->interface_name,
3783              sub->sw_if_index,
3784              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3785              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3786              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3787              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3788     if (sub->vtr_op != L2_VTR_DISABLED)
3789       {
3790         fformat (vam->ofp,
3791                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3792                  "tag1: %d tag2: %d ]\n",
3793                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3794                  sub->vtr_tag1, sub->vtr_tag2);
3795       }
3796   }
3797
3798   return 0;
3799 }
3800
3801 static int
3802 name_sort_cmp (void *a1, void *a2)
3803 {
3804   name_sort_t *n1 = a1;
3805   name_sort_t *n2 = a2;
3806
3807   return strcmp ((char *) n1->name, (char *) n2->name);
3808 }
3809
3810 static int
3811 dump_interface_table (vat_main_t * vam)
3812 {
3813   hash_pair_t *p;
3814   name_sort_t *nses = 0, *ns;
3815
3816   if (vam->json_output)
3817     {
3818       clib_warning
3819         ("JSON output supported only for VPE API calls and dump_stats_table");
3820       return -99;
3821     }
3822
3823   /* *INDENT-OFF* */
3824   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3825   ({
3826     vec_add2 (nses, ns, 1);
3827     ns->name = (u8 *)(p->key);
3828     ns->value = (u32) p->value[0];
3829   }));
3830   /* *INDENT-ON* */
3831
3832   vec_sort_with_function (nses, name_sort_cmp);
3833
3834   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3835   vec_foreach (ns, nses)
3836   {
3837     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3838   }
3839   vec_free (nses);
3840   return 0;
3841 }
3842
3843 static int
3844 dump_ip_table (vat_main_t * vam, int is_ipv6)
3845 {
3846   const ip_details_t *det = NULL;
3847   const ip_address_details_t *address = NULL;
3848   u32 i = ~0;
3849
3850   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3851
3852   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3853   {
3854     i++;
3855     if (!det->present)
3856       {
3857         continue;
3858       }
3859     fformat (vam->ofp, "%-12d\n", i);
3860     fformat (vam->ofp,
3861              "            %-30s%-13s\n", "Address", "Prefix length");
3862     if (!det->addr)
3863       {
3864         continue;
3865       }
3866     vec_foreach (address, det->addr)
3867     {
3868       fformat (vam->ofp,
3869                "            %-30U%-13d\n",
3870                is_ipv6 ? format_ip6_address : format_ip4_address,
3871                address->ip, address->prefix_length);
3872     }
3873   }
3874
3875   return 0;
3876 }
3877
3878 static int
3879 dump_ipv4_table (vat_main_t * vam)
3880 {
3881   if (vam->json_output)
3882     {
3883       clib_warning
3884         ("JSON output supported only for VPE API calls and dump_stats_table");
3885       return -99;
3886     }
3887
3888   return dump_ip_table (vam, 0);
3889 }
3890
3891 static int
3892 dump_ipv6_table (vat_main_t * vam)
3893 {
3894   if (vam->json_output)
3895     {
3896       clib_warning
3897         ("JSON output supported only for VPE API calls and dump_stats_table");
3898       return -99;
3899     }
3900
3901   return dump_ip_table (vam, 1);
3902 }
3903
3904 static char *
3905 counter_type_to_str (u8 counter_type, u8 is_combined)
3906 {
3907   if (!is_combined)
3908     {
3909       switch (counter_type)
3910         {
3911         case VNET_INTERFACE_COUNTER_DROP:
3912           return "drop";
3913         case VNET_INTERFACE_COUNTER_PUNT:
3914           return "punt";
3915         case VNET_INTERFACE_COUNTER_IP4:
3916           return "ip4";
3917         case VNET_INTERFACE_COUNTER_IP6:
3918           return "ip6";
3919         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3920           return "rx-no-buf";
3921         case VNET_INTERFACE_COUNTER_RX_MISS:
3922           return "rx-miss";
3923         case VNET_INTERFACE_COUNTER_RX_ERROR:
3924           return "rx-error";
3925         case VNET_INTERFACE_COUNTER_TX_ERROR:
3926           return "tx-error";
3927         default:
3928           return "INVALID-COUNTER-TYPE";
3929         }
3930     }
3931   else
3932     {
3933       switch (counter_type)
3934         {
3935         case VNET_INTERFACE_COUNTER_RX:
3936           return "rx";
3937         case VNET_INTERFACE_COUNTER_TX:
3938           return "tx";
3939         default:
3940           return "INVALID-COUNTER-TYPE";
3941         }
3942     }
3943 }
3944
3945 static int
3946 dump_stats_table (vat_main_t * vam)
3947 {
3948   vat_json_node_t node;
3949   vat_json_node_t *msg_array;
3950   vat_json_node_t *msg;
3951   vat_json_node_t *counter_array;
3952   vat_json_node_t *counter;
3953   interface_counter_t c;
3954   u64 packets;
3955   ip4_fib_counter_t *c4;
3956   ip6_fib_counter_t *c6;
3957   int i, j;
3958
3959   if (!vam->json_output)
3960     {
3961       clib_warning ("dump_stats_table supported only in JSON format");
3962       return -99;
3963     }
3964
3965   vat_json_init_object (&node);
3966
3967   /* interface counters */
3968   msg_array = vat_json_object_add (&node, "interface_counters");
3969   vat_json_init_array (msg_array);
3970   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
3971     {
3972       msg = vat_json_array_add (msg_array);
3973       vat_json_init_object (msg);
3974       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3975                                        (u8 *) counter_type_to_str (i, 0));
3976       vat_json_object_add_int (msg, "is_combined", 0);
3977       counter_array = vat_json_object_add (msg, "data");
3978       vat_json_init_array (counter_array);
3979       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
3980         {
3981           packets = vam->simple_interface_counters[i][j];
3982           vat_json_array_add_uint (counter_array, packets);
3983         }
3984     }
3985   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
3986     {
3987       msg = vat_json_array_add (msg_array);
3988       vat_json_init_object (msg);
3989       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3990                                        (u8 *) counter_type_to_str (i, 1));
3991       vat_json_object_add_int (msg, "is_combined", 1);
3992       counter_array = vat_json_object_add (msg, "data");
3993       vat_json_init_array (counter_array);
3994       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
3995         {
3996           c = vam->combined_interface_counters[i][j];
3997           counter = vat_json_array_add (counter_array);
3998           vat_json_init_object (counter);
3999           vat_json_object_add_uint (counter, "packets", c.packets);
4000           vat_json_object_add_uint (counter, "bytes", c.bytes);
4001         }
4002     }
4003
4004   /* ip4 fib counters */
4005   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4006   vat_json_init_array (msg_array);
4007   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4008     {
4009       msg = vat_json_array_add (msg_array);
4010       vat_json_init_object (msg);
4011       vat_json_object_add_uint (msg, "vrf_id",
4012                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4013       counter_array = vat_json_object_add (msg, "c");
4014       vat_json_init_array (counter_array);
4015       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4016         {
4017           counter = vat_json_array_add (counter_array);
4018           vat_json_init_object (counter);
4019           c4 = &vam->ip4_fib_counters[i][j];
4020           vat_json_object_add_ip4 (counter, "address", c4->address);
4021           vat_json_object_add_uint (counter, "address_length",
4022                                     c4->address_length);
4023           vat_json_object_add_uint (counter, "packets", c4->packets);
4024           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4025         }
4026     }
4027
4028   /* ip6 fib counters */
4029   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4030   vat_json_init_array (msg_array);
4031   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4032     {
4033       msg = vat_json_array_add (msg_array);
4034       vat_json_init_object (msg);
4035       vat_json_object_add_uint (msg, "vrf_id",
4036                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4037       counter_array = vat_json_object_add (msg, "c");
4038       vat_json_init_array (counter_array);
4039       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4040         {
4041           counter = vat_json_array_add (counter_array);
4042           vat_json_init_object (counter);
4043           c6 = &vam->ip6_fib_counters[i][j];
4044           vat_json_object_add_ip6 (counter, "address", c6->address);
4045           vat_json_object_add_uint (counter, "address_length",
4046                                     c6->address_length);
4047           vat_json_object_add_uint (counter, "packets", c6->packets);
4048           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4049         }
4050     }
4051
4052   vat_json_print (vam->ofp, &node);
4053   vat_json_free (&node);
4054
4055   return 0;
4056 }
4057
4058 int
4059 exec (vat_main_t * vam)
4060 {
4061   api_main_t *am = &api_main;
4062   vl_api_cli_request_t *mp;
4063   f64 timeout;
4064   void *oldheap;
4065   u8 *cmd = 0;
4066   unformat_input_t *i = vam->input;
4067
4068   if (vec_len (i->buffer) == 0)
4069     return -1;
4070
4071   if (vam->exec_mode == 0 && unformat (i, "mode"))
4072     {
4073       vam->exec_mode = 1;
4074       return 0;
4075     }
4076   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4077     {
4078       vam->exec_mode = 0;
4079       return 0;
4080     }
4081
4082
4083   M (CLI_REQUEST, cli_request);
4084
4085   /*
4086    * Copy cmd into shared memory.
4087    * In order for the CLI command to work, it
4088    * must be a vector ending in \n, not a C-string ending
4089    * in \n\0.
4090    */
4091   pthread_mutex_lock (&am->vlib_rp->mutex);
4092   oldheap = svm_push_data_heap (am->vlib_rp);
4093
4094   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4095   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4096
4097   svm_pop_heap (oldheap);
4098   pthread_mutex_unlock (&am->vlib_rp->mutex);
4099
4100   mp->cmd_in_shmem = (u64) cmd;
4101   S;
4102   timeout = vat_time_now (vam) + 10.0;
4103
4104   while (vat_time_now (vam) < timeout)
4105     {
4106       if (vam->result_ready == 1)
4107         {
4108           u8 *free_me;
4109           if (vam->shmem_result != NULL)
4110             fformat (vam->ofp, "%s", vam->shmem_result);
4111           pthread_mutex_lock (&am->vlib_rp->mutex);
4112           oldheap = svm_push_data_heap (am->vlib_rp);
4113
4114           free_me = (u8 *) vam->shmem_result;
4115           vec_free (free_me);
4116
4117           svm_pop_heap (oldheap);
4118           pthread_mutex_unlock (&am->vlib_rp->mutex);
4119           return 0;
4120         }
4121     }
4122   return -99;
4123 }
4124
4125 /*
4126  * Future replacement of exec() that passes CLI buffers directly in
4127  * the API messages instead of an additional shared memory area.
4128  */
4129 static int
4130 exec_inband (vat_main_t * vam)
4131 {
4132   vl_api_cli_inband_t *mp;
4133   f64 timeout;
4134   unformat_input_t *i = vam->input;
4135
4136   if (vec_len (i->buffer) == 0)
4137     return -1;
4138
4139   if (vam->exec_mode == 0 && unformat (i, "mode"))
4140     {
4141       vam->exec_mode = 1;
4142       return 0;
4143     }
4144   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4145     {
4146       vam->exec_mode = 0;
4147       return 0;
4148     }
4149
4150   /*
4151    * In order for the CLI command to work, it
4152    * must be a vector ending in \n, not a C-string ending
4153    * in \n\0.
4154    */
4155   u32 len = vec_len (vam->input->buffer);
4156   M2 (CLI_INBAND, cli_inband, len);
4157   clib_memcpy (mp->cmd, vam->input->buffer, len);
4158   mp->length = htonl (len);
4159
4160   S;
4161   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4162 }
4163
4164 static int
4165 api_create_loopback (vat_main_t * vam)
4166 {
4167   unformat_input_t *i = vam->input;
4168   vl_api_create_loopback_t *mp;
4169   f64 timeout;
4170   u8 mac_address[6];
4171   u8 mac_set = 0;
4172
4173   memset (mac_address, 0, sizeof (mac_address));
4174
4175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4176     {
4177       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4178         mac_set = 1;
4179       else
4180         break;
4181     }
4182
4183   /* Construct the API message */
4184   M (CREATE_LOOPBACK, create_loopback);
4185   if (mac_set)
4186     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4187
4188   S;
4189   W;
4190 }
4191
4192 static int
4193 api_delete_loopback (vat_main_t * vam)
4194 {
4195   unformat_input_t *i = vam->input;
4196   vl_api_delete_loopback_t *mp;
4197   f64 timeout;
4198   u32 sw_if_index = ~0;
4199
4200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4201     {
4202       if (unformat (i, "sw_if_index %d", &sw_if_index))
4203         ;
4204       else
4205         break;
4206     }
4207
4208   if (sw_if_index == ~0)
4209     {
4210       errmsg ("missing sw_if_index\n");
4211       return -99;
4212     }
4213
4214   /* Construct the API message */
4215   M (DELETE_LOOPBACK, delete_loopback);
4216   mp->sw_if_index = ntohl (sw_if_index);
4217
4218   S;
4219   W;
4220 }
4221
4222 static int
4223 api_want_stats (vat_main_t * vam)
4224 {
4225   unformat_input_t *i = vam->input;
4226   vl_api_want_stats_t *mp;
4227   f64 timeout;
4228   int enable = -1;
4229
4230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4231     {
4232       if (unformat (i, "enable"))
4233         enable = 1;
4234       else if (unformat (i, "disable"))
4235         enable = 0;
4236       else
4237         break;
4238     }
4239
4240   if (enable == -1)
4241     {
4242       errmsg ("missing enable|disable\n");
4243       return -99;
4244     }
4245
4246   M (WANT_STATS, want_stats);
4247   mp->enable_disable = enable;
4248
4249   S;
4250   W;
4251 }
4252
4253 static int
4254 api_want_interface_events (vat_main_t * vam)
4255 {
4256   unformat_input_t *i = vam->input;
4257   vl_api_want_interface_events_t *mp;
4258   f64 timeout;
4259   int enable = -1;
4260
4261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4262     {
4263       if (unformat (i, "enable"))
4264         enable = 1;
4265       else if (unformat (i, "disable"))
4266         enable = 0;
4267       else
4268         break;
4269     }
4270
4271   if (enable == -1)
4272     {
4273       errmsg ("missing enable|disable\n");
4274       return -99;
4275     }
4276
4277   M (WANT_INTERFACE_EVENTS, want_interface_events);
4278   mp->enable_disable = enable;
4279
4280   vam->interface_event_display = enable;
4281
4282   S;
4283   W;
4284 }
4285
4286
4287 /* Note: non-static, called once to set up the initial intfc table */
4288 int
4289 api_sw_interface_dump (vat_main_t * vam)
4290 {
4291   vl_api_sw_interface_dump_t *mp;
4292   f64 timeout;
4293   hash_pair_t *p;
4294   name_sort_t *nses = 0, *ns;
4295   sw_interface_subif_t *sub = NULL;
4296
4297   /* Toss the old name table */
4298   /* *INDENT-OFF* */
4299   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4300   ({
4301     vec_add2 (nses, ns, 1);
4302     ns->name = (u8 *)(p->key);
4303     ns->value = (u32) p->value[0];
4304   }));
4305   /* *INDENT-ON* */
4306
4307   hash_free (vam->sw_if_index_by_interface_name);
4308
4309   vec_foreach (ns, nses) vec_free (ns->name);
4310
4311   vec_free (nses);
4312
4313   vec_foreach (sub, vam->sw_if_subif_table)
4314   {
4315     vec_free (sub->interface_name);
4316   }
4317   vec_free (vam->sw_if_subif_table);
4318
4319   /* recreate the interface name hash table */
4320   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4321
4322   /* Get list of ethernets */
4323   M (SW_INTERFACE_DUMP, sw_interface_dump);
4324   mp->name_filter_valid = 1;
4325   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4326   S;
4327
4328   /* and local / loopback interfaces */
4329   M (SW_INTERFACE_DUMP, sw_interface_dump);
4330   mp->name_filter_valid = 1;
4331   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4332   S;
4333
4334
4335   /* and vxlan-gpe tunnel interfaces */
4336   M (SW_INTERFACE_DUMP, sw_interface_dump);
4337   mp->name_filter_valid = 1;
4338   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4339            sizeof (mp->name_filter) - 1);
4340   S;
4341
4342   /* and vxlan tunnel interfaces */
4343   M (SW_INTERFACE_DUMP, sw_interface_dump);
4344   mp->name_filter_valid = 1;
4345   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4346   S;
4347
4348   /* and host (af_packet) interfaces */
4349   M (SW_INTERFACE_DUMP, sw_interface_dump);
4350   mp->name_filter_valid = 1;
4351   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4352   S;
4353
4354   /* and l2tpv3 tunnel interfaces */
4355   M (SW_INTERFACE_DUMP, sw_interface_dump);
4356   mp->name_filter_valid = 1;
4357   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4358            sizeof (mp->name_filter) - 1);
4359   S;
4360
4361   /* and GRE tunnel interfaces */
4362   M (SW_INTERFACE_DUMP, sw_interface_dump);
4363   mp->name_filter_valid = 1;
4364   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4365   S;
4366
4367   /* and LISP-GPE interfaces */
4368   M (SW_INTERFACE_DUMP, sw_interface_dump);
4369   mp->name_filter_valid = 1;
4370   strncpy ((char *) mp->name_filter, "lisp_gpe",
4371            sizeof (mp->name_filter) - 1);
4372   S;
4373
4374   /* Use a control ping for synchronization */
4375   {
4376     vl_api_control_ping_t *mp;
4377     M (CONTROL_PING, control_ping);
4378     S;
4379   }
4380   W;
4381 }
4382
4383 static int
4384 api_sw_interface_set_flags (vat_main_t * vam)
4385 {
4386   unformat_input_t *i = vam->input;
4387   vl_api_sw_interface_set_flags_t *mp;
4388   f64 timeout;
4389   u32 sw_if_index;
4390   u8 sw_if_index_set = 0;
4391   u8 admin_up = 0, link_up = 0;
4392
4393   /* Parse args required to build the message */
4394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4395     {
4396       if (unformat (i, "admin-up"))
4397         admin_up = 1;
4398       else if (unformat (i, "admin-down"))
4399         admin_up = 0;
4400       else if (unformat (i, "link-up"))
4401         link_up = 1;
4402       else if (unformat (i, "link-down"))
4403         link_up = 0;
4404       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4405         sw_if_index_set = 1;
4406       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4407         sw_if_index_set = 1;
4408       else
4409         break;
4410     }
4411
4412   if (sw_if_index_set == 0)
4413     {
4414       errmsg ("missing interface name or sw_if_index\n");
4415       return -99;
4416     }
4417
4418   /* Construct the API message */
4419   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4420   mp->sw_if_index = ntohl (sw_if_index);
4421   mp->admin_up_down = admin_up;
4422   mp->link_up_down = link_up;
4423
4424   /* send it... */
4425   S;
4426
4427   /* Wait for a reply, return the good/bad news... */
4428   W;
4429 }
4430
4431 static int
4432 api_sw_interface_clear_stats (vat_main_t * vam)
4433 {
4434   unformat_input_t *i = vam->input;
4435   vl_api_sw_interface_clear_stats_t *mp;
4436   f64 timeout;
4437   u32 sw_if_index;
4438   u8 sw_if_index_set = 0;
4439
4440   /* Parse args required to build the message */
4441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4442     {
4443       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4444         sw_if_index_set = 1;
4445       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4446         sw_if_index_set = 1;
4447       else
4448         break;
4449     }
4450
4451   /* Construct the API message */
4452   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4453
4454   if (sw_if_index_set == 1)
4455     mp->sw_if_index = ntohl (sw_if_index);
4456   else
4457     mp->sw_if_index = ~0;
4458
4459   /* send it... */
4460   S;
4461
4462   /* Wait for a reply, return the good/bad news... */
4463   W;
4464 }
4465
4466 static int
4467 api_sw_interface_add_del_address (vat_main_t * vam)
4468 {
4469   unformat_input_t *i = vam->input;
4470   vl_api_sw_interface_add_del_address_t *mp;
4471   f64 timeout;
4472   u32 sw_if_index;
4473   u8 sw_if_index_set = 0;
4474   u8 is_add = 1, del_all = 0;
4475   u32 address_length = 0;
4476   u8 v4_address_set = 0;
4477   u8 v6_address_set = 0;
4478   ip4_address_t v4address;
4479   ip6_address_t v6address;
4480
4481   /* Parse args required to build the message */
4482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4483     {
4484       if (unformat (i, "del-all"))
4485         del_all = 1;
4486       else if (unformat (i, "del"))
4487         is_add = 0;
4488       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4489         sw_if_index_set = 1;
4490       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4491         sw_if_index_set = 1;
4492       else if (unformat (i, "%U/%d",
4493                          unformat_ip4_address, &v4address, &address_length))
4494         v4_address_set = 1;
4495       else if (unformat (i, "%U/%d",
4496                          unformat_ip6_address, &v6address, &address_length))
4497         v6_address_set = 1;
4498       else
4499         break;
4500     }
4501
4502   if (sw_if_index_set == 0)
4503     {
4504       errmsg ("missing interface name or sw_if_index\n");
4505       return -99;
4506     }
4507   if (v4_address_set && v6_address_set)
4508     {
4509       errmsg ("both v4 and v6 addresses set\n");
4510       return -99;
4511     }
4512   if (!v4_address_set && !v6_address_set && !del_all)
4513     {
4514       errmsg ("no addresses set\n");
4515       return -99;
4516     }
4517
4518   /* Construct the API message */
4519   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4520
4521   mp->sw_if_index = ntohl (sw_if_index);
4522   mp->is_add = is_add;
4523   mp->del_all = del_all;
4524   if (v6_address_set)
4525     {
4526       mp->is_ipv6 = 1;
4527       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4528     }
4529   else
4530     {
4531       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4532     }
4533   mp->address_length = address_length;
4534
4535   /* send it... */
4536   S;
4537
4538   /* Wait for a reply, return good/bad news  */
4539   W;
4540 }
4541
4542 static int
4543 api_sw_interface_set_table (vat_main_t * vam)
4544 {
4545   unformat_input_t *i = vam->input;
4546   vl_api_sw_interface_set_table_t *mp;
4547   f64 timeout;
4548   u32 sw_if_index, vrf_id = 0;
4549   u8 sw_if_index_set = 0;
4550   u8 is_ipv6 = 0;
4551
4552   /* Parse args required to build the message */
4553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4554     {
4555       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4556         sw_if_index_set = 1;
4557       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4558         sw_if_index_set = 1;
4559       else if (unformat (i, "vrf %d", &vrf_id))
4560         ;
4561       else if (unformat (i, "ipv6"))
4562         is_ipv6 = 1;
4563       else
4564         break;
4565     }
4566
4567   if (sw_if_index_set == 0)
4568     {
4569       errmsg ("missing interface name or sw_if_index\n");
4570       return -99;
4571     }
4572
4573   /* Construct the API message */
4574   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4575
4576   mp->sw_if_index = ntohl (sw_if_index);
4577   mp->is_ipv6 = is_ipv6;
4578   mp->vrf_id = ntohl (vrf_id);
4579
4580   /* send it... */
4581   S;
4582
4583   /* Wait for a reply... */
4584   W;
4585 }
4586
4587 static int
4588 api_sw_interface_set_vpath (vat_main_t * vam)
4589 {
4590   unformat_input_t *i = vam->input;
4591   vl_api_sw_interface_set_vpath_t *mp;
4592   f64 timeout;
4593   u32 sw_if_index = 0;
4594   u8 sw_if_index_set = 0;
4595   u8 is_enable = 0;
4596
4597   /* Parse args required to build the message */
4598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4599     {
4600       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4601         sw_if_index_set = 1;
4602       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4603         sw_if_index_set = 1;
4604       else if (unformat (i, "enable"))
4605         is_enable = 1;
4606       else if (unformat (i, "disable"))
4607         is_enable = 0;
4608       else
4609         break;
4610     }
4611
4612   if (sw_if_index_set == 0)
4613     {
4614       errmsg ("missing interface name or sw_if_index\n");
4615       return -99;
4616     }
4617
4618   /* Construct the API message */
4619   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4620
4621   mp->sw_if_index = ntohl (sw_if_index);
4622   mp->enable = is_enable;
4623
4624   /* send it... */
4625   S;
4626
4627   /* Wait for a reply... */
4628   W;
4629 }
4630
4631 static int
4632 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4633 {
4634   unformat_input_t *i = vam->input;
4635   vl_api_sw_interface_set_l2_xconnect_t *mp;
4636   f64 timeout;
4637   u32 rx_sw_if_index;
4638   u8 rx_sw_if_index_set = 0;
4639   u32 tx_sw_if_index;
4640   u8 tx_sw_if_index_set = 0;
4641   u8 enable = 1;
4642
4643   /* Parse args required to build the message */
4644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4645     {
4646       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4647         rx_sw_if_index_set = 1;
4648       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4649         tx_sw_if_index_set = 1;
4650       else if (unformat (i, "rx"))
4651         {
4652           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4653             {
4654               if (unformat (i, "%U", unformat_sw_if_index, vam,
4655                             &rx_sw_if_index))
4656                 rx_sw_if_index_set = 1;
4657             }
4658           else
4659             break;
4660         }
4661       else if (unformat (i, "tx"))
4662         {
4663           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4664             {
4665               if (unformat (i, "%U", unformat_sw_if_index, vam,
4666                             &tx_sw_if_index))
4667                 tx_sw_if_index_set = 1;
4668             }
4669           else
4670             break;
4671         }
4672       else if (unformat (i, "enable"))
4673         enable = 1;
4674       else if (unformat (i, "disable"))
4675         enable = 0;
4676       else
4677         break;
4678     }
4679
4680   if (rx_sw_if_index_set == 0)
4681     {
4682       errmsg ("missing rx interface name or rx_sw_if_index\n");
4683       return -99;
4684     }
4685
4686   if (enable && (tx_sw_if_index_set == 0))
4687     {
4688       errmsg ("missing tx interface name or tx_sw_if_index\n");
4689       return -99;
4690     }
4691
4692   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4693
4694   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4695   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4696   mp->enable = enable;
4697
4698   S;
4699   W;
4700   /* NOTREACHED */
4701   return 0;
4702 }
4703
4704 static int
4705 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4706 {
4707   unformat_input_t *i = vam->input;
4708   vl_api_sw_interface_set_l2_bridge_t *mp;
4709   f64 timeout;
4710   u32 rx_sw_if_index;
4711   u8 rx_sw_if_index_set = 0;
4712   u32 bd_id;
4713   u8 bd_id_set = 0;
4714   u8 bvi = 0;
4715   u32 shg = 0;
4716   u8 enable = 1;
4717
4718   /* Parse args required to build the message */
4719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4720     {
4721       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4722         rx_sw_if_index_set = 1;
4723       else if (unformat (i, "bd_id %d", &bd_id))
4724         bd_id_set = 1;
4725       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
4726         rx_sw_if_index_set = 1;
4727       else if (unformat (i, "shg %d", &shg))
4728         ;
4729       else if (unformat (i, "bvi"))
4730         bvi = 1;
4731       else if (unformat (i, "enable"))
4732         enable = 1;
4733       else if (unformat (i, "disable"))
4734         enable = 0;
4735       else
4736         break;
4737     }
4738
4739   if (rx_sw_if_index_set == 0)
4740     {
4741       errmsg ("missing rx interface name or sw_if_index\n");
4742       return -99;
4743     }
4744
4745   if (enable && (bd_id_set == 0))
4746     {
4747       errmsg ("missing bridge domain\n");
4748       return -99;
4749     }
4750
4751   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
4752
4753   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4754   mp->bd_id = ntohl (bd_id);
4755   mp->shg = (u8) shg;
4756   mp->bvi = bvi;
4757   mp->enable = enable;
4758
4759   S;
4760   W;
4761   /* NOTREACHED */
4762   return 0;
4763 }
4764
4765 static int
4766 api_bridge_domain_dump (vat_main_t * vam)
4767 {
4768   unformat_input_t *i = vam->input;
4769   vl_api_bridge_domain_dump_t *mp;
4770   f64 timeout;
4771   u32 bd_id = ~0;
4772
4773   /* Parse args required to build the message */
4774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4775     {
4776       if (unformat (i, "bd_id %d", &bd_id))
4777         ;
4778       else
4779         break;
4780     }
4781
4782   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
4783   mp->bd_id = ntohl (bd_id);
4784   S;
4785
4786   /* Use a control ping for synchronization */
4787   {
4788     vl_api_control_ping_t *mp;
4789     M (CONTROL_PING, control_ping);
4790     S;
4791   }
4792
4793   W;
4794   /* NOTREACHED */
4795   return 0;
4796 }
4797
4798 static int
4799 api_bridge_domain_add_del (vat_main_t * vam)
4800 {
4801   unformat_input_t *i = vam->input;
4802   vl_api_bridge_domain_add_del_t *mp;
4803   f64 timeout;
4804   u32 bd_id = ~0;
4805   u8 is_add = 1;
4806   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4807
4808   /* Parse args required to build the message */
4809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4810     {
4811       if (unformat (i, "bd_id %d", &bd_id))
4812         ;
4813       else if (unformat (i, "flood %d", &flood))
4814         ;
4815       else if (unformat (i, "uu-flood %d", &uu_flood))
4816         ;
4817       else if (unformat (i, "forward %d", &forward))
4818         ;
4819       else if (unformat (i, "learn %d", &learn))
4820         ;
4821       else if (unformat (i, "arp-term %d", &arp_term))
4822         ;
4823       else if (unformat (i, "del"))
4824         {
4825           is_add = 0;
4826           flood = uu_flood = forward = learn = 0;
4827         }
4828       else
4829         break;
4830     }
4831
4832   if (bd_id == ~0)
4833     {
4834       errmsg ("missing bridge domain\n");
4835       return -99;
4836     }
4837
4838   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
4839
4840   mp->bd_id = ntohl (bd_id);
4841   mp->flood = flood;
4842   mp->uu_flood = uu_flood;
4843   mp->forward = forward;
4844   mp->learn = learn;
4845   mp->arp_term = arp_term;
4846   mp->is_add = is_add;
4847
4848   S;
4849   W;
4850   /* NOTREACHED */
4851   return 0;
4852 }
4853
4854 static int
4855 api_l2fib_add_del (vat_main_t * vam)
4856 {
4857   unformat_input_t *i = vam->input;
4858   vl_api_l2fib_add_del_t *mp;
4859   f64 timeout;
4860   u64 mac = 0;
4861   u8 mac_set = 0;
4862   u32 bd_id;
4863   u8 bd_id_set = 0;
4864   u32 sw_if_index;
4865   u8 sw_if_index_set = 0;
4866   u8 is_add = 1;
4867   u8 static_mac = 0;
4868   u8 filter_mac = 0;
4869   u8 bvi_mac = 0;
4870   int count = 1;
4871   f64 before = 0;
4872   int j;
4873
4874   /* Parse args required to build the message */
4875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4876     {
4877       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
4878         mac_set = 1;
4879       else if (unformat (i, "bd_id %d", &bd_id))
4880         bd_id_set = 1;
4881       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4882         sw_if_index_set = 1;
4883       else if (unformat (i, "sw_if"))
4884         {
4885           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4886             {
4887               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4888                 sw_if_index_set = 1;
4889             }
4890           else
4891             break;
4892         }
4893       else if (unformat (i, "static"))
4894         static_mac = 1;
4895       else if (unformat (i, "filter"))
4896         {
4897           filter_mac = 1;
4898           static_mac = 1;
4899         }
4900       else if (unformat (i, "bvi"))
4901         {
4902           bvi_mac = 1;
4903           static_mac = 1;
4904         }
4905       else if (unformat (i, "del"))
4906         is_add = 0;
4907       else if (unformat (i, "count %d", &count))
4908         ;
4909       else
4910         break;
4911     }
4912
4913   if (mac_set == 0)
4914     {
4915       errmsg ("missing mac address\n");
4916       return -99;
4917     }
4918
4919   if (bd_id_set == 0)
4920     {
4921       errmsg ("missing bridge domain\n");
4922       return -99;
4923     }
4924
4925   if (is_add && (sw_if_index_set == 0))
4926     {
4927       errmsg ("missing interface name or sw_if_index\n");
4928       return -99;
4929     }
4930
4931   if (count > 1)
4932     {
4933       /* Turn on async mode */
4934       vam->async_mode = 1;
4935       vam->async_errors = 0;
4936       before = vat_time_now (vam);
4937     }
4938
4939   for (j = 0; j < count; j++)
4940     {
4941       M (L2FIB_ADD_DEL, l2fib_add_del);
4942
4943       mp->mac = mac;
4944       mp->bd_id = ntohl (bd_id);
4945       mp->is_add = is_add;
4946
4947       if (is_add)
4948         {
4949           mp->sw_if_index = ntohl (sw_if_index);
4950           mp->static_mac = static_mac;
4951           mp->filter_mac = filter_mac;
4952           mp->bvi_mac = bvi_mac;
4953         }
4954       increment_mac_address (&mac);
4955       /* send it... */
4956       S;
4957     }
4958
4959   if (count > 1)
4960     {
4961       vl_api_control_ping_t *mp;
4962       f64 after;
4963
4964       /* Shut off async mode */
4965       vam->async_mode = 0;
4966
4967       M (CONTROL_PING, control_ping);
4968       S;
4969
4970       timeout = vat_time_now (vam) + 1.0;
4971       while (vat_time_now (vam) < timeout)
4972         if (vam->result_ready == 1)
4973           goto out;
4974       vam->retval = -99;
4975
4976     out:
4977       if (vam->retval == -99)
4978         errmsg ("timeout\n");
4979
4980       if (vam->async_errors > 0)
4981         {
4982           errmsg ("%d asynchronous errors\n", vam->async_errors);
4983           vam->retval = -98;
4984         }
4985       vam->async_errors = 0;
4986       after = vat_time_now (vam);
4987
4988       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4989                count, after - before, count / (after - before));
4990     }
4991   else
4992     {
4993       /* Wait for a reply... */
4994       W;
4995     }
4996   /* Return the good/bad news */
4997   return (vam->retval);
4998 }
4999
5000 static int
5001 api_l2_flags (vat_main_t * vam)
5002 {
5003   unformat_input_t *i = vam->input;
5004   vl_api_l2_flags_t *mp;
5005   f64 timeout;
5006   u32 sw_if_index;
5007   u32 feature_bitmap = 0;
5008   u8 sw_if_index_set = 0;
5009
5010   /* Parse args required to build the message */
5011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5012     {
5013       if (unformat (i, "sw_if_index %d", &sw_if_index))
5014         sw_if_index_set = 1;
5015       else if (unformat (i, "sw_if"))
5016         {
5017           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5018             {
5019               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5020                 sw_if_index_set = 1;
5021             }
5022           else
5023             break;
5024         }
5025       else if (unformat (i, "learn"))
5026         feature_bitmap |= L2INPUT_FEAT_LEARN;
5027       else if (unformat (i, "forward"))
5028         feature_bitmap |= L2INPUT_FEAT_FWD;
5029       else if (unformat (i, "flood"))
5030         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5031       else if (unformat (i, "uu-flood"))
5032         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5033       else
5034         break;
5035     }
5036
5037   if (sw_if_index_set == 0)
5038     {
5039       errmsg ("missing interface name or sw_if_index\n");
5040       return -99;
5041     }
5042
5043   M (L2_FLAGS, l2_flags);
5044
5045   mp->sw_if_index = ntohl (sw_if_index);
5046   mp->feature_bitmap = ntohl (feature_bitmap);
5047
5048   S;
5049   W;
5050   /* NOTREACHED */
5051   return 0;
5052 }
5053
5054 static int
5055 api_bridge_flags (vat_main_t * vam)
5056 {
5057   unformat_input_t *i = vam->input;
5058   vl_api_bridge_flags_t *mp;
5059   f64 timeout;
5060   u32 bd_id;
5061   u8 bd_id_set = 0;
5062   u8 is_set = 1;
5063   u32 flags = 0;
5064
5065   /* Parse args required to build the message */
5066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5067     {
5068       if (unformat (i, "bd_id %d", &bd_id))
5069         bd_id_set = 1;
5070       else if (unformat (i, "learn"))
5071         flags |= L2_LEARN;
5072       else if (unformat (i, "forward"))
5073         flags |= L2_FWD;
5074       else if (unformat (i, "flood"))
5075         flags |= L2_FLOOD;
5076       else if (unformat (i, "uu-flood"))
5077         flags |= L2_UU_FLOOD;
5078       else if (unformat (i, "arp-term"))
5079         flags |= L2_ARP_TERM;
5080       else if (unformat (i, "off"))
5081         is_set = 0;
5082       else if (unformat (i, "disable"))
5083         is_set = 0;
5084       else
5085         break;
5086     }
5087
5088   if (bd_id_set == 0)
5089     {
5090       errmsg ("missing bridge domain\n");
5091       return -99;
5092     }
5093
5094   M (BRIDGE_FLAGS, bridge_flags);
5095
5096   mp->bd_id = ntohl (bd_id);
5097   mp->feature_bitmap = ntohl (flags);
5098   mp->is_set = is_set;
5099
5100   S;
5101   W;
5102   /* NOTREACHED */
5103   return 0;
5104 }
5105
5106 static int
5107 api_bd_ip_mac_add_del (vat_main_t * vam)
5108 {
5109   unformat_input_t *i = vam->input;
5110   vl_api_bd_ip_mac_add_del_t *mp;
5111   f64 timeout;
5112   u32 bd_id;
5113   u8 is_ipv6 = 0;
5114   u8 is_add = 1;
5115   u8 bd_id_set = 0;
5116   u8 ip_set = 0;
5117   u8 mac_set = 0;
5118   ip4_address_t v4addr;
5119   ip6_address_t v6addr;
5120   u8 macaddr[6];
5121
5122
5123   /* Parse args required to build the message */
5124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5125     {
5126       if (unformat (i, "bd_id %d", &bd_id))
5127         {
5128           bd_id_set++;
5129         }
5130       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5131         {
5132           ip_set++;
5133         }
5134       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5135         {
5136           ip_set++;
5137           is_ipv6++;
5138         }
5139       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5140         {
5141           mac_set++;
5142         }
5143       else if (unformat (i, "del"))
5144         is_add = 0;
5145       else
5146         break;
5147     }
5148
5149   if (bd_id_set == 0)
5150     {
5151       errmsg ("missing bridge domain\n");
5152       return -99;
5153     }
5154   else if (ip_set == 0)
5155     {
5156       errmsg ("missing IP address\n");
5157       return -99;
5158     }
5159   else if (mac_set == 0)
5160     {
5161       errmsg ("missing MAC address\n");
5162       return -99;
5163     }
5164
5165   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5166
5167   mp->bd_id = ntohl (bd_id);
5168   mp->is_ipv6 = is_ipv6;
5169   mp->is_add = is_add;
5170   if (is_ipv6)
5171     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5172   else
5173     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5174   clib_memcpy (mp->mac_address, macaddr, 6);
5175   S;
5176   W;
5177   /* NOTREACHED */
5178   return 0;
5179 }
5180
5181 static int
5182 api_tap_connect (vat_main_t * vam)
5183 {
5184   unformat_input_t *i = vam->input;
5185   vl_api_tap_connect_t *mp;
5186   f64 timeout;
5187   u8 mac_address[6];
5188   u8 random_mac = 1;
5189   u8 name_set = 0;
5190   u8 *tap_name;
5191
5192   memset (mac_address, 0, sizeof (mac_address));
5193
5194   /* Parse args required to build the message */
5195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5196     {
5197       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5198         {
5199           random_mac = 0;
5200         }
5201       else if (unformat (i, "random-mac"))
5202         random_mac = 1;
5203       else if (unformat (i, "tapname %s", &tap_name))
5204         name_set = 1;
5205       else
5206         break;
5207     }
5208
5209   if (name_set == 0)
5210     {
5211       errmsg ("missing tap name\n");
5212       return -99;
5213     }
5214   if (vec_len (tap_name) > 63)
5215     {
5216       errmsg ("tap name too long\n");
5217     }
5218   vec_add1 (tap_name, 0);
5219
5220   /* Construct the API message */
5221   M (TAP_CONNECT, tap_connect);
5222
5223   mp->use_random_mac = random_mac;
5224   clib_memcpy (mp->mac_address, mac_address, 6);
5225   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5226   vec_free (tap_name);
5227
5228   /* send it... */
5229   S;
5230
5231   /* Wait for a reply... */
5232   W;
5233 }
5234
5235 static int
5236 api_tap_modify (vat_main_t * vam)
5237 {
5238   unformat_input_t *i = vam->input;
5239   vl_api_tap_modify_t *mp;
5240   f64 timeout;
5241   u8 mac_address[6];
5242   u8 random_mac = 1;
5243   u8 name_set = 0;
5244   u8 *tap_name;
5245   u32 sw_if_index = ~0;
5246   u8 sw_if_index_set = 0;
5247
5248   memset (mac_address, 0, sizeof (mac_address));
5249
5250   /* Parse args required to build the message */
5251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5252     {
5253       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5254         sw_if_index_set = 1;
5255       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5256         sw_if_index_set = 1;
5257       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5258         {
5259           random_mac = 0;
5260         }
5261       else if (unformat (i, "random-mac"))
5262         random_mac = 1;
5263       else if (unformat (i, "tapname %s", &tap_name))
5264         name_set = 1;
5265       else
5266         break;
5267     }
5268
5269   if (sw_if_index_set == 0)
5270     {
5271       errmsg ("missing vpp interface name");
5272       return -99;
5273     }
5274   if (name_set == 0)
5275     {
5276       errmsg ("missing tap name\n");
5277       return -99;
5278     }
5279   if (vec_len (tap_name) > 63)
5280     {
5281       errmsg ("tap name too long\n");
5282     }
5283   vec_add1 (tap_name, 0);
5284
5285   /* Construct the API message */
5286   M (TAP_MODIFY, tap_modify);
5287
5288   mp->use_random_mac = random_mac;
5289   mp->sw_if_index = ntohl (sw_if_index);
5290   clib_memcpy (mp->mac_address, mac_address, 6);
5291   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5292   vec_free (tap_name);
5293
5294   /* send it... */
5295   S;
5296
5297   /* Wait for a reply... */
5298   W;
5299 }
5300
5301 static int
5302 api_tap_delete (vat_main_t * vam)
5303 {
5304   unformat_input_t *i = vam->input;
5305   vl_api_tap_delete_t *mp;
5306   f64 timeout;
5307   u32 sw_if_index = ~0;
5308   u8 sw_if_index_set = 0;
5309
5310   /* Parse args required to build the message */
5311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5312     {
5313       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5314         sw_if_index_set = 1;
5315       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5316         sw_if_index_set = 1;
5317       else
5318         break;
5319     }
5320
5321   if (sw_if_index_set == 0)
5322     {
5323       errmsg ("missing vpp interface name");
5324       return -99;
5325     }
5326
5327   /* Construct the API message */
5328   M (TAP_DELETE, tap_delete);
5329
5330   mp->sw_if_index = ntohl (sw_if_index);
5331
5332   /* send it... */
5333   S;
5334
5335   /* Wait for a reply... */
5336   W;
5337 }
5338
5339 static int
5340 api_ip_add_del_route (vat_main_t * vam)
5341 {
5342   unformat_input_t *i = vam->input;
5343   vl_api_ip_add_del_route_t *mp;
5344   f64 timeout;
5345   u32 sw_if_index = ~0, vrf_id = 0;
5346   u8 sw_if_index_set = 0;
5347   u8 is_ipv6 = 0;
5348   u8 is_local = 0, is_drop = 0;
5349   u8 create_vrf_if_needed = 0;
5350   u8 is_add = 1;
5351   u8 next_hop_weight = 1;
5352   u8 not_last = 0;
5353   u8 is_multipath = 0;
5354   u8 address_set = 0;
5355   u8 address_length_set = 0;
5356   u32 lookup_in_vrf = 0;
5357   u32 resolve_attempts = 0;
5358   u32 dst_address_length = 0;
5359   u8 next_hop_set = 0;
5360   ip4_address_t v4_dst_address, v4_next_hop_address;
5361   ip6_address_t v6_dst_address, v6_next_hop_address;
5362   int count = 1;
5363   int j;
5364   f64 before = 0;
5365   u32 random_add_del = 0;
5366   u32 *random_vector = 0;
5367   uword *random_hash;
5368   u32 random_seed = 0xdeaddabe;
5369   u32 classify_table_index = ~0;
5370   u8 is_classify = 0;
5371
5372   /* Parse args required to build the message */
5373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5374     {
5375       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5376         sw_if_index_set = 1;
5377       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5378         sw_if_index_set = 1;
5379       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5380         {
5381           address_set = 1;
5382           is_ipv6 = 0;
5383         }
5384       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5385         {
5386           address_set = 1;
5387           is_ipv6 = 1;
5388         }
5389       else if (unformat (i, "/%d", &dst_address_length))
5390         {
5391           address_length_set = 1;
5392         }
5393
5394       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5395                                          &v4_next_hop_address))
5396         {
5397           next_hop_set = 1;
5398         }
5399       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5400                                          &v6_next_hop_address))
5401         {
5402           next_hop_set = 1;
5403         }
5404       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5405         ;
5406       else if (unformat (i, "weight %d", &next_hop_weight))
5407         ;
5408       else if (unformat (i, "drop"))
5409         {
5410           is_drop = 1;
5411         }
5412       else if (unformat (i, "local"))
5413         {
5414           is_local = 1;
5415         }
5416       else if (unformat (i, "classify %d", &classify_table_index))
5417         {
5418           is_classify = 1;
5419         }
5420       else if (unformat (i, "del"))
5421         is_add = 0;
5422       else if (unformat (i, "add"))
5423         is_add = 1;
5424       else if (unformat (i, "not-last"))
5425         not_last = 1;
5426       else if (unformat (i, "multipath"))
5427         is_multipath = 1;
5428       else if (unformat (i, "vrf %d", &vrf_id))
5429         ;
5430       else if (unformat (i, "create-vrf"))
5431         create_vrf_if_needed = 1;
5432       else if (unformat (i, "count %d", &count))
5433         ;
5434       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5435         ;
5436       else if (unformat (i, "random"))
5437         random_add_del = 1;
5438       else if (unformat (i, "seed %d", &random_seed))
5439         ;
5440       else
5441         {
5442           clib_warning ("parse error '%U'", format_unformat_error, i);
5443           return -99;
5444         }
5445     }
5446
5447   if (resolve_attempts > 0 && sw_if_index_set == 0)
5448     {
5449       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5450       return -99;
5451     }
5452
5453   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5454     {
5455       errmsg ("next hop / local / drop / classify not set\n");
5456       return -99;
5457     }
5458
5459   if (address_set == 0)
5460     {
5461       errmsg ("missing addresses\n");
5462       return -99;
5463     }
5464
5465   if (address_length_set == 0)
5466     {
5467       errmsg ("missing address length\n");
5468       return -99;
5469     }
5470
5471   /* Generate a pile of unique, random routes */
5472   if (random_add_del)
5473     {
5474       u32 this_random_address;
5475       random_hash = hash_create (count, sizeof (uword));
5476
5477       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5478       for (j = 0; j <= count; j++)
5479         {
5480           do
5481             {
5482               this_random_address = random_u32 (&random_seed);
5483               this_random_address =
5484                 clib_host_to_net_u32 (this_random_address);
5485             }
5486           while (hash_get (random_hash, this_random_address));
5487           vec_add1 (random_vector, this_random_address);
5488           hash_set (random_hash, this_random_address, 1);
5489         }
5490       hash_free (random_hash);
5491       v4_dst_address.as_u32 = random_vector[0];
5492     }
5493
5494   if (count > 1)
5495     {
5496       /* Turn on async mode */
5497       vam->async_mode = 1;
5498       vam->async_errors = 0;
5499       before = vat_time_now (vam);
5500     }
5501
5502   for (j = 0; j < count; j++)
5503     {
5504       /* Construct the API message */
5505       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5506
5507       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5508       mp->vrf_id = ntohl (vrf_id);
5509       if (resolve_attempts > 0)
5510         {
5511           mp->resolve_attempts = ntohl (resolve_attempts);
5512           mp->resolve_if_needed = 1;
5513         }
5514       mp->create_vrf_if_needed = create_vrf_if_needed;
5515
5516       mp->is_add = is_add;
5517       mp->is_drop = is_drop;
5518       mp->is_ipv6 = is_ipv6;
5519       mp->is_local = is_local;
5520       mp->is_classify = is_classify;
5521       mp->is_multipath = is_multipath;
5522       mp->not_last = not_last;
5523       mp->next_hop_weight = next_hop_weight;
5524       mp->dst_address_length = dst_address_length;
5525       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5526       mp->classify_table_index = ntohl (classify_table_index);
5527
5528       if (is_ipv6)
5529         {
5530           clib_memcpy (mp->dst_address, &v6_dst_address,
5531                        sizeof (v6_dst_address));
5532           if (next_hop_set)
5533             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5534                          sizeof (v6_next_hop_address));
5535           increment_v6_address (&v6_dst_address);
5536         }
5537       else
5538         {
5539           clib_memcpy (mp->dst_address, &v4_dst_address,
5540                        sizeof (v4_dst_address));
5541           if (next_hop_set)
5542             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5543                          sizeof (v4_next_hop_address));
5544           if (random_add_del)
5545             v4_dst_address.as_u32 = random_vector[j + 1];
5546           else
5547             increment_v4_address (&v4_dst_address);
5548         }
5549       /* send it... */
5550       S;
5551     }
5552
5553   /* When testing multiple add/del ops, use a control-ping to sync */
5554   if (count > 1)
5555     {
5556       vl_api_control_ping_t *mp;
5557       f64 after;
5558
5559       /* Shut off async mode */
5560       vam->async_mode = 0;
5561
5562       M (CONTROL_PING, control_ping);
5563       S;
5564
5565       timeout = vat_time_now (vam) + 1.0;
5566       while (vat_time_now (vam) < timeout)
5567         if (vam->result_ready == 1)
5568           goto out;
5569       vam->retval = -99;
5570
5571     out:
5572       if (vam->retval == -99)
5573         errmsg ("timeout\n");
5574
5575       if (vam->async_errors > 0)
5576         {
5577           errmsg ("%d asynchronous errors\n", vam->async_errors);
5578           vam->retval = -98;
5579         }
5580       vam->async_errors = 0;
5581       after = vat_time_now (vam);
5582
5583       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5584                count, after - before, count / (after - before));
5585     }
5586   else
5587     {
5588       /* Wait for a reply... */
5589       W;
5590     }
5591
5592   /* Return the good/bad news */
5593   return (vam->retval);
5594 }
5595
5596 static int
5597 api_proxy_arp_add_del (vat_main_t * vam)
5598 {
5599   unformat_input_t *i = vam->input;
5600   vl_api_proxy_arp_add_del_t *mp;
5601   f64 timeout;
5602   u32 vrf_id = 0;
5603   u8 is_add = 1;
5604   ip4_address_t lo, hi;
5605   u8 range_set = 0;
5606
5607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5608     {
5609       if (unformat (i, "vrf %d", &vrf_id))
5610         ;
5611       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5612                          unformat_ip4_address, &hi))
5613         range_set = 1;
5614       else if (unformat (i, "del"))
5615         is_add = 0;
5616       else
5617         {
5618           clib_warning ("parse error '%U'", format_unformat_error, i);
5619           return -99;
5620         }
5621     }
5622
5623   if (range_set == 0)
5624     {
5625       errmsg ("address range not set\n");
5626       return -99;
5627     }
5628
5629   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5630
5631   mp->vrf_id = ntohl (vrf_id);
5632   mp->is_add = is_add;
5633   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5634   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5635
5636   S;
5637   W;
5638   /* NOTREACHED */
5639   return 0;
5640 }
5641
5642 static int
5643 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5644 {
5645   unformat_input_t *i = vam->input;
5646   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5647   f64 timeout;
5648   u32 sw_if_index;
5649   u8 enable = 1;
5650   u8 sw_if_index_set = 0;
5651
5652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5653     {
5654       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5655         sw_if_index_set = 1;
5656       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5657         sw_if_index_set = 1;
5658       else if (unformat (i, "enable"))
5659         enable = 1;
5660       else if (unformat (i, "disable"))
5661         enable = 0;
5662       else
5663         {
5664           clib_warning ("parse error '%U'", format_unformat_error, i);
5665           return -99;
5666         }
5667     }
5668
5669   if (sw_if_index_set == 0)
5670     {
5671       errmsg ("missing interface name or sw_if_index\n");
5672       return -99;
5673     }
5674
5675   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5676
5677   mp->sw_if_index = ntohl (sw_if_index);
5678   mp->enable_disable = enable;
5679
5680   S;
5681   W;
5682   /* NOTREACHED */
5683   return 0;
5684 }
5685
5686 static int
5687 api_mpls_add_del_decap (vat_main_t * vam)
5688 {
5689   unformat_input_t *i = vam->input;
5690   vl_api_mpls_add_del_decap_t *mp;
5691   f64 timeout;
5692   u32 rx_vrf_id = 0;
5693   u32 tx_vrf_id = 0;
5694   u32 label = 0;
5695   u8 is_add = 1;
5696   u8 s_bit = 1;
5697   u32 next_index = 1;
5698
5699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5700     {
5701       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5702         ;
5703       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5704         ;
5705       else if (unformat (i, "label %d", &label))
5706         ;
5707       else if (unformat (i, "next-index %d", &next_index))
5708         ;
5709       else if (unformat (i, "del"))
5710         is_add = 0;
5711       else if (unformat (i, "s-bit-clear"))
5712         s_bit = 0;
5713       else
5714         {
5715           clib_warning ("parse error '%U'", format_unformat_error, i);
5716           return -99;
5717         }
5718     }
5719
5720   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5721
5722   mp->rx_vrf_id = ntohl (rx_vrf_id);
5723   mp->tx_vrf_id = ntohl (tx_vrf_id);
5724   mp->label = ntohl (label);
5725   mp->next_index = ntohl (next_index);
5726   mp->s_bit = s_bit;
5727   mp->is_add = is_add;
5728
5729   S;
5730   W;
5731   /* NOTREACHED */
5732   return 0;
5733 }
5734
5735 static int
5736 api_mpls_add_del_encap (vat_main_t * vam)
5737 {
5738   unformat_input_t *i = vam->input;
5739   vl_api_mpls_add_del_encap_t *mp;
5740   f64 timeout;
5741   u32 vrf_id = 0;
5742   u32 *labels = 0;
5743   u32 label;
5744   ip4_address_t dst_address;
5745   u8 is_add = 1;
5746
5747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5748     {
5749       if (unformat (i, "vrf %d", &vrf_id))
5750         ;
5751       else if (unformat (i, "label %d", &label))
5752         vec_add1 (labels, ntohl (label));
5753       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5754         ;
5755       else if (unformat (i, "del"))
5756         is_add = 0;
5757       else
5758         {
5759           clib_warning ("parse error '%U'", format_unformat_error, i);
5760           return -99;
5761         }
5762     }
5763
5764   if (vec_len (labels) == 0)
5765     {
5766       errmsg ("missing encap label stack\n");
5767       return -99;
5768     }
5769
5770   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
5771       sizeof (u32) * vec_len (labels));
5772
5773   mp->vrf_id = ntohl (vrf_id);
5774   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5775   mp->is_add = is_add;
5776   mp->nlabels = vec_len (labels);
5777   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
5778
5779   vec_free (labels);
5780
5781   S;
5782   W;
5783   /* NOTREACHED */
5784   return 0;
5785 }
5786
5787 static int
5788 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
5789 {
5790   unformat_input_t *i = vam->input;
5791   vl_api_mpls_gre_add_del_tunnel_t *mp;
5792   f64 timeout;
5793   u32 inner_vrf_id = 0;
5794   u32 outer_vrf_id = 0;
5795   ip4_address_t src_address;
5796   ip4_address_t dst_address;
5797   ip4_address_t intfc_address;
5798   u32 tmp;
5799   u8 intfc_address_length = 0;
5800   u8 is_add = 1;
5801   u8 l2_only = 0;
5802
5803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5804     {
5805       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5806         ;
5807       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5808         ;
5809       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
5810         ;
5811       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5812         ;
5813       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5814                          &intfc_address, &tmp))
5815         intfc_address_length = tmp;
5816       else if (unformat (i, "l2-only"))
5817         l2_only = 1;
5818       else if (unformat (i, "del"))
5819         is_add = 0;
5820       else
5821         {
5822           clib_warning ("parse error '%U'", format_unformat_error, i);
5823           return -99;
5824         }
5825     }
5826
5827   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
5828
5829   mp->inner_vrf_id = ntohl (inner_vrf_id);
5830   mp->outer_vrf_id = ntohl (outer_vrf_id);
5831   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
5832   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5833   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
5834   mp->intfc_address_length = intfc_address_length;
5835   mp->l2_only = l2_only;
5836   mp->is_add = is_add;
5837
5838   S;
5839   W;
5840   /* NOTREACHED */
5841   return 0;
5842 }
5843
5844 static int
5845 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
5846 {
5847   unformat_input_t *i = vam->input;
5848   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
5849   f64 timeout;
5850   u32 inner_vrf_id = 0;
5851   ip4_address_t intfc_address;
5852   u8 dst_mac_address[6];
5853   int dst_set = 1;
5854   u32 tmp;
5855   u8 intfc_address_length = 0;
5856   u8 is_add = 1;
5857   u8 l2_only = 0;
5858   u32 tx_sw_if_index;
5859   int tx_sw_if_index_set = 0;
5860
5861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5862     {
5863       if (unformat (i, "vrf %d", &inner_vrf_id))
5864         ;
5865       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5866                          &intfc_address, &tmp))
5867         intfc_address_length = tmp;
5868       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
5869         tx_sw_if_index_set = 1;
5870       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5871         tx_sw_if_index_set = 1;
5872       else if (unformat (i, "dst %U", unformat_ethernet_address,
5873                          dst_mac_address))
5874         dst_set = 1;
5875       else if (unformat (i, "l2-only"))
5876         l2_only = 1;
5877       else if (unformat (i, "del"))
5878         is_add = 0;
5879       else
5880         {
5881           clib_warning ("parse error '%U'", format_unformat_error, i);
5882           return -99;
5883         }
5884     }
5885
5886   if (!dst_set)
5887     {
5888       errmsg ("dst (mac address) not set\n");
5889       return -99;
5890     }
5891   if (!tx_sw_if_index_set)
5892     {
5893       errmsg ("tx-intfc not set\n");
5894       return -99;
5895     }
5896
5897   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
5898
5899   mp->vrf_id = ntohl (inner_vrf_id);
5900   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
5901   mp->adj_address_length = intfc_address_length;
5902   clib_memcpy (mp->dst_mac_address, dst_mac_address,
5903                sizeof (dst_mac_address));
5904   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5905   mp->l2_only = l2_only;
5906   mp->is_add = is_add;
5907
5908   S;
5909   W;
5910   /* NOTREACHED */
5911   return 0;
5912 }
5913
5914 static int
5915 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
5916 {
5917   unformat_input_t *i = vam->input;
5918   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
5919   f64 timeout;
5920   u32 inner_vrf_id = 0;
5921   u32 outer_vrf_id = 0;
5922   ip4_address_t adj_address;
5923   int adj_address_set = 0;
5924   ip4_address_t next_hop_address;
5925   int next_hop_address_set = 0;
5926   u32 tmp;
5927   u8 adj_address_length = 0;
5928   u8 l2_only = 0;
5929   u8 is_add = 1;
5930   u32 resolve_attempts = 5;
5931   u8 resolve_if_needed = 1;
5932
5933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5934     {
5935       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5936         ;
5937       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5938         ;
5939       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5940                          &adj_address, &tmp))
5941         {
5942           adj_address_length = tmp;
5943           adj_address_set = 1;
5944         }
5945       else if (unformat (i, "next-hop %U", unformat_ip4_address,
5946                          &next_hop_address))
5947         next_hop_address_set = 1;
5948       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5949         ;
5950       else if (unformat (i, "resolve-if-needed %d", &tmp))
5951         resolve_if_needed = tmp;
5952       else if (unformat (i, "l2-only"))
5953         l2_only = 1;
5954       else if (unformat (i, "del"))
5955         is_add = 0;
5956       else
5957         {
5958           clib_warning ("parse error '%U'", format_unformat_error, i);
5959           return -99;
5960         }
5961     }
5962
5963   if (!adj_address_set)
5964     {
5965       errmsg ("adjacency address/mask not set\n");
5966       return -99;
5967     }
5968   if (!next_hop_address_set)
5969     {
5970       errmsg ("ip4 next hop address (in outer fib) not set\n");
5971       return -99;
5972     }
5973
5974   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
5975
5976   mp->inner_vrf_id = ntohl (inner_vrf_id);
5977   mp->outer_vrf_id = ntohl (outer_vrf_id);
5978   mp->resolve_attempts = ntohl (resolve_attempts);
5979   mp->resolve_if_needed = resolve_if_needed;
5980   mp->is_add = is_add;
5981   mp->l2_only = l2_only;
5982   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
5983   mp->adj_address_length = adj_address_length;
5984   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
5985                sizeof (next_hop_address));
5986
5987   S;
5988   W;
5989   /* NOTREACHED */
5990   return 0;
5991 }
5992
5993 static int
5994 api_sw_interface_set_unnumbered (vat_main_t * vam)
5995 {
5996   unformat_input_t *i = vam->input;
5997   vl_api_sw_interface_set_unnumbered_t *mp;
5998   f64 timeout;
5999   u32 sw_if_index;
6000   u32 unnum_sw_index = ~0;
6001   u8 is_add = 1;
6002   u8 sw_if_index_set = 0;
6003
6004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6005     {
6006       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6007         sw_if_index_set = 1;
6008       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6009         sw_if_index_set = 1;
6010       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6011         ;
6012       else if (unformat (i, "del"))
6013         is_add = 0;
6014       else
6015         {
6016           clib_warning ("parse error '%U'", format_unformat_error, i);
6017           return -99;
6018         }
6019     }
6020
6021   if (sw_if_index_set == 0)
6022     {
6023       errmsg ("missing interface name or sw_if_index\n");
6024       return -99;
6025     }
6026
6027   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6028
6029   mp->sw_if_index = ntohl (sw_if_index);
6030   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6031   mp->is_add = is_add;
6032
6033   S;
6034   W;
6035   /* NOTREACHED */
6036   return 0;
6037 }
6038
6039 static int
6040 api_ip_neighbor_add_del (vat_main_t * vam)
6041 {
6042   unformat_input_t *i = vam->input;
6043   vl_api_ip_neighbor_add_del_t *mp;
6044   f64 timeout;
6045   u32 sw_if_index;
6046   u8 sw_if_index_set = 0;
6047   u32 vrf_id = 0;
6048   u8 is_add = 1;
6049   u8 is_static = 0;
6050   u8 mac_address[6];
6051   u8 mac_set = 0;
6052   u8 v4_address_set = 0;
6053   u8 v6_address_set = 0;
6054   ip4_address_t v4address;
6055   ip6_address_t v6address;
6056
6057   memset (mac_address, 0, sizeof (mac_address));
6058
6059   /* Parse args required to build the message */
6060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6061     {
6062       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6063         {
6064           mac_set = 1;
6065         }
6066       else if (unformat (i, "del"))
6067         is_add = 0;
6068       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6069         sw_if_index_set = 1;
6070       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6071         sw_if_index_set = 1;
6072       else if (unformat (i, "is_static"))
6073         is_static = 1;
6074       else if (unformat (i, "vrf %d", &vrf_id))
6075         ;
6076       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6077         v4_address_set = 1;
6078       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6079         v6_address_set = 1;
6080       else
6081         {
6082           clib_warning ("parse error '%U'", format_unformat_error, i);
6083           return -99;
6084         }
6085     }
6086
6087   if (sw_if_index_set == 0)
6088     {
6089       errmsg ("missing interface name or sw_if_index\n");
6090       return -99;
6091     }
6092   if (v4_address_set && v6_address_set)
6093     {
6094       errmsg ("both v4 and v6 addresses set\n");
6095       return -99;
6096     }
6097   if (!v4_address_set && !v6_address_set)
6098     {
6099       errmsg ("no address set\n");
6100       return -99;
6101     }
6102
6103   /* Construct the API message */
6104   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6105
6106   mp->sw_if_index = ntohl (sw_if_index);
6107   mp->is_add = is_add;
6108   mp->vrf_id = ntohl (vrf_id);
6109   mp->is_static = is_static;
6110   if (mac_set)
6111     clib_memcpy (mp->mac_address, mac_address, 6);
6112   if (v6_address_set)
6113     {
6114       mp->is_ipv6 = 1;
6115       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6116     }
6117   else
6118     {
6119       /* mp->is_ipv6 = 0; via memset in M macro above */
6120       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6121     }
6122
6123   /* send it... */
6124   S;
6125
6126   /* Wait for a reply, return good/bad news  */
6127   W;
6128
6129   /* NOTREACHED */
6130   return 0;
6131 }
6132
6133 static int
6134 api_reset_vrf (vat_main_t * vam)
6135 {
6136   unformat_input_t *i = vam->input;
6137   vl_api_reset_vrf_t *mp;
6138   f64 timeout;
6139   u32 vrf_id = 0;
6140   u8 is_ipv6 = 0;
6141   u8 vrf_id_set = 0;
6142
6143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6144     {
6145       if (unformat (i, "vrf %d", &vrf_id))
6146         vrf_id_set = 1;
6147       else if (unformat (i, "ipv6"))
6148         is_ipv6 = 1;
6149       else
6150         {
6151           clib_warning ("parse error '%U'", format_unformat_error, i);
6152           return -99;
6153         }
6154     }
6155
6156   if (vrf_id_set == 0)
6157     {
6158       errmsg ("missing vrf id\n");
6159       return -99;
6160     }
6161
6162   M (RESET_VRF, reset_vrf);
6163
6164   mp->vrf_id = ntohl (vrf_id);
6165   mp->is_ipv6 = is_ipv6;
6166
6167   S;
6168   W;
6169   /* NOTREACHED */
6170   return 0;
6171 }
6172
6173 static int
6174 api_create_vlan_subif (vat_main_t * vam)
6175 {
6176   unformat_input_t *i = vam->input;
6177   vl_api_create_vlan_subif_t *mp;
6178   f64 timeout;
6179   u32 sw_if_index;
6180   u8 sw_if_index_set = 0;
6181   u32 vlan_id;
6182   u8 vlan_id_set = 0;
6183
6184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6185     {
6186       if (unformat (i, "sw_if_index %d", &sw_if_index))
6187         sw_if_index_set = 1;
6188       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6189         sw_if_index_set = 1;
6190       else if (unformat (i, "vlan %d", &vlan_id))
6191         vlan_id_set = 1;
6192       else
6193         {
6194           clib_warning ("parse error '%U'", format_unformat_error, i);
6195           return -99;
6196         }
6197     }
6198
6199   if (sw_if_index_set == 0)
6200     {
6201       errmsg ("missing interface name or sw_if_index\n");
6202       return -99;
6203     }
6204
6205   if (vlan_id_set == 0)
6206     {
6207       errmsg ("missing vlan_id\n");
6208       return -99;
6209     }
6210   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6211
6212   mp->sw_if_index = ntohl (sw_if_index);
6213   mp->vlan_id = ntohl (vlan_id);
6214
6215   S;
6216   W;
6217   /* NOTREACHED */
6218   return 0;
6219 }
6220
6221 #define foreach_create_subif_bit                \
6222 _(no_tags)                                      \
6223 _(one_tag)                                      \
6224 _(two_tags)                                     \
6225 _(dot1ad)                                       \
6226 _(exact_match)                                  \
6227 _(default_sub)                                  \
6228 _(outer_vlan_id_any)                            \
6229 _(inner_vlan_id_any)
6230
6231 static int
6232 api_create_subif (vat_main_t * vam)
6233 {
6234   unformat_input_t *i = vam->input;
6235   vl_api_create_subif_t *mp;
6236   f64 timeout;
6237   u32 sw_if_index;
6238   u8 sw_if_index_set = 0;
6239   u32 sub_id;
6240   u8 sub_id_set = 0;
6241   u32 no_tags = 0;
6242   u32 one_tag = 0;
6243   u32 two_tags = 0;
6244   u32 dot1ad = 0;
6245   u32 exact_match = 0;
6246   u32 default_sub = 0;
6247   u32 outer_vlan_id_any = 0;
6248   u32 inner_vlan_id_any = 0;
6249   u32 tmp;
6250   u16 outer_vlan_id = 0;
6251   u16 inner_vlan_id = 0;
6252
6253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6254     {
6255       if (unformat (i, "sw_if_index %d", &sw_if_index))
6256         sw_if_index_set = 1;
6257       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6258         sw_if_index_set = 1;
6259       else if (unformat (i, "sub_id %d", &sub_id))
6260         sub_id_set = 1;
6261       else if (unformat (i, "outer_vlan_id %d", &tmp))
6262         outer_vlan_id = tmp;
6263       else if (unformat (i, "inner_vlan_id %d", &tmp))
6264         inner_vlan_id = tmp;
6265
6266 #define _(a) else if (unformat (i, #a)) a = 1 ;
6267       foreach_create_subif_bit
6268 #undef _
6269         else
6270         {
6271           clib_warning ("parse error '%U'", format_unformat_error, i);
6272           return -99;
6273         }
6274     }
6275
6276   if (sw_if_index_set == 0)
6277     {
6278       errmsg ("missing interface name or sw_if_index\n");
6279       return -99;
6280     }
6281
6282   if (sub_id_set == 0)
6283     {
6284       errmsg ("missing sub_id\n");
6285       return -99;
6286     }
6287   M (CREATE_SUBIF, create_subif);
6288
6289   mp->sw_if_index = ntohl (sw_if_index);
6290   mp->sub_id = ntohl (sub_id);
6291
6292 #define _(a) mp->a = a;
6293   foreach_create_subif_bit;
6294 #undef _
6295
6296   mp->outer_vlan_id = ntohs (outer_vlan_id);
6297   mp->inner_vlan_id = ntohs (inner_vlan_id);
6298
6299   S;
6300   W;
6301   /* NOTREACHED */
6302   return 0;
6303 }
6304
6305 static int
6306 api_oam_add_del (vat_main_t * vam)
6307 {
6308   unformat_input_t *i = vam->input;
6309   vl_api_oam_add_del_t *mp;
6310   f64 timeout;
6311   u32 vrf_id = 0;
6312   u8 is_add = 1;
6313   ip4_address_t src, dst;
6314   u8 src_set = 0;
6315   u8 dst_set = 0;
6316
6317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6318     {
6319       if (unformat (i, "vrf %d", &vrf_id))
6320         ;
6321       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6322         src_set = 1;
6323       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6324         dst_set = 1;
6325       else if (unformat (i, "del"))
6326         is_add = 0;
6327       else
6328         {
6329           clib_warning ("parse error '%U'", format_unformat_error, i);
6330           return -99;
6331         }
6332     }
6333
6334   if (src_set == 0)
6335     {
6336       errmsg ("missing src addr\n");
6337       return -99;
6338     }
6339
6340   if (dst_set == 0)
6341     {
6342       errmsg ("missing dst addr\n");
6343       return -99;
6344     }
6345
6346   M (OAM_ADD_DEL, oam_add_del);
6347
6348   mp->vrf_id = ntohl (vrf_id);
6349   mp->is_add = is_add;
6350   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6351   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6352
6353   S;
6354   W;
6355   /* NOTREACHED */
6356   return 0;
6357 }
6358
6359 static int
6360 api_reset_fib (vat_main_t * vam)
6361 {
6362   unformat_input_t *i = vam->input;
6363   vl_api_reset_fib_t *mp;
6364   f64 timeout;
6365   u32 vrf_id = 0;
6366   u8 is_ipv6 = 0;
6367   u8 vrf_id_set = 0;
6368
6369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6370     {
6371       if (unformat (i, "vrf %d", &vrf_id))
6372         vrf_id_set = 1;
6373       else if (unformat (i, "ipv6"))
6374         is_ipv6 = 1;
6375       else
6376         {
6377           clib_warning ("parse error '%U'", format_unformat_error, i);
6378           return -99;
6379         }
6380     }
6381
6382   if (vrf_id_set == 0)
6383     {
6384       errmsg ("missing vrf id\n");
6385       return -99;
6386     }
6387
6388   M (RESET_FIB, reset_fib);
6389
6390   mp->vrf_id = ntohl (vrf_id);
6391   mp->is_ipv6 = is_ipv6;
6392
6393   S;
6394   W;
6395   /* NOTREACHED */
6396   return 0;
6397 }
6398
6399 static int
6400 api_dhcp_proxy_config (vat_main_t * vam)
6401 {
6402   unformat_input_t *i = vam->input;
6403   vl_api_dhcp_proxy_config_t *mp;
6404   f64 timeout;
6405   u32 vrf_id = 0;
6406   u8 is_add = 1;
6407   u8 insert_cid = 1;
6408   u8 v4_address_set = 0;
6409   u8 v6_address_set = 0;
6410   ip4_address_t v4address;
6411   ip6_address_t v6address;
6412   u8 v4_src_address_set = 0;
6413   u8 v6_src_address_set = 0;
6414   ip4_address_t v4srcaddress;
6415   ip6_address_t v6srcaddress;
6416
6417   /* Parse args required to build the message */
6418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6419     {
6420       if (unformat (i, "del"))
6421         is_add = 0;
6422       else if (unformat (i, "vrf %d", &vrf_id))
6423         ;
6424       else if (unformat (i, "insert-cid %d", &insert_cid))
6425         ;
6426       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6427         v4_address_set = 1;
6428       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6429         v6_address_set = 1;
6430       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6431         v4_src_address_set = 1;
6432       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6433         v6_src_address_set = 1;
6434       else
6435         break;
6436     }
6437
6438   if (v4_address_set && v6_address_set)
6439     {
6440       errmsg ("both v4 and v6 server addresses set\n");
6441       return -99;
6442     }
6443   if (!v4_address_set && !v6_address_set)
6444     {
6445       errmsg ("no server addresses set\n");
6446       return -99;
6447     }
6448
6449   if (v4_src_address_set && v6_src_address_set)
6450     {
6451       errmsg ("both v4 and v6  src addresses set\n");
6452       return -99;
6453     }
6454   if (!v4_src_address_set && !v6_src_address_set)
6455     {
6456       errmsg ("no src addresses set\n");
6457       return -99;
6458     }
6459
6460   if (!(v4_src_address_set && v4_address_set) &&
6461       !(v6_src_address_set && v6_address_set))
6462     {
6463       errmsg ("no matching server and src addresses set\n");
6464       return -99;
6465     }
6466
6467   /* Construct the API message */
6468   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6469
6470   mp->insert_circuit_id = insert_cid;
6471   mp->is_add = is_add;
6472   mp->vrf_id = ntohl (vrf_id);
6473   if (v6_address_set)
6474     {
6475       mp->is_ipv6 = 1;
6476       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6477       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6478     }
6479   else
6480     {
6481       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6482       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6483     }
6484
6485   /* send it... */
6486   S;
6487
6488   /* Wait for a reply, return good/bad news  */
6489   W;
6490   /* NOTREACHED */
6491   return 0;
6492 }
6493
6494 static int
6495 api_dhcp_proxy_config_2 (vat_main_t * vam)
6496 {
6497   unformat_input_t *i = vam->input;
6498   vl_api_dhcp_proxy_config_2_t *mp;
6499   f64 timeout;
6500   u32 rx_vrf_id = 0;
6501   u32 server_vrf_id = 0;
6502   u8 is_add = 1;
6503   u8 insert_cid = 1;
6504   u8 v4_address_set = 0;
6505   u8 v6_address_set = 0;
6506   ip4_address_t v4address;
6507   ip6_address_t v6address;
6508   u8 v4_src_address_set = 0;
6509   u8 v6_src_address_set = 0;
6510   ip4_address_t v4srcaddress;
6511   ip6_address_t v6srcaddress;
6512
6513   /* Parse args required to build the message */
6514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6515     {
6516       if (unformat (i, "del"))
6517         is_add = 0;
6518       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6519         ;
6520       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6521         ;
6522       else if (unformat (i, "insert-cid %d", &insert_cid))
6523         ;
6524       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6525         v4_address_set = 1;
6526       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6527         v6_address_set = 1;
6528       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6529         v4_src_address_set = 1;
6530       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6531         v6_src_address_set = 1;
6532       else
6533         break;
6534     }
6535
6536   if (v4_address_set && v6_address_set)
6537     {
6538       errmsg ("both v4 and v6 server addresses set\n");
6539       return -99;
6540     }
6541   if (!v4_address_set && !v6_address_set)
6542     {
6543       errmsg ("no server addresses set\n");
6544       return -99;
6545     }
6546
6547   if (v4_src_address_set && v6_src_address_set)
6548     {
6549       errmsg ("both v4 and v6  src addresses set\n");
6550       return -99;
6551     }
6552   if (!v4_src_address_set && !v6_src_address_set)
6553     {
6554       errmsg ("no src addresses set\n");
6555       return -99;
6556     }
6557
6558   if (!(v4_src_address_set && v4_address_set) &&
6559       !(v6_src_address_set && v6_address_set))
6560     {
6561       errmsg ("no matching server and src addresses set\n");
6562       return -99;
6563     }
6564
6565   /* Construct the API message */
6566   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6567
6568   mp->insert_circuit_id = insert_cid;
6569   mp->is_add = is_add;
6570   mp->rx_vrf_id = ntohl (rx_vrf_id);
6571   mp->server_vrf_id = ntohl (server_vrf_id);
6572   if (v6_address_set)
6573     {
6574       mp->is_ipv6 = 1;
6575       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6576       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6577     }
6578   else
6579     {
6580       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6581       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6582     }
6583
6584   /* send it... */
6585   S;
6586
6587   /* Wait for a reply, return good/bad news  */
6588   W;
6589   /* NOTREACHED */
6590   return 0;
6591 }
6592
6593 static int
6594 api_dhcp_proxy_set_vss (vat_main_t * vam)
6595 {
6596   unformat_input_t *i = vam->input;
6597   vl_api_dhcp_proxy_set_vss_t *mp;
6598   f64 timeout;
6599   u8 is_ipv6 = 0;
6600   u8 is_add = 1;
6601   u32 tbl_id;
6602   u8 tbl_id_set = 0;
6603   u32 oui;
6604   u8 oui_set = 0;
6605   u32 fib_id;
6606   u8 fib_id_set = 0;
6607
6608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6609     {
6610       if (unformat (i, "tbl_id %d", &tbl_id))
6611         tbl_id_set = 1;
6612       if (unformat (i, "fib_id %d", &fib_id))
6613         fib_id_set = 1;
6614       if (unformat (i, "oui %d", &oui))
6615         oui_set = 1;
6616       else if (unformat (i, "ipv6"))
6617         is_ipv6 = 1;
6618       else if (unformat (i, "del"))
6619         is_add = 0;
6620       else
6621         {
6622           clib_warning ("parse error '%U'", format_unformat_error, i);
6623           return -99;
6624         }
6625     }
6626
6627   if (tbl_id_set == 0)
6628     {
6629       errmsg ("missing tbl id\n");
6630       return -99;
6631     }
6632
6633   if (fib_id_set == 0)
6634     {
6635       errmsg ("missing fib id\n");
6636       return -99;
6637     }
6638   if (oui_set == 0)
6639     {
6640       errmsg ("missing oui\n");
6641       return -99;
6642     }
6643
6644   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6645   mp->tbl_id = ntohl (tbl_id);
6646   mp->fib_id = ntohl (fib_id);
6647   mp->oui = ntohl (oui);
6648   mp->is_ipv6 = is_ipv6;
6649   mp->is_add = is_add;
6650
6651   S;
6652   W;
6653   /* NOTREACHED */
6654   return 0;
6655 }
6656
6657 static int
6658 api_dhcp_client_config (vat_main_t * vam)
6659 {
6660   unformat_input_t *i = vam->input;
6661   vl_api_dhcp_client_config_t *mp;
6662   f64 timeout;
6663   u32 sw_if_index;
6664   u8 sw_if_index_set = 0;
6665   u8 is_add = 1;
6666   u8 *hostname = 0;
6667   u8 disable_event = 0;
6668
6669   /* Parse args required to build the message */
6670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6671     {
6672       if (unformat (i, "del"))
6673         is_add = 0;
6674       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6675         sw_if_index_set = 1;
6676       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6677         sw_if_index_set = 1;
6678       else if (unformat (i, "hostname %s", &hostname))
6679         ;
6680       else if (unformat (i, "disable_event"))
6681         disable_event = 1;
6682       else
6683         break;
6684     }
6685
6686   if (sw_if_index_set == 0)
6687     {
6688       errmsg ("missing interface name or sw_if_index\n");
6689       return -99;
6690     }
6691
6692   if (vec_len (hostname) > 63)
6693     {
6694       errmsg ("hostname too long\n");
6695     }
6696   vec_add1 (hostname, 0);
6697
6698   /* Construct the API message */
6699   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6700
6701   mp->sw_if_index = ntohl (sw_if_index);
6702   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6703   vec_free (hostname);
6704   mp->is_add = is_add;
6705   mp->want_dhcp_event = disable_event ? 0 : 1;
6706   mp->pid = getpid ();
6707
6708   /* send it... */
6709   S;
6710
6711   /* Wait for a reply, return good/bad news  */
6712   W;
6713   /* NOTREACHED */
6714   return 0;
6715 }
6716
6717 static int
6718 api_set_ip_flow_hash (vat_main_t * vam)
6719 {
6720   unformat_input_t *i = vam->input;
6721   vl_api_set_ip_flow_hash_t *mp;
6722   f64 timeout;
6723   u32 vrf_id = 0;
6724   u8 is_ipv6 = 0;
6725   u8 vrf_id_set = 0;
6726   u8 src = 0;
6727   u8 dst = 0;
6728   u8 sport = 0;
6729   u8 dport = 0;
6730   u8 proto = 0;
6731   u8 reverse = 0;
6732
6733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6734     {
6735       if (unformat (i, "vrf %d", &vrf_id))
6736         vrf_id_set = 1;
6737       else if (unformat (i, "ipv6"))
6738         is_ipv6 = 1;
6739       else if (unformat (i, "src"))
6740         src = 1;
6741       else if (unformat (i, "dst"))
6742         dst = 1;
6743       else if (unformat (i, "sport"))
6744         sport = 1;
6745       else if (unformat (i, "dport"))
6746         dport = 1;
6747       else if (unformat (i, "proto"))
6748         proto = 1;
6749       else if (unformat (i, "reverse"))
6750         reverse = 1;
6751
6752       else
6753         {
6754           clib_warning ("parse error '%U'", format_unformat_error, i);
6755           return -99;
6756         }
6757     }
6758
6759   if (vrf_id_set == 0)
6760     {
6761       errmsg ("missing vrf id\n");
6762       return -99;
6763     }
6764
6765   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
6766   mp->src = src;
6767   mp->dst = dst;
6768   mp->sport = sport;
6769   mp->dport = dport;
6770   mp->proto = proto;
6771   mp->reverse = reverse;
6772   mp->vrf_id = ntohl (vrf_id);
6773   mp->is_ipv6 = is_ipv6;
6774
6775   S;
6776   W;
6777   /* NOTREACHED */
6778   return 0;
6779 }
6780
6781 static int
6782 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
6783 {
6784   unformat_input_t *i = vam->input;
6785   vl_api_sw_interface_ip6_enable_disable_t *mp;
6786   f64 timeout;
6787   u32 sw_if_index;
6788   u8 sw_if_index_set = 0;
6789   u8 enable = 0;
6790
6791   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6792     {
6793       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6794         sw_if_index_set = 1;
6795       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6796         sw_if_index_set = 1;
6797       else if (unformat (i, "enable"))
6798         enable = 1;
6799       else if (unformat (i, "disable"))
6800         enable = 0;
6801       else
6802         {
6803           clib_warning ("parse error '%U'", format_unformat_error, i);
6804           return -99;
6805         }
6806     }
6807
6808   if (sw_if_index_set == 0)
6809     {
6810       errmsg ("missing interface name or sw_if_index\n");
6811       return -99;
6812     }
6813
6814   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
6815
6816   mp->sw_if_index = ntohl (sw_if_index);
6817   mp->enable = enable;
6818
6819   S;
6820   W;
6821   /* NOTREACHED */
6822   return 0;
6823 }
6824
6825 static int
6826 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
6827 {
6828   unformat_input_t *i = vam->input;
6829   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
6830   f64 timeout;
6831   u32 sw_if_index;
6832   u8 sw_if_index_set = 0;
6833   u32 address_length = 0;
6834   u8 v6_address_set = 0;
6835   ip6_address_t v6address;
6836
6837   /* Parse args required to build the message */
6838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6839     {
6840       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6841         sw_if_index_set = 1;
6842       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6843         sw_if_index_set = 1;
6844       else if (unformat (i, "%U/%d",
6845                          unformat_ip6_address, &v6address, &address_length))
6846         v6_address_set = 1;
6847       else
6848         break;
6849     }
6850
6851   if (sw_if_index_set == 0)
6852     {
6853       errmsg ("missing interface name or sw_if_index\n");
6854       return -99;
6855     }
6856   if (!v6_address_set)
6857     {
6858       errmsg ("no address set\n");
6859       return -99;
6860     }
6861
6862   /* Construct the API message */
6863   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
6864      sw_interface_ip6_set_link_local_address);
6865
6866   mp->sw_if_index = ntohl (sw_if_index);
6867   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6868   mp->address_length = address_length;
6869
6870   /* send it... */
6871   S;
6872
6873   /* Wait for a reply, return good/bad news  */
6874   W;
6875
6876   /* NOTREACHED */
6877   return 0;
6878 }
6879
6880
6881 static int
6882 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
6883 {
6884   unformat_input_t *i = vam->input;
6885   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
6886   f64 timeout;
6887   u32 sw_if_index;
6888   u8 sw_if_index_set = 0;
6889   u32 address_length = 0;
6890   u8 v6_address_set = 0;
6891   ip6_address_t v6address;
6892   u8 use_default = 0;
6893   u8 no_advertise = 0;
6894   u8 off_link = 0;
6895   u8 no_autoconfig = 0;
6896   u8 no_onlink = 0;
6897   u8 is_no = 0;
6898   u32 val_lifetime = 0;
6899   u32 pref_lifetime = 0;
6900
6901   /* Parse args required to build the message */
6902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6903     {
6904       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6905         sw_if_index_set = 1;
6906       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6907         sw_if_index_set = 1;
6908       else if (unformat (i, "%U/%d",
6909                          unformat_ip6_address, &v6address, &address_length))
6910         v6_address_set = 1;
6911       else if (unformat (i, "val_life %d", &val_lifetime))
6912         ;
6913       else if (unformat (i, "pref_life %d", &pref_lifetime))
6914         ;
6915       else if (unformat (i, "def"))
6916         use_default = 1;
6917       else if (unformat (i, "noadv"))
6918         no_advertise = 1;
6919       else if (unformat (i, "offl"))
6920         off_link = 1;
6921       else if (unformat (i, "noauto"))
6922         no_autoconfig = 1;
6923       else if (unformat (i, "nolink"))
6924         no_onlink = 1;
6925       else if (unformat (i, "isno"))
6926         is_no = 1;
6927       else
6928         {
6929           clib_warning ("parse error '%U'", format_unformat_error, i);
6930           return -99;
6931         }
6932     }
6933
6934   if (sw_if_index_set == 0)
6935     {
6936       errmsg ("missing interface name or sw_if_index\n");
6937       return -99;
6938     }
6939   if (!v6_address_set)
6940     {
6941       errmsg ("no address set\n");
6942       return -99;
6943     }
6944
6945   /* Construct the API message */
6946   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
6947
6948   mp->sw_if_index = ntohl (sw_if_index);
6949   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6950   mp->address_length = address_length;
6951   mp->use_default = use_default;
6952   mp->no_advertise = no_advertise;
6953   mp->off_link = off_link;
6954   mp->no_autoconfig = no_autoconfig;
6955   mp->no_onlink = no_onlink;
6956   mp->is_no = is_no;
6957   mp->val_lifetime = ntohl (val_lifetime);
6958   mp->pref_lifetime = ntohl (pref_lifetime);
6959
6960   /* send it... */
6961   S;
6962
6963   /* Wait for a reply, return good/bad news  */
6964   W;
6965
6966   /* NOTREACHED */
6967   return 0;
6968 }
6969
6970 static int
6971 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
6972 {
6973   unformat_input_t *i = vam->input;
6974   vl_api_sw_interface_ip6nd_ra_config_t *mp;
6975   f64 timeout;
6976   u32 sw_if_index;
6977   u8 sw_if_index_set = 0;
6978   u8 suppress = 0;
6979   u8 managed = 0;
6980   u8 other = 0;
6981   u8 ll_option = 0;
6982   u8 send_unicast = 0;
6983   u8 cease = 0;
6984   u8 is_no = 0;
6985   u8 default_router = 0;
6986   u32 max_interval = 0;
6987   u32 min_interval = 0;
6988   u32 lifetime = 0;
6989   u32 initial_count = 0;
6990   u32 initial_interval = 0;
6991
6992
6993   /* Parse args required to build the message */
6994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6995     {
6996       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6997         sw_if_index_set = 1;
6998       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6999         sw_if_index_set = 1;
7000       else if (unformat (i, "maxint %d", &max_interval))
7001         ;
7002       else if (unformat (i, "minint %d", &min_interval))
7003         ;
7004       else if (unformat (i, "life %d", &lifetime))
7005         ;
7006       else if (unformat (i, "count %d", &initial_count))
7007         ;
7008       else if (unformat (i, "interval %d", &initial_interval))
7009         ;
7010       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7011         suppress = 1;
7012       else if (unformat (i, "managed"))
7013         managed = 1;
7014       else if (unformat (i, "other"))
7015         other = 1;
7016       else if (unformat (i, "ll"))
7017         ll_option = 1;
7018       else if (unformat (i, "send"))
7019         send_unicast = 1;
7020       else if (unformat (i, "cease"))
7021         cease = 1;
7022       else if (unformat (i, "isno"))
7023         is_no = 1;
7024       else if (unformat (i, "def"))
7025         default_router = 1;
7026       else
7027         {
7028           clib_warning ("parse error '%U'", format_unformat_error, i);
7029           return -99;
7030         }
7031     }
7032
7033   if (sw_if_index_set == 0)
7034     {
7035       errmsg ("missing interface name or sw_if_index\n");
7036       return -99;
7037     }
7038
7039   /* Construct the API message */
7040   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7041
7042   mp->sw_if_index = ntohl (sw_if_index);
7043   mp->max_interval = ntohl (max_interval);
7044   mp->min_interval = ntohl (min_interval);
7045   mp->lifetime = ntohl (lifetime);
7046   mp->initial_count = ntohl (initial_count);
7047   mp->initial_interval = ntohl (initial_interval);
7048   mp->suppress = suppress;
7049   mp->managed = managed;
7050   mp->other = other;
7051   mp->ll_option = ll_option;
7052   mp->send_unicast = send_unicast;
7053   mp->cease = cease;
7054   mp->is_no = is_no;
7055   mp->default_router = default_router;
7056
7057   /* send it... */
7058   S;
7059
7060   /* Wait for a reply, return good/bad news  */
7061   W;
7062
7063   /* NOTREACHED */
7064   return 0;
7065 }
7066
7067 static int
7068 api_set_arp_neighbor_limit (vat_main_t * vam)
7069 {
7070   unformat_input_t *i = vam->input;
7071   vl_api_set_arp_neighbor_limit_t *mp;
7072   f64 timeout;
7073   u32 arp_nbr_limit;
7074   u8 limit_set = 0;
7075   u8 is_ipv6 = 0;
7076
7077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7078     {
7079       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7080         limit_set = 1;
7081       else if (unformat (i, "ipv6"))
7082         is_ipv6 = 1;
7083       else
7084         {
7085           clib_warning ("parse error '%U'", format_unformat_error, i);
7086           return -99;
7087         }
7088     }
7089
7090   if (limit_set == 0)
7091     {
7092       errmsg ("missing limit value\n");
7093       return -99;
7094     }
7095
7096   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7097
7098   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7099   mp->is_ipv6 = is_ipv6;
7100
7101   S;
7102   W;
7103   /* NOTREACHED */
7104   return 0;
7105 }
7106
7107 static int
7108 api_l2_patch_add_del (vat_main_t * vam)
7109 {
7110   unformat_input_t *i = vam->input;
7111   vl_api_l2_patch_add_del_t *mp;
7112   f64 timeout;
7113   u32 rx_sw_if_index;
7114   u8 rx_sw_if_index_set = 0;
7115   u32 tx_sw_if_index;
7116   u8 tx_sw_if_index_set = 0;
7117   u8 is_add = 1;
7118
7119   /* Parse args required to build the message */
7120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7121     {
7122       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7123         rx_sw_if_index_set = 1;
7124       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7125         tx_sw_if_index_set = 1;
7126       else if (unformat (i, "rx"))
7127         {
7128           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7129             {
7130               if (unformat (i, "%U", unformat_sw_if_index, vam,
7131                             &rx_sw_if_index))
7132                 rx_sw_if_index_set = 1;
7133             }
7134           else
7135             break;
7136         }
7137       else if (unformat (i, "tx"))
7138         {
7139           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7140             {
7141               if (unformat (i, "%U", unformat_sw_if_index, vam,
7142                             &tx_sw_if_index))
7143                 tx_sw_if_index_set = 1;
7144             }
7145           else
7146             break;
7147         }
7148       else if (unformat (i, "del"))
7149         is_add = 0;
7150       else
7151         break;
7152     }
7153
7154   if (rx_sw_if_index_set == 0)
7155     {
7156       errmsg ("missing rx interface name or rx_sw_if_index\n");
7157       return -99;
7158     }
7159
7160   if (tx_sw_if_index_set == 0)
7161     {
7162       errmsg ("missing tx interface name or tx_sw_if_index\n");
7163       return -99;
7164     }
7165
7166   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7167
7168   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7169   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7170   mp->is_add = is_add;
7171
7172   S;
7173   W;
7174   /* NOTREACHED */
7175   return 0;
7176 }
7177
7178 static int
7179 api_ioam_enable (vat_main_t * vam)
7180 {
7181   unformat_input_t *input = vam->input;
7182   vl_api_ioam_enable_t *mp;
7183   f64 timeout;
7184   u32 id = 0;
7185   int has_trace_option = 0;
7186   int has_pow_option = 0;
7187   int has_ppc_option = 0;
7188
7189   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7190     {
7191       if (unformat (input, "trace"))
7192         has_trace_option = 1;
7193       else if (unformat (input, "pow"))
7194         has_pow_option = 1;
7195       else if (unformat (input, "ppc encap"))
7196         has_ppc_option = PPC_ENCAP;
7197       else if (unformat (input, "ppc decap"))
7198         has_ppc_option = PPC_DECAP;
7199       else if (unformat (input, "ppc none"))
7200         has_ppc_option = PPC_NONE;
7201       else
7202         break;
7203     }
7204   M (IOAM_ENABLE, ioam_enable);
7205   mp->id = htons (id);
7206   mp->trace_ppc = has_ppc_option;
7207   mp->pow_enable = has_pow_option;
7208   mp->trace_enable = has_trace_option;
7209
7210   S;
7211   W;
7212
7213   return (0);
7214
7215 }
7216
7217
7218 static int
7219 api_ioam_disable (vat_main_t * vam)
7220 {
7221   vl_api_ioam_disable_t *mp;
7222   f64 timeout;
7223
7224   M (IOAM_DISABLE, ioam_disable);
7225   S;
7226   W;
7227   return 0;
7228 }
7229
7230 static int
7231 api_sr_tunnel_add_del (vat_main_t * vam)
7232 {
7233   unformat_input_t *i = vam->input;
7234   vl_api_sr_tunnel_add_del_t *mp;
7235   f64 timeout;
7236   int is_del = 0;
7237   int pl_index;
7238   ip6_address_t src_address;
7239   int src_address_set = 0;
7240   ip6_address_t dst_address;
7241   u32 dst_mask_width;
7242   int dst_address_set = 0;
7243   u16 flags = 0;
7244   u32 rx_table_id = 0;
7245   u32 tx_table_id = 0;
7246   ip6_address_t *segments = 0;
7247   ip6_address_t *this_seg;
7248   ip6_address_t *tags = 0;
7249   ip6_address_t *this_tag;
7250   ip6_address_t next_address, tag;
7251   u8 *name = 0;
7252   u8 *policy_name = 0;
7253
7254   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7255     {
7256       if (unformat (i, "del"))
7257         is_del = 1;
7258       else if (unformat (i, "name %s", &name))
7259         ;
7260       else if (unformat (i, "policy %s", &policy_name))
7261         ;
7262       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7263         ;
7264       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7265         ;
7266       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7267         src_address_set = 1;
7268       else if (unformat (i, "dst %U/%d",
7269                          unformat_ip6_address, &dst_address, &dst_mask_width))
7270         dst_address_set = 1;
7271       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7272         {
7273           vec_add2 (segments, this_seg, 1);
7274           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7275                        sizeof (*this_seg));
7276         }
7277       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7278         {
7279           vec_add2 (tags, this_tag, 1);
7280           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7281         }
7282       else if (unformat (i, "clean"))
7283         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7284       else if (unformat (i, "protected"))
7285         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7286       else if (unformat (i, "InPE %d", &pl_index))
7287         {
7288           if (pl_index <= 0 || pl_index > 4)
7289             {
7290             pl_index_range_error:
7291               errmsg ("pl index %d out of range\n", pl_index);
7292               return -99;
7293             }
7294           flags |=
7295             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7296         }
7297       else if (unformat (i, "EgPE %d", &pl_index))
7298         {
7299           if (pl_index <= 0 || pl_index > 4)
7300             goto pl_index_range_error;
7301           flags |=
7302             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7303         }
7304       else if (unformat (i, "OrgSrc %d", &pl_index))
7305         {
7306           if (pl_index <= 0 || pl_index > 4)
7307             goto pl_index_range_error;
7308           flags |=
7309             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7310         }
7311       else
7312         break;
7313     }
7314
7315   if (!src_address_set)
7316     {
7317       errmsg ("src address required\n");
7318       return -99;
7319     }
7320
7321   if (!dst_address_set)
7322     {
7323       errmsg ("dst address required\n");
7324       return -99;
7325     }
7326
7327   if (!segments)
7328     {
7329       errmsg ("at least one sr segment required\n");
7330       return -99;
7331     }
7332
7333   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7334       vec_len (segments) * sizeof (ip6_address_t)
7335       + vec_len (tags) * sizeof (ip6_address_t));
7336
7337   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7338   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7339   mp->dst_mask_width = dst_mask_width;
7340   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7341   mp->n_segments = vec_len (segments);
7342   mp->n_tags = vec_len (tags);
7343   mp->is_add = is_del == 0;
7344   clib_memcpy (mp->segs_and_tags, segments,
7345                vec_len (segments) * sizeof (ip6_address_t));
7346   clib_memcpy (mp->segs_and_tags +
7347                vec_len (segments) * sizeof (ip6_address_t), tags,
7348                vec_len (tags) * sizeof (ip6_address_t));
7349
7350   mp->outer_vrf_id = ntohl (rx_table_id);
7351   mp->inner_vrf_id = ntohl (tx_table_id);
7352   memcpy (mp->name, name, vec_len (name));
7353   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7354
7355   vec_free (segments);
7356   vec_free (tags);
7357
7358   S;
7359   W;
7360   /* NOTREACHED */
7361 }
7362
7363 static int
7364 api_sr_policy_add_del (vat_main_t * vam)
7365 {
7366   unformat_input_t *input = vam->input;
7367   vl_api_sr_policy_add_del_t *mp;
7368   f64 timeout;
7369   int is_del = 0;
7370   u8 *name = 0;
7371   u8 *tunnel_name = 0;
7372   u8 **tunnel_names = 0;
7373
7374   int name_set = 0;
7375   int tunnel_set = 0;
7376   int j = 0;
7377   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7378   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7379
7380   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7381     {
7382       if (unformat (input, "del"))
7383         is_del = 1;
7384       else if (unformat (input, "name %s", &name))
7385         name_set = 1;
7386       else if (unformat (input, "tunnel %s", &tunnel_name))
7387         {
7388           if (tunnel_name)
7389             {
7390               vec_add1 (tunnel_names, tunnel_name);
7391               /* For serializer:
7392                  - length = #bytes to store in serial vector
7393                  - +1 = byte to store that length
7394                */
7395               tunnel_names_length += (vec_len (tunnel_name) + 1);
7396               tunnel_set = 1;
7397               tunnel_name = 0;
7398             }
7399         }
7400       else
7401         break;
7402     }
7403
7404   if (!name_set)
7405     {
7406       errmsg ("policy name required\n");
7407       return -99;
7408     }
7409
7410   if ((!tunnel_set) && (!is_del))
7411     {
7412       errmsg ("tunnel name required\n");
7413       return -99;
7414     }
7415
7416   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7417
7418
7419
7420   mp->is_add = !is_del;
7421
7422   memcpy (mp->name, name, vec_len (name));
7423   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7424   u8 *serial_orig = 0;
7425   vec_validate (serial_orig, tunnel_names_length);
7426   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7427   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7428
7429   for (j = 0; j < vec_len (tunnel_names); j++)
7430     {
7431       tun_name_len = vec_len (tunnel_names[j]);
7432       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7433       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7434       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7435       serial_orig += tun_name_len;      // Advance past the copy
7436     }
7437   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7438
7439   vec_free (tunnel_names);
7440   vec_free (tunnel_name);
7441
7442   S;
7443   W;
7444   /* NOTREACHED */
7445 }
7446
7447 static int
7448 api_sr_multicast_map_add_del (vat_main_t * vam)
7449 {
7450   unformat_input_t *input = vam->input;
7451   vl_api_sr_multicast_map_add_del_t *mp;
7452   f64 timeout;
7453   int is_del = 0;
7454   ip6_address_t multicast_address;
7455   u8 *policy_name = 0;
7456   int multicast_address_set = 0;
7457
7458   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7459     {
7460       if (unformat (input, "del"))
7461         is_del = 1;
7462       else
7463         if (unformat
7464             (input, "address %U", unformat_ip6_address, &multicast_address))
7465         multicast_address_set = 1;
7466       else if (unformat (input, "sr-policy %s", &policy_name))
7467         ;
7468       else
7469         break;
7470     }
7471
7472   if (!is_del && !policy_name)
7473     {
7474       errmsg ("sr-policy name required\n");
7475       return -99;
7476     }
7477
7478
7479   if (!multicast_address_set)
7480     {
7481       errmsg ("address required\n");
7482       return -99;
7483     }
7484
7485   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7486
7487   mp->is_add = !is_del;
7488   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7489   clib_memcpy (mp->multicast_address, &multicast_address,
7490                sizeof (mp->multicast_address));
7491
7492
7493   vec_free (policy_name);
7494
7495   S;
7496   W;
7497   /* NOTREACHED */
7498 }
7499
7500
7501 #define foreach_ip4_proto_field                 \
7502 _(src_address)                                  \
7503 _(dst_address)                                  \
7504 _(tos)                                          \
7505 _(length)                                       \
7506 _(fragment_id)                                  \
7507 _(ttl)                                          \
7508 _(protocol)                                     \
7509 _(checksum)
7510
7511 uword
7512 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7513 {
7514   u8 **maskp = va_arg (*args, u8 **);
7515   u8 *mask = 0;
7516   u8 found_something = 0;
7517   ip4_header_t *ip;
7518
7519 #define _(a) u8 a=0;
7520   foreach_ip4_proto_field;
7521 #undef _
7522   u8 version = 0;
7523   u8 hdr_length = 0;
7524
7525
7526   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7527     {
7528       if (unformat (input, "version"))
7529         version = 1;
7530       else if (unformat (input, "hdr_length"))
7531         hdr_length = 1;
7532       else if (unformat (input, "src"))
7533         src_address = 1;
7534       else if (unformat (input, "dst"))
7535         dst_address = 1;
7536       else if (unformat (input, "proto"))
7537         protocol = 1;
7538
7539 #define _(a) else if (unformat (input, #a)) a=1;
7540       foreach_ip4_proto_field
7541 #undef _
7542         else
7543         break;
7544     }
7545
7546 #define _(a) found_something += a;
7547   foreach_ip4_proto_field;
7548 #undef _
7549
7550   if (found_something == 0)
7551     return 0;
7552
7553   vec_validate (mask, sizeof (*ip) - 1);
7554
7555   ip = (ip4_header_t *) mask;
7556
7557 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7558   foreach_ip4_proto_field;
7559 #undef _
7560
7561   ip->ip_version_and_header_length = 0;
7562
7563   if (version)
7564     ip->ip_version_and_header_length |= 0xF0;
7565
7566   if (hdr_length)
7567     ip->ip_version_and_header_length |= 0x0F;
7568
7569   *maskp = mask;
7570   return 1;
7571 }
7572
7573 #define foreach_ip6_proto_field                 \
7574 _(src_address)                                  \
7575 _(dst_address)                                  \
7576 _(payload_length)                               \
7577 _(hop_limit)                                    \
7578 _(protocol)
7579
7580 uword
7581 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7582 {
7583   u8 **maskp = va_arg (*args, u8 **);
7584   u8 *mask = 0;
7585   u8 found_something = 0;
7586   ip6_header_t *ip;
7587   u32 ip_version_traffic_class_and_flow_label;
7588
7589 #define _(a) u8 a=0;
7590   foreach_ip6_proto_field;
7591 #undef _
7592   u8 version = 0;
7593   u8 traffic_class = 0;
7594   u8 flow_label = 0;
7595
7596   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7597     {
7598       if (unformat (input, "version"))
7599         version = 1;
7600       else if (unformat (input, "traffic-class"))
7601         traffic_class = 1;
7602       else if (unformat (input, "flow-label"))
7603         flow_label = 1;
7604       else if (unformat (input, "src"))
7605         src_address = 1;
7606       else if (unformat (input, "dst"))
7607         dst_address = 1;
7608       else if (unformat (input, "proto"))
7609         protocol = 1;
7610
7611 #define _(a) else if (unformat (input, #a)) a=1;
7612       foreach_ip6_proto_field
7613 #undef _
7614         else
7615         break;
7616     }
7617
7618 #define _(a) found_something += a;
7619   foreach_ip6_proto_field;
7620 #undef _
7621
7622   if (found_something == 0)
7623     return 0;
7624
7625   vec_validate (mask, sizeof (*ip) - 1);
7626
7627   ip = (ip6_header_t *) mask;
7628
7629 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7630   foreach_ip6_proto_field;
7631 #undef _
7632
7633   ip_version_traffic_class_and_flow_label = 0;
7634
7635   if (version)
7636     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7637
7638   if (traffic_class)
7639     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7640
7641   if (flow_label)
7642     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7643
7644   ip->ip_version_traffic_class_and_flow_label =
7645     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7646
7647   *maskp = mask;
7648   return 1;
7649 }
7650
7651 uword
7652 unformat_l3_mask (unformat_input_t * input, va_list * args)
7653 {
7654   u8 **maskp = va_arg (*args, u8 **);
7655
7656   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7657     {
7658       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7659         return 1;
7660       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7661         return 1;
7662       else
7663         break;
7664     }
7665   return 0;
7666 }
7667
7668 uword
7669 unformat_l2_mask (unformat_input_t * input, va_list * args)
7670 {
7671   u8 **maskp = va_arg (*args, u8 **);
7672   u8 *mask = 0;
7673   u8 src = 0;
7674   u8 dst = 0;
7675   u8 proto = 0;
7676   u8 tag1 = 0;
7677   u8 tag2 = 0;
7678   u8 ignore_tag1 = 0;
7679   u8 ignore_tag2 = 0;
7680   u8 cos1 = 0;
7681   u8 cos2 = 0;
7682   u8 dot1q = 0;
7683   u8 dot1ad = 0;
7684   int len = 14;
7685
7686   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7687     {
7688       if (unformat (input, "src"))
7689         src = 1;
7690       else if (unformat (input, "dst"))
7691         dst = 1;
7692       else if (unformat (input, "proto"))
7693         proto = 1;
7694       else if (unformat (input, "tag1"))
7695         tag1 = 1;
7696       else if (unformat (input, "tag2"))
7697         tag2 = 1;
7698       else if (unformat (input, "ignore-tag1"))
7699         ignore_tag1 = 1;
7700       else if (unformat (input, "ignore-tag2"))
7701         ignore_tag2 = 1;
7702       else if (unformat (input, "cos1"))
7703         cos1 = 1;
7704       else if (unformat (input, "cos2"))
7705         cos2 = 1;
7706       else if (unformat (input, "dot1q"))
7707         dot1q = 1;
7708       else if (unformat (input, "dot1ad"))
7709         dot1ad = 1;
7710       else
7711         break;
7712     }
7713   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7714        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7715     return 0;
7716
7717   if (tag1 || ignore_tag1 || cos1 || dot1q)
7718     len = 18;
7719   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7720     len = 22;
7721
7722   vec_validate (mask, len - 1);
7723
7724   if (dst)
7725     memset (mask, 0xff, 6);
7726
7727   if (src)
7728     memset (mask + 6, 0xff, 6);
7729
7730   if (tag2 || dot1ad)
7731     {
7732       /* inner vlan tag */
7733       if (tag2)
7734         {
7735           mask[19] = 0xff;
7736           mask[18] = 0x0f;
7737         }
7738       if (cos2)
7739         mask[18] |= 0xe0;
7740       if (proto)
7741         mask[21] = mask[20] = 0xff;
7742       if (tag1)
7743         {
7744           mask[15] = 0xff;
7745           mask[14] = 0x0f;
7746         }
7747       if (cos1)
7748         mask[14] |= 0xe0;
7749       *maskp = mask;
7750       return 1;
7751     }
7752   if (tag1 | dot1q)
7753     {
7754       if (tag1)
7755         {
7756           mask[15] = 0xff;
7757           mask[14] = 0x0f;
7758         }
7759       if (cos1)
7760         mask[14] |= 0xe0;
7761       if (proto)
7762         mask[16] = mask[17] = 0xff;
7763
7764       *maskp = mask;
7765       return 1;
7766     }
7767   if (cos2)
7768     mask[18] |= 0xe0;
7769   if (cos1)
7770     mask[14] |= 0xe0;
7771   if (proto)
7772     mask[12] = mask[13] = 0xff;
7773
7774   *maskp = mask;
7775   return 1;
7776 }
7777
7778 uword
7779 unformat_classify_mask (unformat_input_t * input, va_list * args)
7780 {
7781   u8 **maskp = va_arg (*args, u8 **);
7782   u32 *skipp = va_arg (*args, u32 *);
7783   u32 *matchp = va_arg (*args, u32 *);
7784   u32 match;
7785   u8 *mask = 0;
7786   u8 *l2 = 0;
7787   u8 *l3 = 0;
7788   int i;
7789
7790   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7791     {
7792       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7793         ;
7794       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7795         ;
7796       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7797         ;
7798       else
7799         break;
7800     }
7801
7802   if (mask || l2 || l3)
7803     {
7804       if (l2 || l3)
7805         {
7806           /* "With a free Ethernet header in every package" */
7807           if (l2 == 0)
7808             vec_validate (l2, 13);
7809           mask = l2;
7810           if (vec_len (l3))
7811             {
7812               vec_append (mask, l3);
7813               vec_free (l3);
7814             }
7815         }
7816
7817       /* Scan forward looking for the first significant mask octet */
7818       for (i = 0; i < vec_len (mask); i++)
7819         if (mask[i])
7820           break;
7821
7822       /* compute (skip, match) params */
7823       *skipp = i / sizeof (u32x4);
7824       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7825
7826       /* Pad mask to an even multiple of the vector size */
7827       while (vec_len (mask) % sizeof (u32x4))
7828         vec_add1 (mask, 0);
7829
7830       match = vec_len (mask) / sizeof (u32x4);
7831
7832       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7833         {
7834           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7835           if (*tmp || *(tmp + 1))
7836             break;
7837           match--;
7838         }
7839       if (match == 0)
7840         clib_warning ("BUG: match 0");
7841
7842       _vec_len (mask) = match * sizeof (u32x4);
7843
7844       *matchp = match;
7845       *maskp = mask;
7846
7847       return 1;
7848     }
7849
7850   return 0;
7851 }
7852
7853 #define foreach_l2_next                         \
7854 _(drop, DROP)                                   \
7855 _(ethernet, ETHERNET_INPUT)                     \
7856 _(ip4, IP4_INPUT)                               \
7857 _(ip6, IP6_INPUT)
7858
7859 uword
7860 unformat_l2_next_index (unformat_input_t * input, va_list * args)
7861 {
7862   u32 *miss_next_indexp = va_arg (*args, u32 *);
7863   u32 next_index = 0;
7864   u32 tmp;
7865
7866 #define _(n,N) \
7867   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
7868   foreach_l2_next;
7869 #undef _
7870
7871   if (unformat (input, "%d", &tmp))
7872     {
7873       next_index = tmp;
7874       goto out;
7875     }
7876
7877   return 0;
7878
7879 out:
7880   *miss_next_indexp = next_index;
7881   return 1;
7882 }
7883
7884 #define foreach_ip_next                         \
7885 _(miss, MISS)                                   \
7886 _(drop, DROP)                                   \
7887 _(local, LOCAL)                                 \
7888 _(rewrite, REWRITE)
7889
7890 uword
7891 unformat_ip_next_index (unformat_input_t * input, va_list * args)
7892 {
7893   u32 *miss_next_indexp = va_arg (*args, u32 *);
7894   u32 next_index = 0;
7895   u32 tmp;
7896
7897 #define _(n,N) \
7898   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7899   foreach_ip_next;
7900 #undef _
7901
7902   if (unformat (input, "%d", &tmp))
7903     {
7904       next_index = tmp;
7905       goto out;
7906     }
7907
7908   return 0;
7909
7910 out:
7911   *miss_next_indexp = next_index;
7912   return 1;
7913 }
7914
7915 #define foreach_acl_next                        \
7916 _(deny, DENY)
7917
7918 uword
7919 unformat_acl_next_index (unformat_input_t * input, va_list * args)
7920 {
7921   u32 *miss_next_indexp = va_arg (*args, u32 *);
7922   u32 next_index = 0;
7923   u32 tmp;
7924
7925 #define _(n,N) \
7926   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7927   foreach_acl_next;
7928 #undef _
7929
7930   if (unformat (input, "permit"))
7931     {
7932       next_index = ~0;
7933       goto out;
7934     }
7935   else if (unformat (input, "%d", &tmp))
7936     {
7937       next_index = tmp;
7938       goto out;
7939     }
7940
7941   return 0;
7942
7943 out:
7944   *miss_next_indexp = next_index;
7945   return 1;
7946 }
7947
7948 uword
7949 unformat_policer_precolor (unformat_input_t * input, va_list * args)
7950 {
7951   u32 *r = va_arg (*args, u32 *);
7952
7953   if (unformat (input, "conform-color"))
7954     *r = POLICE_CONFORM;
7955   else if (unformat (input, "exceed-color"))
7956     *r = POLICE_EXCEED;
7957   else
7958     return 0;
7959
7960   return 1;
7961 }
7962
7963 static int
7964 api_classify_add_del_table (vat_main_t * vam)
7965 {
7966   unformat_input_t *i = vam->input;
7967   vl_api_classify_add_del_table_t *mp;
7968
7969   u32 nbuckets = 2;
7970   u32 skip = ~0;
7971   u32 match = ~0;
7972   int is_add = 1;
7973   u32 table_index = ~0;
7974   u32 next_table_index = ~0;
7975   u32 miss_next_index = ~0;
7976   u32 memory_size = 32 << 20;
7977   u8 *mask = 0;
7978   f64 timeout;
7979
7980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7981     {
7982       if (unformat (i, "del"))
7983         is_add = 0;
7984       else if (unformat (i, "buckets %d", &nbuckets))
7985         ;
7986       else if (unformat (i, "memory_size %d", &memory_size))
7987         ;
7988       else if (unformat (i, "skip %d", &skip))
7989         ;
7990       else if (unformat (i, "match %d", &match))
7991         ;
7992       else if (unformat (i, "table %d", &table_index))
7993         ;
7994       else if (unformat (i, "mask %U", unformat_classify_mask,
7995                          &mask, &skip, &match))
7996         ;
7997       else if (unformat (i, "next-table %d", &next_table_index))
7998         ;
7999       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8000                          &miss_next_index))
8001         ;
8002       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8003                          &miss_next_index))
8004         ;
8005       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8006                          &miss_next_index))
8007         ;
8008       else
8009         break;
8010     }
8011
8012   if (is_add && mask == 0)
8013     {
8014       errmsg ("Mask required\n");
8015       return -99;
8016     }
8017
8018   if (is_add && skip == ~0)
8019     {
8020       errmsg ("skip count required\n");
8021       return -99;
8022     }
8023
8024   if (is_add && match == ~0)
8025     {
8026       errmsg ("match count required\n");
8027       return -99;
8028     }
8029
8030   if (!is_add && table_index == ~0)
8031     {
8032       errmsg ("table index required for delete\n");
8033       return -99;
8034     }
8035
8036   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8037
8038   mp->is_add = is_add;
8039   mp->table_index = ntohl (table_index);
8040   mp->nbuckets = ntohl (nbuckets);
8041   mp->memory_size = ntohl (memory_size);
8042   mp->skip_n_vectors = ntohl (skip);
8043   mp->match_n_vectors = ntohl (match);
8044   mp->next_table_index = ntohl (next_table_index);
8045   mp->miss_next_index = ntohl (miss_next_index);
8046   clib_memcpy (mp->mask, mask, vec_len (mask));
8047
8048   vec_free (mask);
8049
8050   S;
8051   W;
8052   /* NOTREACHED */
8053 }
8054
8055 uword
8056 unformat_ip4_match (unformat_input_t * input, va_list * args)
8057 {
8058   u8 **matchp = va_arg (*args, u8 **);
8059   u8 *match = 0;
8060   ip4_header_t *ip;
8061   int version = 0;
8062   u32 version_val;
8063   int hdr_length = 0;
8064   u32 hdr_length_val;
8065   int src = 0, dst = 0;
8066   ip4_address_t src_val, dst_val;
8067   int proto = 0;
8068   u32 proto_val;
8069   int tos = 0;
8070   u32 tos_val;
8071   int length = 0;
8072   u32 length_val;
8073   int fragment_id = 0;
8074   u32 fragment_id_val;
8075   int ttl = 0;
8076   int ttl_val;
8077   int checksum = 0;
8078   u32 checksum_val;
8079
8080   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8081     {
8082       if (unformat (input, "version %d", &version_val))
8083         version = 1;
8084       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8085         hdr_length = 1;
8086       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8087         src = 1;
8088       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8089         dst = 1;
8090       else if (unformat (input, "proto %d", &proto_val))
8091         proto = 1;
8092       else if (unformat (input, "tos %d", &tos_val))
8093         tos = 1;
8094       else if (unformat (input, "length %d", &length_val))
8095         length = 1;
8096       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8097         fragment_id = 1;
8098       else if (unformat (input, "ttl %d", &ttl_val))
8099         ttl = 1;
8100       else if (unformat (input, "checksum %d", &checksum_val))
8101         checksum = 1;
8102       else
8103         break;
8104     }
8105
8106   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8107       + ttl + checksum == 0)
8108     return 0;
8109
8110   /*
8111    * Aligned because we use the real comparison functions
8112    */
8113   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8114
8115   ip = (ip4_header_t *) match;
8116
8117   /* These are realistically matched in practice */
8118   if (src)
8119     ip->src_address.as_u32 = src_val.as_u32;
8120
8121   if (dst)
8122     ip->dst_address.as_u32 = dst_val.as_u32;
8123
8124   if (proto)
8125     ip->protocol = proto_val;
8126
8127
8128   /* These are not, but they're included for completeness */
8129   if (version)
8130     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8131
8132   if (hdr_length)
8133     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8134
8135   if (tos)
8136     ip->tos = tos_val;
8137
8138   if (length)
8139     ip->length = length_val;
8140
8141   if (ttl)
8142     ip->ttl = ttl_val;
8143
8144   if (checksum)
8145     ip->checksum = checksum_val;
8146
8147   *matchp = match;
8148   return 1;
8149 }
8150
8151 uword
8152 unformat_ip6_match (unformat_input_t * input, va_list * args)
8153 {
8154   u8 **matchp = va_arg (*args, u8 **);
8155   u8 *match = 0;
8156   ip6_header_t *ip;
8157   int version = 0;
8158   u32 version_val;
8159   u8 traffic_class = 0;
8160   u32 traffic_class_val = 0;
8161   u8 flow_label = 0;
8162   u8 flow_label_val;
8163   int src = 0, dst = 0;
8164   ip6_address_t src_val, dst_val;
8165   int proto = 0;
8166   u32 proto_val;
8167   int payload_length = 0;
8168   u32 payload_length_val;
8169   int hop_limit = 0;
8170   int hop_limit_val;
8171   u32 ip_version_traffic_class_and_flow_label;
8172
8173   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8174     {
8175       if (unformat (input, "version %d", &version_val))
8176         version = 1;
8177       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8178         traffic_class = 1;
8179       else if (unformat (input, "flow_label %d", &flow_label_val))
8180         flow_label = 1;
8181       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8182         src = 1;
8183       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8184         dst = 1;
8185       else if (unformat (input, "proto %d", &proto_val))
8186         proto = 1;
8187       else if (unformat (input, "payload_length %d", &payload_length_val))
8188         payload_length = 1;
8189       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8190         hop_limit = 1;
8191       else
8192         break;
8193     }
8194
8195   if (version + traffic_class + flow_label + src + dst + proto +
8196       payload_length + hop_limit == 0)
8197     return 0;
8198
8199   /*
8200    * Aligned because we use the real comparison functions
8201    */
8202   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8203
8204   ip = (ip6_header_t *) match;
8205
8206   if (src)
8207     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8208
8209   if (dst)
8210     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8211
8212   if (proto)
8213     ip->protocol = proto_val;
8214
8215   ip_version_traffic_class_and_flow_label = 0;
8216
8217   if (version)
8218     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8219
8220   if (traffic_class)
8221     ip_version_traffic_class_and_flow_label |=
8222       (traffic_class_val & 0xFF) << 20;
8223
8224   if (flow_label)
8225     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8226
8227   ip->ip_version_traffic_class_and_flow_label =
8228     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8229
8230   if (payload_length)
8231     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8232
8233   if (hop_limit)
8234     ip->hop_limit = hop_limit_val;
8235
8236   *matchp = match;
8237   return 1;
8238 }
8239
8240 uword
8241 unformat_l3_match (unformat_input_t * input, va_list * args)
8242 {
8243   u8 **matchp = va_arg (*args, u8 **);
8244
8245   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8246     {
8247       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8248         return 1;
8249       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8250         return 1;
8251       else
8252         break;
8253     }
8254   return 0;
8255 }
8256
8257 uword
8258 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8259 {
8260   u8 *tagp = va_arg (*args, u8 *);
8261   u32 tag;
8262
8263   if (unformat (input, "%d", &tag))
8264     {
8265       tagp[0] = (tag >> 8) & 0x0F;
8266       tagp[1] = tag & 0xFF;
8267       return 1;
8268     }
8269
8270   return 0;
8271 }
8272
8273 uword
8274 unformat_l2_match (unformat_input_t * input, va_list * args)
8275 {
8276   u8 **matchp = va_arg (*args, u8 **);
8277   u8 *match = 0;
8278   u8 src = 0;
8279   u8 src_val[6];
8280   u8 dst = 0;
8281   u8 dst_val[6];
8282   u8 proto = 0;
8283   u16 proto_val;
8284   u8 tag1 = 0;
8285   u8 tag1_val[2];
8286   u8 tag2 = 0;
8287   u8 tag2_val[2];
8288   int len = 14;
8289   u8 ignore_tag1 = 0;
8290   u8 ignore_tag2 = 0;
8291   u8 cos1 = 0;
8292   u8 cos2 = 0;
8293   u32 cos1_val = 0;
8294   u32 cos2_val = 0;
8295
8296   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8297     {
8298       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8299         src = 1;
8300       else
8301         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8302         dst = 1;
8303       else if (unformat (input, "proto %U",
8304                          unformat_ethernet_type_host_byte_order, &proto_val))
8305         proto = 1;
8306       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8307         tag1 = 1;
8308       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8309         tag2 = 1;
8310       else if (unformat (input, "ignore-tag1"))
8311         ignore_tag1 = 1;
8312       else if (unformat (input, "ignore-tag2"))
8313         ignore_tag2 = 1;
8314       else if (unformat (input, "cos1 %d", &cos1_val))
8315         cos1 = 1;
8316       else if (unformat (input, "cos2 %d", &cos2_val))
8317         cos2 = 1;
8318       else
8319         break;
8320     }
8321   if ((src + dst + proto + tag1 + tag2 +
8322        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8323     return 0;
8324
8325   if (tag1 || ignore_tag1 || cos1)
8326     len = 18;
8327   if (tag2 || ignore_tag2 || cos2)
8328     len = 22;
8329
8330   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8331
8332   if (dst)
8333     clib_memcpy (match, dst_val, 6);
8334
8335   if (src)
8336     clib_memcpy (match + 6, src_val, 6);
8337
8338   if (tag2)
8339     {
8340       /* inner vlan tag */
8341       match[19] = tag2_val[1];
8342       match[18] = tag2_val[0];
8343       if (cos2)
8344         match[18] |= (cos2_val & 0x7) << 5;
8345       if (proto)
8346         {
8347           match[21] = proto_val & 0xff;
8348           match[20] = proto_val >> 8;
8349         }
8350       if (tag1)
8351         {
8352           match[15] = tag1_val[1];
8353           match[14] = tag1_val[0];
8354         }
8355       if (cos1)
8356         match[14] |= (cos1_val & 0x7) << 5;
8357       *matchp = match;
8358       return 1;
8359     }
8360   if (tag1)
8361     {
8362       match[15] = tag1_val[1];
8363       match[14] = tag1_val[0];
8364       if (proto)
8365         {
8366           match[17] = proto_val & 0xff;
8367           match[16] = proto_val >> 8;
8368         }
8369       if (cos1)
8370         match[14] |= (cos1_val & 0x7) << 5;
8371
8372       *matchp = match;
8373       return 1;
8374     }
8375   if (cos2)
8376     match[18] |= (cos2_val & 0x7) << 5;
8377   if (cos1)
8378     match[14] |= (cos1_val & 0x7) << 5;
8379   if (proto)
8380     {
8381       match[13] = proto_val & 0xff;
8382       match[12] = proto_val >> 8;
8383     }
8384
8385   *matchp = match;
8386   return 1;
8387 }
8388
8389
8390 uword
8391 unformat_classify_match (unformat_input_t * input, va_list * args)
8392 {
8393   u8 **matchp = va_arg (*args, u8 **);
8394   u32 skip_n_vectors = va_arg (*args, u32);
8395   u32 match_n_vectors = va_arg (*args, u32);
8396
8397   u8 *match = 0;
8398   u8 *l2 = 0;
8399   u8 *l3 = 0;
8400
8401   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8402     {
8403       if (unformat (input, "hex %U", unformat_hex_string, &match))
8404         ;
8405       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8406         ;
8407       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8408         ;
8409       else
8410         break;
8411     }
8412
8413   if (match || l2 || l3)
8414     {
8415       if (l2 || l3)
8416         {
8417           /* "Win a free Ethernet header in every packet" */
8418           if (l2 == 0)
8419             vec_validate_aligned (l2, 13, sizeof (u32x4));
8420           match = l2;
8421           if (vec_len (l3))
8422             {
8423               vec_append_aligned (match, l3, sizeof (u32x4));
8424               vec_free (l3);
8425             }
8426         }
8427
8428       /* Make sure the vector is big enough even if key is all 0's */
8429       vec_validate_aligned
8430         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8431          sizeof (u32x4));
8432
8433       /* Set size, include skipped vectors */
8434       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8435
8436       *matchp = match;
8437
8438       return 1;
8439     }
8440
8441   return 0;
8442 }
8443
8444 static int
8445 api_classify_add_del_session (vat_main_t * vam)
8446 {
8447   unformat_input_t *i = vam->input;
8448   vl_api_classify_add_del_session_t *mp;
8449   int is_add = 1;
8450   u32 table_index = ~0;
8451   u32 hit_next_index = ~0;
8452   u32 opaque_index = ~0;
8453   u8 *match = 0;
8454   i32 advance = 0;
8455   f64 timeout;
8456   u32 skip_n_vectors = 0;
8457   u32 match_n_vectors = 0;
8458
8459   /*
8460    * Warning: you have to supply skip_n and match_n
8461    * because the API client cant simply look at the classify
8462    * table object.
8463    */
8464
8465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8466     {
8467       if (unformat (i, "del"))
8468         is_add = 0;
8469       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8470                          &hit_next_index))
8471         ;
8472       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8473                          &hit_next_index))
8474         ;
8475       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8476                          &hit_next_index))
8477         ;
8478       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8479         ;
8480       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8481         ;
8482       else if (unformat (i, "opaque-index %d", &opaque_index))
8483         ;
8484       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8485         ;
8486       else if (unformat (i, "match_n %d", &match_n_vectors))
8487         ;
8488       else if (unformat (i, "match %U", unformat_classify_match,
8489                          &match, skip_n_vectors, match_n_vectors))
8490         ;
8491       else if (unformat (i, "advance %d", &advance))
8492         ;
8493       else if (unformat (i, "table-index %d", &table_index))
8494         ;
8495       else
8496         break;
8497     }
8498
8499   if (table_index == ~0)
8500     {
8501       errmsg ("Table index required\n");
8502       return -99;
8503     }
8504
8505   if (is_add && match == 0)
8506     {
8507       errmsg ("Match value required\n");
8508       return -99;
8509     }
8510
8511   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8512
8513   mp->is_add = is_add;
8514   mp->table_index = ntohl (table_index);
8515   mp->hit_next_index = ntohl (hit_next_index);
8516   mp->opaque_index = ntohl (opaque_index);
8517   mp->advance = ntohl (advance);
8518   clib_memcpy (mp->match, match, vec_len (match));
8519   vec_free (match);
8520
8521   S;
8522   W;
8523   /* NOTREACHED */
8524 }
8525
8526 static int
8527 api_classify_set_interface_ip_table (vat_main_t * vam)
8528 {
8529   unformat_input_t *i = vam->input;
8530   vl_api_classify_set_interface_ip_table_t *mp;
8531   f64 timeout;
8532   u32 sw_if_index;
8533   int sw_if_index_set;
8534   u32 table_index = ~0;
8535   u8 is_ipv6 = 0;
8536
8537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8538     {
8539       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8540         sw_if_index_set = 1;
8541       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8542         sw_if_index_set = 1;
8543       else if (unformat (i, "table %d", &table_index))
8544         ;
8545       else
8546         {
8547           clib_warning ("parse error '%U'", format_unformat_error, i);
8548           return -99;
8549         }
8550     }
8551
8552   if (sw_if_index_set == 0)
8553     {
8554       errmsg ("missing interface name or sw_if_index\n");
8555       return -99;
8556     }
8557
8558
8559   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8560
8561   mp->sw_if_index = ntohl (sw_if_index);
8562   mp->table_index = ntohl (table_index);
8563   mp->is_ipv6 = is_ipv6;
8564
8565   S;
8566   W;
8567   /* NOTREACHED */
8568   return 0;
8569 }
8570
8571 static int
8572 api_classify_set_interface_l2_tables (vat_main_t * vam)
8573 {
8574   unformat_input_t *i = vam->input;
8575   vl_api_classify_set_interface_l2_tables_t *mp;
8576   f64 timeout;
8577   u32 sw_if_index;
8578   int sw_if_index_set;
8579   u32 ip4_table_index = ~0;
8580   u32 ip6_table_index = ~0;
8581   u32 other_table_index = ~0;
8582   u32 is_input = 1;
8583
8584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8585     {
8586       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8587         sw_if_index_set = 1;
8588       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8589         sw_if_index_set = 1;
8590       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8591         ;
8592       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8593         ;
8594       else if (unformat (i, "other-table %d", &other_table_index))
8595         ;
8596       else if (unformat (i, "is-input %d", &is_input))
8597         ;
8598       else
8599         {
8600           clib_warning ("parse error '%U'", format_unformat_error, i);
8601           return -99;
8602         }
8603     }
8604
8605   if (sw_if_index_set == 0)
8606     {
8607       errmsg ("missing interface name or sw_if_index\n");
8608       return -99;
8609     }
8610
8611
8612   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8613
8614   mp->sw_if_index = ntohl (sw_if_index);
8615   mp->ip4_table_index = ntohl (ip4_table_index);
8616   mp->ip6_table_index = ntohl (ip6_table_index);
8617   mp->other_table_index = ntohl (other_table_index);
8618   mp->is_input = (u8) is_input;
8619
8620   S;
8621   W;
8622   /* NOTREACHED */
8623   return 0;
8624 }
8625
8626 static int
8627 api_set_ipfix_exporter (vat_main_t * vam)
8628 {
8629   unformat_input_t *i = vam->input;
8630   vl_api_set_ipfix_exporter_t *mp;
8631   ip4_address_t collector_address;
8632   u8 collector_address_set = 0;
8633   u32 collector_port = ~0;
8634   ip4_address_t src_address;
8635   u8 src_address_set = 0;
8636   u32 vrf_id = ~0;
8637   u32 path_mtu = ~0;
8638   u32 template_interval = ~0;
8639   u8 udp_checksum = 0;
8640   f64 timeout;
8641
8642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8643     {
8644       if (unformat (i, "collector_address %U", unformat_ip4_address,
8645                     &collector_address))
8646         collector_address_set = 1;
8647       else if (unformat (i, "collector_port %d", &collector_port))
8648         ;
8649       else if (unformat (i, "src_address %U", unformat_ip4_address,
8650                          &src_address))
8651         src_address_set = 1;
8652       else if (unformat (i, "vrf_id %d", &vrf_id))
8653         ;
8654       else if (unformat (i, "path_mtu %d", &path_mtu))
8655         ;
8656       else if (unformat (i, "template_interval %d", &template_interval))
8657         ;
8658       else if (unformat (i, "udp_checksum"))
8659         udp_checksum = 1;
8660       else
8661         break;
8662     }
8663
8664   if (collector_address_set == 0)
8665     {
8666       errmsg ("collector_address required\n");
8667       return -99;
8668     }
8669
8670   if (src_address_set == 0)
8671     {
8672       errmsg ("src_address required\n");
8673       return -99;
8674     }
8675
8676   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
8677
8678   memcpy (mp->collector_address, collector_address.data,
8679           sizeof (collector_address.data));
8680   mp->collector_port = htons ((u16) collector_port);
8681   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8682   mp->vrf_id = htonl (vrf_id);
8683   mp->path_mtu = htonl (path_mtu);
8684   mp->template_interval = htonl (template_interval);
8685   mp->udp_checksum = udp_checksum;
8686
8687   S;
8688   W;
8689   /* NOTREACHED */
8690 }
8691
8692 static int
8693 api_set_ipfix_classify_stream (vat_main_t * vam)
8694 {
8695   unformat_input_t *i = vam->input;
8696   vl_api_set_ipfix_classify_stream_t *mp;
8697   u32 domain_id = 0;
8698   u32 src_port = UDP_DST_PORT_ipfix;
8699   f64 timeout;
8700
8701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8702     {
8703       if (unformat (i, "domain %d", &domain_id))
8704         ;
8705       else if (unformat (i, "src_port %d", &src_port))
8706         ;
8707       else
8708         {
8709           errmsg ("unknown input `%U'", format_unformat_error, i);
8710           return -99;
8711         }
8712     }
8713
8714   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
8715
8716   mp->domain_id = htonl (domain_id);
8717   mp->src_port = htons ((u16) src_port);
8718
8719   S;
8720   W;
8721   /* NOTREACHED */
8722 }
8723
8724 static int
8725 api_ipfix_classify_table_add_del (vat_main_t * vam)
8726 {
8727   unformat_input_t *i = vam->input;
8728   vl_api_ipfix_classify_table_add_del_t *mp;
8729   int is_add = -1;
8730   u32 classify_table_index;
8731   u8 ip_version = 0;
8732   u8 transport_protocol = 255;
8733   f64 timeout;
8734
8735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8736     {
8737       if (unformat (i, "add"))
8738         is_add = 1;
8739       else if (unformat (i, "del"))
8740         is_add = 0;
8741       else if (unformat (i, "table %d", &classify_table_index))
8742         ;
8743       else if (unformat (i, "ip4"))
8744         ip_version = 4;
8745       else if (unformat (i, "ip6"))
8746         ip_version = 6;
8747       else if (unformat (i, "tcp"))
8748         transport_protocol = 6;
8749       else if (unformat (i, "udp"))
8750         transport_protocol = 17;
8751       else
8752         {
8753           errmsg ("unknown input `%U'", format_unformat_error, i);
8754           return -99;
8755         }
8756     }
8757
8758   if (is_add == -1)
8759     {
8760       errmsg ("expecting: add|del");
8761       return -99;
8762     }
8763   if (classify_table_index == ~0)
8764     {
8765       errmsg ("classifier table not specified");
8766       return -99;
8767     }
8768   if (ip_version == 0)
8769     {
8770       errmsg ("IP version not specified");
8771       return -99;
8772     }
8773
8774   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
8775
8776   mp->is_add = is_add;
8777   mp->table_id = htonl (classify_table_index);
8778   mp->ip_version = ip_version;
8779   mp->transport_protocol = transport_protocol;
8780
8781   S;
8782   W;
8783   /* NOTREACHED */
8784 }
8785
8786 static int
8787 api_get_node_index (vat_main_t * vam)
8788 {
8789   unformat_input_t *i = vam->input;
8790   vl_api_get_node_index_t *mp;
8791   f64 timeout;
8792   u8 *name = 0;
8793
8794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8795     {
8796       if (unformat (i, "node %s", &name))
8797         ;
8798       else
8799         break;
8800     }
8801   if (name == 0)
8802     {
8803       errmsg ("node name required\n");
8804       return -99;
8805     }
8806   if (vec_len (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   M (GET_NODE_INDEX, get_node_index);
8813   clib_memcpy (mp->node_name, name, vec_len (name));
8814   vec_free (name);
8815
8816   S;
8817   W;
8818   /* NOTREACHED */
8819   return 0;
8820 }
8821
8822 static int
8823 api_get_next_index (vat_main_t * vam)
8824 {
8825   unformat_input_t *i = vam->input;
8826   vl_api_get_next_index_t *mp;
8827   f64 timeout;
8828   u8 *node_name = 0, *next_node_name = 0;
8829
8830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8831     {
8832       if (unformat (i, "node-name %s", &node_name))
8833         ;
8834       else if (unformat (i, "next-node-name %s", &next_node_name))
8835         break;
8836     }
8837
8838   if (node_name == 0)
8839     {
8840       errmsg ("node name required\n");
8841       return -99;
8842     }
8843   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
8844     {
8845       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8846       return -99;
8847     }
8848
8849   if (next_node_name == 0)
8850     {
8851       errmsg ("next node name required\n");
8852       return -99;
8853     }
8854   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
8855     {
8856       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
8857       return -99;
8858     }
8859
8860   M (GET_NEXT_INDEX, get_next_index);
8861   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
8862   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
8863   vec_free (node_name);
8864   vec_free (next_node_name);
8865
8866   S;
8867   W;
8868   /* NOTREACHED */
8869   return 0;
8870 }
8871
8872 static int
8873 api_add_node_next (vat_main_t * vam)
8874 {
8875   unformat_input_t *i = vam->input;
8876   vl_api_add_node_next_t *mp;
8877   f64 timeout;
8878   u8 *name = 0;
8879   u8 *next = 0;
8880
8881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8882     {
8883       if (unformat (i, "node %s", &name))
8884         ;
8885       else if (unformat (i, "next %s", &next))
8886         ;
8887       else
8888         break;
8889     }
8890   if (name == 0)
8891     {
8892       errmsg ("node name required\n");
8893       return -99;
8894     }
8895   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8896     {
8897       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8898       return -99;
8899     }
8900   if (next == 0)
8901     {
8902       errmsg ("next node required\n");
8903       return -99;
8904     }
8905   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
8906     {
8907       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
8908       return -99;
8909     }
8910
8911   M (ADD_NODE_NEXT, add_node_next);
8912   clib_memcpy (mp->node_name, name, vec_len (name));
8913   clib_memcpy (mp->next_name, next, vec_len (next));
8914   vec_free (name);
8915   vec_free (next);
8916
8917   S;
8918   W;
8919   /* NOTREACHED */
8920   return 0;
8921 }
8922
8923 static int
8924 api_l2tpv3_create_tunnel (vat_main_t * vam)
8925 {
8926   unformat_input_t *i = vam->input;
8927   ip6_address_t client_address, our_address;
8928   int client_address_set = 0;
8929   int our_address_set = 0;
8930   u32 local_session_id = 0;
8931   u32 remote_session_id = 0;
8932   u64 local_cookie = 0;
8933   u64 remote_cookie = 0;
8934   u8 l2_sublayer_present = 0;
8935   vl_api_l2tpv3_create_tunnel_t *mp;
8936   f64 timeout;
8937
8938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8939     {
8940       if (unformat (i, "client_address %U", unformat_ip6_address,
8941                     &client_address))
8942         client_address_set = 1;
8943       else if (unformat (i, "our_address %U", unformat_ip6_address,
8944                          &our_address))
8945         our_address_set = 1;
8946       else if (unformat (i, "local_session_id %d", &local_session_id))
8947         ;
8948       else if (unformat (i, "remote_session_id %d", &remote_session_id))
8949         ;
8950       else if (unformat (i, "local_cookie %lld", &local_cookie))
8951         ;
8952       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
8953         ;
8954       else if (unformat (i, "l2-sublayer-present"))
8955         l2_sublayer_present = 1;
8956       else
8957         break;
8958     }
8959
8960   if (client_address_set == 0)
8961     {
8962       errmsg ("client_address required\n");
8963       return -99;
8964     }
8965
8966   if (our_address_set == 0)
8967     {
8968       errmsg ("our_address required\n");
8969       return -99;
8970     }
8971
8972   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
8973
8974   clib_memcpy (mp->client_address, client_address.as_u8,
8975                sizeof (mp->client_address));
8976
8977   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
8978
8979   mp->local_session_id = ntohl (local_session_id);
8980   mp->remote_session_id = ntohl (remote_session_id);
8981   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
8982   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
8983   mp->l2_sublayer_present = l2_sublayer_present;
8984   mp->is_ipv6 = 1;
8985
8986   S;
8987   W;
8988   /* NOTREACHED */
8989   return 0;
8990 }
8991
8992 static int
8993 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
8994 {
8995   unformat_input_t *i = vam->input;
8996   u32 sw_if_index;
8997   u8 sw_if_index_set = 0;
8998   u64 new_local_cookie = 0;
8999   u64 new_remote_cookie = 0;
9000   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9001   f64 timeout;
9002
9003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9004     {
9005       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9006         sw_if_index_set = 1;
9007       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9008         sw_if_index_set = 1;
9009       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9010         ;
9011       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9012         ;
9013       else
9014         break;
9015     }
9016
9017   if (sw_if_index_set == 0)
9018     {
9019       errmsg ("missing interface name or sw_if_index\n");
9020       return -99;
9021     }
9022
9023   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9024
9025   mp->sw_if_index = ntohl (sw_if_index);
9026   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9027   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9028
9029   S;
9030   W;
9031   /* NOTREACHED */
9032   return 0;
9033 }
9034
9035 static int
9036 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9037 {
9038   unformat_input_t *i = vam->input;
9039   vl_api_l2tpv3_interface_enable_disable_t *mp;
9040   f64 timeout;
9041   u32 sw_if_index;
9042   u8 sw_if_index_set = 0;
9043   u8 enable_disable = 1;
9044
9045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9046     {
9047       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9048         sw_if_index_set = 1;
9049       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9050         sw_if_index_set = 1;
9051       else if (unformat (i, "enable"))
9052         enable_disable = 1;
9053       else if (unformat (i, "disable"))
9054         enable_disable = 0;
9055       else
9056         break;
9057     }
9058
9059   if (sw_if_index_set == 0)
9060     {
9061       errmsg ("missing interface name or sw_if_index\n");
9062       return -99;
9063     }
9064
9065   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9066
9067   mp->sw_if_index = ntohl (sw_if_index);
9068   mp->enable_disable = enable_disable;
9069
9070   S;
9071   W;
9072   /* NOTREACHED */
9073   return 0;
9074 }
9075
9076 static int
9077 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9078 {
9079   unformat_input_t *i = vam->input;
9080   vl_api_l2tpv3_set_lookup_key_t *mp;
9081   f64 timeout;
9082   u8 key = ~0;
9083
9084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9085     {
9086       if (unformat (i, "lookup_v6_src"))
9087         key = L2T_LOOKUP_SRC_ADDRESS;
9088       else if (unformat (i, "lookup_v6_dst"))
9089         key = L2T_LOOKUP_DST_ADDRESS;
9090       else if (unformat (i, "lookup_session_id"))
9091         key = L2T_LOOKUP_SESSION_ID;
9092       else
9093         break;
9094     }
9095
9096   if (key == (u8) ~ 0)
9097     {
9098       errmsg ("l2tp session lookup key unset\n");
9099       return -99;
9100     }
9101
9102   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9103
9104   mp->key = key;
9105
9106   S;
9107   W;
9108   /* NOTREACHED */
9109   return 0;
9110 }
9111
9112 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9113   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9114 {
9115   vat_main_t *vam = &vat_main;
9116
9117   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9118            format_ip6_address, mp->our_address,
9119            format_ip6_address, mp->client_address,
9120            clib_net_to_host_u32 (mp->sw_if_index));
9121
9122   fformat (vam->ofp,
9123            "   local cookies %016llx %016llx remote cookie %016llx\n",
9124            clib_net_to_host_u64 (mp->local_cookie[0]),
9125            clib_net_to_host_u64 (mp->local_cookie[1]),
9126            clib_net_to_host_u64 (mp->remote_cookie));
9127
9128   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9129            clib_net_to_host_u32 (mp->local_session_id),
9130            clib_net_to_host_u32 (mp->remote_session_id));
9131
9132   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9133            mp->l2_sublayer_present ? "preset" : "absent");
9134
9135 }
9136
9137 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9138   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9139 {
9140   vat_main_t *vam = &vat_main;
9141   vat_json_node_t *node = NULL;
9142   struct in6_addr addr;
9143
9144   if (VAT_JSON_ARRAY != vam->json_tree.type)
9145     {
9146       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9147       vat_json_init_array (&vam->json_tree);
9148     }
9149   node = vat_json_array_add (&vam->json_tree);
9150
9151   vat_json_init_object (node);
9152
9153   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9154   vat_json_object_add_ip6 (node, "our_address", addr);
9155   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9156   vat_json_object_add_ip6 (node, "client_address", addr);
9157
9158   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9159   vat_json_init_array (lc);
9160   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9161   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9162   vat_json_object_add_uint (node, "remote_cookie",
9163                             clib_net_to_host_u64 (mp->remote_cookie));
9164
9165   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9166   vat_json_object_add_uint (node, "local_session_id",
9167                             clib_net_to_host_u32 (mp->local_session_id));
9168   vat_json_object_add_uint (node, "remote_session_id",
9169                             clib_net_to_host_u32 (mp->remote_session_id));
9170   vat_json_object_add_string_copy (node, "l2_sublayer",
9171                                    mp->l2_sublayer_present ? (u8 *) "present"
9172                                    : (u8 *) "absent");
9173 }
9174
9175 static int
9176 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9177 {
9178   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9179   f64 timeout;
9180
9181   /* Get list of l2tpv3-tunnel interfaces */
9182   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9183   S;
9184
9185   /* Use a control ping for synchronization */
9186   {
9187     vl_api_control_ping_t *mp;
9188     M (CONTROL_PING, control_ping);
9189     S;
9190   }
9191   W;
9192 }
9193
9194
9195 static void vl_api_sw_interface_tap_details_t_handler
9196   (vl_api_sw_interface_tap_details_t * mp)
9197 {
9198   vat_main_t *vam = &vat_main;
9199
9200   fformat (vam->ofp, "%-16s %d\n",
9201            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9202 }
9203
9204 static void vl_api_sw_interface_tap_details_t_handler_json
9205   (vl_api_sw_interface_tap_details_t * mp)
9206 {
9207   vat_main_t *vam = &vat_main;
9208   vat_json_node_t *node = NULL;
9209
9210   if (VAT_JSON_ARRAY != vam->json_tree.type)
9211     {
9212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9213       vat_json_init_array (&vam->json_tree);
9214     }
9215   node = vat_json_array_add (&vam->json_tree);
9216
9217   vat_json_init_object (node);
9218   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9219   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9220 }
9221
9222 static int
9223 api_sw_interface_tap_dump (vat_main_t * vam)
9224 {
9225   vl_api_sw_interface_tap_dump_t *mp;
9226   f64 timeout;
9227
9228   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9229   /* Get list of tap interfaces */
9230   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9231   S;
9232
9233   /* Use a control ping for synchronization */
9234   {
9235     vl_api_control_ping_t *mp;
9236     M (CONTROL_PING, control_ping);
9237     S;
9238   }
9239   W;
9240 }
9241
9242 static uword unformat_vxlan_decap_next
9243   (unformat_input_t * input, va_list * args)
9244 {
9245   u32 *result = va_arg (*args, u32 *);
9246   u32 tmp;
9247
9248   if (unformat (input, "drop"))
9249     *result = VXLAN_INPUT_NEXT_DROP;
9250   else if (unformat (input, "ip4"))
9251     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9252   else if (unformat (input, "ip6"))
9253     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9254   else if (unformat (input, "l2"))
9255     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9256   else if (unformat (input, "%d", &tmp))
9257     *result = tmp;
9258   else
9259     return 0;
9260   return 1;
9261 }
9262
9263 static int
9264 api_vxlan_add_del_tunnel (vat_main_t * vam)
9265 {
9266   unformat_input_t *line_input = vam->input;
9267   vl_api_vxlan_add_del_tunnel_t *mp;
9268   f64 timeout;
9269   ip4_address_t src4, dst4;
9270   ip6_address_t src6, dst6;
9271   u8 is_add = 1;
9272   u8 ipv4_set = 0, ipv6_set = 0;
9273   u8 src_set = 0;
9274   u8 dst_set = 0;
9275   u32 encap_vrf_id = 0;
9276   u32 decap_next_index = ~0;
9277   u32 vni = 0;
9278
9279   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9280     {
9281       if (unformat (line_input, "del"))
9282         is_add = 0;
9283       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9284         {
9285           ipv4_set = 1;
9286           src_set = 1;
9287         }
9288       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9289         {
9290           ipv4_set = 1;
9291           dst_set = 1;
9292         }
9293       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9294         {
9295           ipv6_set = 1;
9296           src_set = 1;
9297         }
9298       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9299         {
9300           ipv6_set = 1;
9301           dst_set = 1;
9302         }
9303       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9304         ;
9305       else if (unformat (line_input, "decap-next %U",
9306                          unformat_vxlan_decap_next, &decap_next_index))
9307         ;
9308       else if (unformat (line_input, "vni %d", &vni))
9309         ;
9310       else
9311         {
9312           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9313           return -99;
9314         }
9315     }
9316
9317   if (src_set == 0)
9318     {
9319       errmsg ("tunnel src address not specified\n");
9320       return -99;
9321     }
9322   if (dst_set == 0)
9323     {
9324       errmsg ("tunnel dst address not specified\n");
9325       return -99;
9326     }
9327
9328   if (ipv4_set && ipv6_set)
9329     {
9330       errmsg ("both IPv4 and IPv6 addresses specified");
9331       return -99;
9332     }
9333
9334   if ((vni == 0) || (vni >> 24))
9335     {
9336       errmsg ("vni not specified or out of range\n");
9337       return -99;
9338     }
9339
9340   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9341
9342   if (ipv6_set)
9343     {
9344       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9345       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9346     }
9347   else
9348     {
9349       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9350       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9351     }
9352   mp->encap_vrf_id = ntohl (encap_vrf_id);
9353   mp->decap_next_index = ntohl (decap_next_index);
9354   mp->vni = ntohl (vni);
9355   mp->is_add = is_add;
9356   mp->is_ipv6 = ipv6_set;
9357
9358   S;
9359   W;
9360   /* NOTREACHED */
9361   return 0;
9362 }
9363
9364 static void vl_api_vxlan_tunnel_details_t_handler
9365   (vl_api_vxlan_tunnel_details_t * mp)
9366 {
9367   vat_main_t *vam = &vat_main;
9368
9369   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9370            ntohl (mp->sw_if_index),
9371            format_ip46_address, &(mp->src_address[0]),
9372            IP46_TYPE_ANY,
9373            format_ip46_address, &(mp->dst_address[0]),
9374            IP46_TYPE_ANY,
9375            ntohl (mp->encap_vrf_id),
9376            ntohl (mp->decap_next_index), ntohl (mp->vni));
9377 }
9378
9379 static void vl_api_vxlan_tunnel_details_t_handler_json
9380   (vl_api_vxlan_tunnel_details_t * mp)
9381 {
9382   vat_main_t *vam = &vat_main;
9383   vat_json_node_t *node = NULL;
9384   struct in_addr ip4;
9385   struct in6_addr ip6;
9386
9387   if (VAT_JSON_ARRAY != vam->json_tree.type)
9388     {
9389       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9390       vat_json_init_array (&vam->json_tree);
9391     }
9392   node = vat_json_array_add (&vam->json_tree);
9393
9394   vat_json_init_object (node);
9395   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9396   if (mp->is_ipv6)
9397     {
9398       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9399       vat_json_object_add_ip6 (node, "src_address", ip6);
9400       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9401       vat_json_object_add_ip6 (node, "dst_address", ip6);
9402     }
9403   else
9404     {
9405       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9406       vat_json_object_add_ip4 (node, "src_address", ip4);
9407       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9408       vat_json_object_add_ip4 (node, "dst_address", ip4);
9409     }
9410   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9411   vat_json_object_add_uint (node, "decap_next_index",
9412                             ntohl (mp->decap_next_index));
9413   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9414   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9415 }
9416
9417 static int
9418 api_vxlan_tunnel_dump (vat_main_t * vam)
9419 {
9420   unformat_input_t *i = vam->input;
9421   vl_api_vxlan_tunnel_dump_t *mp;
9422   f64 timeout;
9423   u32 sw_if_index;
9424   u8 sw_if_index_set = 0;
9425
9426   /* Parse args required to build the message */
9427   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9428     {
9429       if (unformat (i, "sw_if_index %d", &sw_if_index))
9430         sw_if_index_set = 1;
9431       else
9432         break;
9433     }
9434
9435   if (sw_if_index_set == 0)
9436     {
9437       sw_if_index = ~0;
9438     }
9439
9440   if (!vam->json_output)
9441     {
9442       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9443                "sw_if_index", "src_address", "dst_address",
9444                "encap_vrf_id", "decap_next_index", "vni");
9445     }
9446
9447   /* Get list of vxlan-tunnel interfaces */
9448   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9449
9450   mp->sw_if_index = htonl (sw_if_index);
9451
9452   S;
9453
9454   /* Use a control ping for synchronization */
9455   {
9456     vl_api_control_ping_t *mp;
9457     M (CONTROL_PING, control_ping);
9458     S;
9459   }
9460   W;
9461 }
9462
9463 static int
9464 api_gre_add_del_tunnel (vat_main_t * vam)
9465 {
9466   unformat_input_t *line_input = vam->input;
9467   vl_api_gre_add_del_tunnel_t *mp;
9468   f64 timeout;
9469   ip4_address_t src4, dst4;
9470   u8 is_add = 1;
9471   u8 src_set = 0;
9472   u8 dst_set = 0;
9473   u32 outer_fib_id = 0;
9474
9475   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9476     {
9477       if (unformat (line_input, "del"))
9478         is_add = 0;
9479       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9480         src_set = 1;
9481       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9482         dst_set = 1;
9483       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9484         ;
9485       else
9486         {
9487           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9488           return -99;
9489         }
9490     }
9491
9492   if (src_set == 0)
9493     {
9494       errmsg ("tunnel src address not specified\n");
9495       return -99;
9496     }
9497   if (dst_set == 0)
9498     {
9499       errmsg ("tunnel dst address not specified\n");
9500       return -99;
9501     }
9502
9503
9504   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9505
9506   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9507   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9508   mp->outer_fib_id = ntohl (outer_fib_id);
9509   mp->is_add = is_add;
9510
9511   S;
9512   W;
9513   /* NOTREACHED */
9514   return 0;
9515 }
9516
9517 static void vl_api_gre_tunnel_details_t_handler
9518   (vl_api_gre_tunnel_details_t * mp)
9519 {
9520   vat_main_t *vam = &vat_main;
9521
9522   fformat (vam->ofp, "%11d%15U%15U%14d\n",
9523            ntohl (mp->sw_if_index),
9524            format_ip4_address, &mp->src_address,
9525            format_ip4_address, &mp->dst_address, ntohl (mp->outer_fib_id));
9526 }
9527
9528 static void vl_api_gre_tunnel_details_t_handler_json
9529   (vl_api_gre_tunnel_details_t * mp)
9530 {
9531   vat_main_t *vam = &vat_main;
9532   vat_json_node_t *node = NULL;
9533   struct in_addr ip4;
9534
9535   if (VAT_JSON_ARRAY != vam->json_tree.type)
9536     {
9537       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9538       vat_json_init_array (&vam->json_tree);
9539     }
9540   node = vat_json_array_add (&vam->json_tree);
9541
9542   vat_json_init_object (node);
9543   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9544   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9545   vat_json_object_add_ip4 (node, "src_address", ip4);
9546   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9547   vat_json_object_add_ip4 (node, "dst_address", ip4);
9548   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9549 }
9550
9551 static int
9552 api_gre_tunnel_dump (vat_main_t * vam)
9553 {
9554   unformat_input_t *i = vam->input;
9555   vl_api_gre_tunnel_dump_t *mp;
9556   f64 timeout;
9557   u32 sw_if_index;
9558   u8 sw_if_index_set = 0;
9559
9560   /* Parse args required to build the message */
9561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9562     {
9563       if (unformat (i, "sw_if_index %d", &sw_if_index))
9564         sw_if_index_set = 1;
9565       else
9566         break;
9567     }
9568
9569   if (sw_if_index_set == 0)
9570     {
9571       sw_if_index = ~0;
9572     }
9573
9574   if (!vam->json_output)
9575     {
9576       fformat (vam->ofp, "%11s%15s%15s%14s\n",
9577                "sw_if_index", "src_address", "dst_address", "outer_fib_id");
9578     }
9579
9580   /* Get list of gre-tunnel interfaces */
9581   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9582
9583   mp->sw_if_index = htonl (sw_if_index);
9584
9585   S;
9586
9587   /* Use a control ping for synchronization */
9588   {
9589     vl_api_control_ping_t *mp;
9590     M (CONTROL_PING, control_ping);
9591     S;
9592   }
9593   W;
9594 }
9595
9596 static int
9597 api_l2_fib_clear_table (vat_main_t * vam)
9598 {
9599 //  unformat_input_t * i = vam->input;
9600   vl_api_l2_fib_clear_table_t *mp;
9601   f64 timeout;
9602
9603   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9604
9605   S;
9606   W;
9607   /* NOTREACHED */
9608   return 0;
9609 }
9610
9611 static int
9612 api_l2_interface_efp_filter (vat_main_t * vam)
9613 {
9614   unformat_input_t *i = vam->input;
9615   vl_api_l2_interface_efp_filter_t *mp;
9616   f64 timeout;
9617   u32 sw_if_index;
9618   u8 enable = 1;
9619   u8 sw_if_index_set = 0;
9620
9621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9622     {
9623       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9624         sw_if_index_set = 1;
9625       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9626         sw_if_index_set = 1;
9627       else if (unformat (i, "enable"))
9628         enable = 1;
9629       else if (unformat (i, "disable"))
9630         enable = 0;
9631       else
9632         {
9633           clib_warning ("parse error '%U'", format_unformat_error, i);
9634           return -99;
9635         }
9636     }
9637
9638   if (sw_if_index_set == 0)
9639     {
9640       errmsg ("missing sw_if_index\n");
9641       return -99;
9642     }
9643
9644   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9645
9646   mp->sw_if_index = ntohl (sw_if_index);
9647   mp->enable_disable = enable;
9648
9649   S;
9650   W;
9651   /* NOTREACHED */
9652   return 0;
9653 }
9654
9655 #define foreach_vtr_op                          \
9656 _("disable",  L2_VTR_DISABLED)                  \
9657 _("push-1",  L2_VTR_PUSH_1)                     \
9658 _("push-2",  L2_VTR_PUSH_2)                     \
9659 _("pop-1",  L2_VTR_POP_1)                       \
9660 _("pop-2",  L2_VTR_POP_2)                       \
9661 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9662 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9663 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9664 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9665
9666 static int
9667 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9668 {
9669   unformat_input_t *i = vam->input;
9670   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9671   f64 timeout;
9672   u32 sw_if_index;
9673   u8 sw_if_index_set = 0;
9674   u8 vtr_op_set = 0;
9675   u32 vtr_op = 0;
9676   u32 push_dot1q = 1;
9677   u32 tag1 = ~0;
9678   u32 tag2 = ~0;
9679
9680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9681     {
9682       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9683         sw_if_index_set = 1;
9684       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9685         sw_if_index_set = 1;
9686       else if (unformat (i, "vtr_op %d", &vtr_op))
9687         vtr_op_set = 1;
9688 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9689       foreach_vtr_op
9690 #undef _
9691         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9692         ;
9693       else if (unformat (i, "tag1 %d", &tag1))
9694         ;
9695       else if (unformat (i, "tag2 %d", &tag2))
9696         ;
9697       else
9698         {
9699           clib_warning ("parse error '%U'", format_unformat_error, i);
9700           return -99;
9701         }
9702     }
9703
9704   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9705     {
9706       errmsg ("missing vtr operation or sw_if_index\n");
9707       return -99;
9708     }
9709
9710   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
9711     mp->sw_if_index = ntohl (sw_if_index);
9712   mp->vtr_op = ntohl (vtr_op);
9713   mp->push_dot1q = ntohl (push_dot1q);
9714   mp->tag1 = ntohl (tag1);
9715   mp->tag2 = ntohl (tag2);
9716
9717   S;
9718   W;
9719   /* NOTREACHED */
9720   return 0;
9721 }
9722
9723 static int
9724 api_create_vhost_user_if (vat_main_t * vam)
9725 {
9726   unformat_input_t *i = vam->input;
9727   vl_api_create_vhost_user_if_t *mp;
9728   f64 timeout;
9729   u8 *file_name;
9730   u8 is_server = 0;
9731   u8 file_name_set = 0;
9732   u32 custom_dev_instance = ~0;
9733   u8 hwaddr[6];
9734   u8 use_custom_mac = 0;
9735
9736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9737     {
9738       if (unformat (i, "socket %s", &file_name))
9739         {
9740           file_name_set = 1;
9741         }
9742       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9743         ;
9744       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9745         use_custom_mac = 1;
9746       else if (unformat (i, "server"))
9747         is_server = 1;
9748       else
9749         break;
9750     }
9751
9752   if (file_name_set == 0)
9753     {
9754       errmsg ("missing socket file name\n");
9755       return -99;
9756     }
9757
9758   if (vec_len (file_name) > 255)
9759     {
9760       errmsg ("socket file name too long\n");
9761       return -99;
9762     }
9763   vec_add1 (file_name, 0);
9764
9765   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
9766
9767   mp->is_server = is_server;
9768   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9769   vec_free (file_name);
9770   if (custom_dev_instance != ~0)
9771     {
9772       mp->renumber = 1;
9773       mp->custom_dev_instance = ntohl (custom_dev_instance);
9774     }
9775   mp->use_custom_mac = use_custom_mac;
9776   clib_memcpy (mp->mac_address, hwaddr, 6);
9777
9778   S;
9779   W;
9780   /* NOTREACHED */
9781   return 0;
9782 }
9783
9784 static int
9785 api_modify_vhost_user_if (vat_main_t * vam)
9786 {
9787   unformat_input_t *i = vam->input;
9788   vl_api_modify_vhost_user_if_t *mp;
9789   f64 timeout;
9790   u8 *file_name;
9791   u8 is_server = 0;
9792   u8 file_name_set = 0;
9793   u32 custom_dev_instance = ~0;
9794   u8 sw_if_index_set = 0;
9795   u32 sw_if_index = (u32) ~ 0;
9796
9797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9798     {
9799       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9800         sw_if_index_set = 1;
9801       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9802         sw_if_index_set = 1;
9803       else if (unformat (i, "socket %s", &file_name))
9804         {
9805           file_name_set = 1;
9806         }
9807       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9808         ;
9809       else if (unformat (i, "server"))
9810         is_server = 1;
9811       else
9812         break;
9813     }
9814
9815   if (sw_if_index_set == 0)
9816     {
9817       errmsg ("missing sw_if_index or interface name\n");
9818       return -99;
9819     }
9820
9821   if (file_name_set == 0)
9822     {
9823       errmsg ("missing socket file name\n");
9824       return -99;
9825     }
9826
9827   if (vec_len (file_name) > 255)
9828     {
9829       errmsg ("socket file name too long\n");
9830       return -99;
9831     }
9832   vec_add1 (file_name, 0);
9833
9834   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
9835
9836   mp->sw_if_index = ntohl (sw_if_index);
9837   mp->is_server = is_server;
9838   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9839   vec_free (file_name);
9840   if (custom_dev_instance != ~0)
9841     {
9842       mp->renumber = 1;
9843       mp->custom_dev_instance = ntohl (custom_dev_instance);
9844     }
9845
9846   S;
9847   W;
9848   /* NOTREACHED */
9849   return 0;
9850 }
9851
9852 static int
9853 api_delete_vhost_user_if (vat_main_t * vam)
9854 {
9855   unformat_input_t *i = vam->input;
9856   vl_api_delete_vhost_user_if_t *mp;
9857   f64 timeout;
9858   u32 sw_if_index = ~0;
9859   u8 sw_if_index_set = 0;
9860
9861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9862     {
9863       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9864         sw_if_index_set = 1;
9865       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9866         sw_if_index_set = 1;
9867       else
9868         break;
9869     }
9870
9871   if (sw_if_index_set == 0)
9872     {
9873       errmsg ("missing sw_if_index or interface name\n");
9874       return -99;
9875     }
9876
9877
9878   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
9879
9880   mp->sw_if_index = ntohl (sw_if_index);
9881
9882   S;
9883   W;
9884   /* NOTREACHED */
9885   return 0;
9886 }
9887
9888 static void vl_api_sw_interface_vhost_user_details_t_handler
9889   (vl_api_sw_interface_vhost_user_details_t * mp)
9890 {
9891   vat_main_t *vam = &vat_main;
9892
9893   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
9894            (char *) mp->interface_name,
9895            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
9896            clib_net_to_host_u64 (mp->features), mp->is_server,
9897            ntohl (mp->num_regions), (char *) mp->sock_filename);
9898   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
9899 }
9900
9901 static void vl_api_sw_interface_vhost_user_details_t_handler_json
9902   (vl_api_sw_interface_vhost_user_details_t * mp)
9903 {
9904   vat_main_t *vam = &vat_main;
9905   vat_json_node_t *node = NULL;
9906
9907   if (VAT_JSON_ARRAY != vam->json_tree.type)
9908     {
9909       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9910       vat_json_init_array (&vam->json_tree);
9911     }
9912   node = vat_json_array_add (&vam->json_tree);
9913
9914   vat_json_init_object (node);
9915   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9916   vat_json_object_add_string_copy (node, "interface_name",
9917                                    mp->interface_name);
9918   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
9919                             ntohl (mp->virtio_net_hdr_sz));
9920   vat_json_object_add_uint (node, "features",
9921                             clib_net_to_host_u64 (mp->features));
9922   vat_json_object_add_uint (node, "is_server", mp->is_server);
9923   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
9924   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
9925   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
9926 }
9927
9928 static int
9929 api_sw_interface_vhost_user_dump (vat_main_t * vam)
9930 {
9931   vl_api_sw_interface_vhost_user_dump_t *mp;
9932   f64 timeout;
9933   fformat (vam->ofp,
9934            "Interface name           idx hdr_sz features server regions filename\n");
9935
9936   /* Get list of vhost-user interfaces */
9937   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
9938   S;
9939
9940   /* Use a control ping for synchronization */
9941   {
9942     vl_api_control_ping_t *mp;
9943     M (CONTROL_PING, control_ping);
9944     S;
9945   }
9946   W;
9947 }
9948
9949 static int
9950 api_show_version (vat_main_t * vam)
9951 {
9952   vl_api_show_version_t *mp;
9953   f64 timeout;
9954
9955   M (SHOW_VERSION, show_version);
9956
9957   S;
9958   W;
9959   /* NOTREACHED */
9960   return 0;
9961 }
9962
9963
9964 static int
9965 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
9966 {
9967   unformat_input_t *line_input = vam->input;
9968   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
9969   f64 timeout;
9970   ip4_address_t local4, remote4;
9971   ip6_address_t local6, remote6;
9972   u8 is_add = 1;
9973   u8 ipv4_set = 0, ipv6_set = 0;
9974   u8 local_set = 0;
9975   u8 remote_set = 0;
9976   u32 encap_vrf_id = 0;
9977   u32 decap_vrf_id = 0;
9978   u8 protocol = ~0;
9979   u32 vni;
9980   u8 vni_set = 0;
9981
9982   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9983     {
9984       if (unformat (line_input, "del"))
9985         is_add = 0;
9986       else if (unformat (line_input, "local %U",
9987                          unformat_ip4_address, &local4))
9988         {
9989           local_set = 1;
9990           ipv4_set = 1;
9991         }
9992       else if (unformat (line_input, "remote %U",
9993                          unformat_ip4_address, &remote4))
9994         {
9995           remote_set = 1;
9996           ipv4_set = 1;
9997         }
9998       else if (unformat (line_input, "local %U",
9999                          unformat_ip6_address, &local6))
10000         {
10001           local_set = 1;
10002           ipv6_set = 1;
10003         }
10004       else if (unformat (line_input, "remote %U",
10005                          unformat_ip6_address, &remote6))
10006         {
10007           remote_set = 1;
10008           ipv6_set = 1;
10009         }
10010       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10011         ;
10012       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10013         ;
10014       else if (unformat (line_input, "vni %d", &vni))
10015         vni_set = 1;
10016       else if (unformat (line_input, "next-ip4"))
10017         protocol = 1;
10018       else if (unformat (line_input, "next-ip6"))
10019         protocol = 2;
10020       else if (unformat (line_input, "next-ethernet"))
10021         protocol = 3;
10022       else if (unformat (line_input, "next-nsh"))
10023         protocol = 4;
10024       else
10025         {
10026           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10027           return -99;
10028         }
10029     }
10030
10031   if (local_set == 0)
10032     {
10033       errmsg ("tunnel local address not specified\n");
10034       return -99;
10035     }
10036   if (remote_set == 0)
10037     {
10038       errmsg ("tunnel remote address not specified\n");
10039       return -99;
10040     }
10041   if (ipv4_set && ipv6_set)
10042     {
10043       errmsg ("both IPv4 and IPv6 addresses specified");
10044       return -99;
10045     }
10046
10047   if (vni_set == 0)
10048     {
10049       errmsg ("vni not specified\n");
10050       return -99;
10051     }
10052
10053   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10054
10055
10056   if (ipv6_set)
10057     {
10058       clib_memcpy (&mp->local, &local6, sizeof (local6));
10059       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10060     }
10061   else
10062     {
10063       clib_memcpy (&mp->local, &local4, sizeof (local4));
10064       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10065     }
10066
10067   mp->encap_vrf_id = ntohl (encap_vrf_id);
10068   mp->decap_vrf_id = ntohl (decap_vrf_id);
10069   mp->protocol = ntohl (protocol);
10070   mp->vni = ntohl (vni);
10071   mp->is_add = is_add;
10072   mp->is_ipv6 = ipv6_set;
10073
10074   S;
10075   W;
10076   /* NOTREACHED */
10077   return 0;
10078 }
10079
10080 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10081   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10082 {
10083   vat_main_t *vam = &vat_main;
10084
10085   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10086            ntohl (mp->sw_if_index),
10087            format_ip46_address, &(mp->local[0]),
10088            format_ip46_address, &(mp->remote[0]),
10089            ntohl (mp->vni),
10090            ntohl (mp->protocol),
10091            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10092 }
10093
10094 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10095   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10096 {
10097   vat_main_t *vam = &vat_main;
10098   vat_json_node_t *node = NULL;
10099   struct in_addr ip4;
10100   struct in6_addr ip6;
10101
10102   if (VAT_JSON_ARRAY != vam->json_tree.type)
10103     {
10104       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10105       vat_json_init_array (&vam->json_tree);
10106     }
10107   node = vat_json_array_add (&vam->json_tree);
10108
10109   vat_json_init_object (node);
10110   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10111   if (mp->is_ipv6)
10112     {
10113       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10114       vat_json_object_add_ip6 (node, "local", ip6);
10115       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10116       vat_json_object_add_ip6 (node, "remote", ip6);
10117     }
10118   else
10119     {
10120       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10121       vat_json_object_add_ip4 (node, "local", ip4);
10122       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10123       vat_json_object_add_ip4 (node, "remote", ip4);
10124     }
10125   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10126   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10127   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10128   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10129   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10130 }
10131
10132 static int
10133 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10134 {
10135   unformat_input_t *i = vam->input;
10136   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10137   f64 timeout;
10138   u32 sw_if_index;
10139   u8 sw_if_index_set = 0;
10140
10141   /* Parse args required to build the message */
10142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10143     {
10144       if (unformat (i, "sw_if_index %d", &sw_if_index))
10145         sw_if_index_set = 1;
10146       else
10147         break;
10148     }
10149
10150   if (sw_if_index_set == 0)
10151     {
10152       sw_if_index = ~0;
10153     }
10154
10155   if (!vam->json_output)
10156     {
10157       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10158                "sw_if_index", "local", "remote", "vni",
10159                "protocol", "encap_vrf_id", "decap_vrf_id");
10160     }
10161
10162   /* Get list of vxlan-tunnel interfaces */
10163   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10164
10165   mp->sw_if_index = htonl (sw_if_index);
10166
10167   S;
10168
10169   /* Use a control ping for synchronization */
10170   {
10171     vl_api_control_ping_t *mp;
10172     M (CONTROL_PING, control_ping);
10173     S;
10174   }
10175   W;
10176 }
10177
10178 u8 *
10179 format_l2_fib_mac_address (u8 * s, va_list * args)
10180 {
10181   u8 *a = va_arg (*args, u8 *);
10182
10183   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10184                  a[2], a[3], a[4], a[5], a[6], a[7]);
10185 }
10186
10187 static void vl_api_l2_fib_table_entry_t_handler
10188   (vl_api_l2_fib_table_entry_t * mp)
10189 {
10190   vat_main_t *vam = &vat_main;
10191
10192   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10193            "       %d       %d     %d\n",
10194            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10195            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10196            mp->bvi_mac);
10197 }
10198
10199 static void vl_api_l2_fib_table_entry_t_handler_json
10200   (vl_api_l2_fib_table_entry_t * mp)
10201 {
10202   vat_main_t *vam = &vat_main;
10203   vat_json_node_t *node = NULL;
10204
10205   if (VAT_JSON_ARRAY != vam->json_tree.type)
10206     {
10207       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10208       vat_json_init_array (&vam->json_tree);
10209     }
10210   node = vat_json_array_add (&vam->json_tree);
10211
10212   vat_json_init_object (node);
10213   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10214   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10215   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10216   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10217   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10218   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10219 }
10220
10221 static int
10222 api_l2_fib_table_dump (vat_main_t * vam)
10223 {
10224   unformat_input_t *i = vam->input;
10225   vl_api_l2_fib_table_dump_t *mp;
10226   f64 timeout;
10227   u32 bd_id;
10228   u8 bd_id_set = 0;
10229
10230   /* Parse args required to build the message */
10231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10232     {
10233       if (unformat (i, "bd_id %d", &bd_id))
10234         bd_id_set = 1;
10235       else
10236         break;
10237     }
10238
10239   if (bd_id_set == 0)
10240     {
10241       errmsg ("missing bridge domain\n");
10242       return -99;
10243     }
10244
10245   fformat (vam->ofp,
10246            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10247
10248   /* Get list of l2 fib entries */
10249   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10250
10251   mp->bd_id = ntohl (bd_id);
10252   S;
10253
10254   /* Use a control ping for synchronization */
10255   {
10256     vl_api_control_ping_t *mp;
10257     M (CONTROL_PING, control_ping);
10258     S;
10259   }
10260   W;
10261 }
10262
10263
10264 static int
10265 api_interface_name_renumber (vat_main_t * vam)
10266 {
10267   unformat_input_t *line_input = vam->input;
10268   vl_api_interface_name_renumber_t *mp;
10269   u32 sw_if_index = ~0;
10270   f64 timeout;
10271   u32 new_show_dev_instance = ~0;
10272
10273   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10274     {
10275       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10276                     &sw_if_index))
10277         ;
10278       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10279         ;
10280       else if (unformat (line_input, "new_show_dev_instance %d",
10281                          &new_show_dev_instance))
10282         ;
10283       else
10284         break;
10285     }
10286
10287   if (sw_if_index == ~0)
10288     {
10289       errmsg ("missing interface name or sw_if_index\n");
10290       return -99;
10291     }
10292
10293   if (new_show_dev_instance == ~0)
10294     {
10295       errmsg ("missing new_show_dev_instance\n");
10296       return -99;
10297     }
10298
10299   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10300
10301   mp->sw_if_index = ntohl (sw_if_index);
10302   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10303
10304   S;
10305   W;
10306 }
10307
10308 static int
10309 api_want_ip4_arp_events (vat_main_t * vam)
10310 {
10311   unformat_input_t *line_input = vam->input;
10312   vl_api_want_ip4_arp_events_t *mp;
10313   f64 timeout;
10314   ip4_address_t address;
10315   int address_set = 0;
10316   u32 enable_disable = 1;
10317
10318   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10319     {
10320       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10321         address_set = 1;
10322       else if (unformat (line_input, "del"))
10323         enable_disable = 0;
10324       else
10325         break;
10326     }
10327
10328   if (address_set == 0)
10329     {
10330       errmsg ("missing addresses\n");
10331       return -99;
10332     }
10333
10334   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10335   mp->enable_disable = enable_disable;
10336   mp->pid = getpid ();
10337   mp->address = address.as_u32;
10338
10339   S;
10340   W;
10341 }
10342
10343 static int
10344 api_want_ip6_nd_events (vat_main_t * vam)
10345 {
10346   unformat_input_t *line_input = vam->input;
10347   vl_api_want_ip6_nd_events_t *mp;
10348   f64 timeout;
10349   ip6_address_t address;
10350   int address_set = 0;
10351   u32 enable_disable = 1;
10352
10353   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10354     {
10355       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
10356         address_set = 1;
10357       else if (unformat (line_input, "del"))
10358         enable_disable = 0;
10359       else
10360         break;
10361     }
10362
10363   if (address_set == 0)
10364     {
10365       errmsg ("missing addresses\n");
10366       return -99;
10367     }
10368
10369   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
10370   mp->enable_disable = enable_disable;
10371   mp->pid = getpid ();
10372   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
10373
10374   S;
10375   W;
10376 }
10377
10378 static int
10379 api_input_acl_set_interface (vat_main_t * vam)
10380 {
10381   unformat_input_t *i = vam->input;
10382   vl_api_input_acl_set_interface_t *mp;
10383   f64 timeout;
10384   u32 sw_if_index;
10385   int sw_if_index_set;
10386   u32 ip4_table_index = ~0;
10387   u32 ip6_table_index = ~0;
10388   u32 l2_table_index = ~0;
10389   u8 is_add = 1;
10390
10391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10392     {
10393       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10394         sw_if_index_set = 1;
10395       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10396         sw_if_index_set = 1;
10397       else if (unformat (i, "del"))
10398         is_add = 0;
10399       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10400         ;
10401       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10402         ;
10403       else if (unformat (i, "l2-table %d", &l2_table_index))
10404         ;
10405       else
10406         {
10407           clib_warning ("parse error '%U'", format_unformat_error, i);
10408           return -99;
10409         }
10410     }
10411
10412   if (sw_if_index_set == 0)
10413     {
10414       errmsg ("missing interface name or sw_if_index\n");
10415       return -99;
10416     }
10417
10418   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10419
10420   mp->sw_if_index = ntohl (sw_if_index);
10421   mp->ip4_table_index = ntohl (ip4_table_index);
10422   mp->ip6_table_index = ntohl (ip6_table_index);
10423   mp->l2_table_index = ntohl (l2_table_index);
10424   mp->is_add = is_add;
10425
10426   S;
10427   W;
10428   /* NOTREACHED */
10429   return 0;
10430 }
10431
10432 static int
10433 api_ip_address_dump (vat_main_t * vam)
10434 {
10435   unformat_input_t *i = vam->input;
10436   vl_api_ip_address_dump_t *mp;
10437   u32 sw_if_index = ~0;
10438   u8 sw_if_index_set = 0;
10439   u8 ipv4_set = 0;
10440   u8 ipv6_set = 0;
10441   f64 timeout;
10442
10443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10444     {
10445       if (unformat (i, "sw_if_index %d", &sw_if_index))
10446         sw_if_index_set = 1;
10447       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10448         sw_if_index_set = 1;
10449       else if (unformat (i, "ipv4"))
10450         ipv4_set = 1;
10451       else if (unformat (i, "ipv6"))
10452         ipv6_set = 1;
10453       else
10454         break;
10455     }
10456
10457   if (ipv4_set && ipv6_set)
10458     {
10459       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10460       return -99;
10461     }
10462
10463   if ((!ipv4_set) && (!ipv6_set))
10464     {
10465       errmsg ("no ipv4 nor ipv6 flag set\n");
10466       return -99;
10467     }
10468
10469   if (sw_if_index_set == 0)
10470     {
10471       errmsg ("missing interface name or sw_if_index\n");
10472       return -99;
10473     }
10474
10475   vam->current_sw_if_index = sw_if_index;
10476   vam->is_ipv6 = ipv6_set;
10477
10478   M (IP_ADDRESS_DUMP, ip_address_dump);
10479   mp->sw_if_index = ntohl (sw_if_index);
10480   mp->is_ipv6 = ipv6_set;
10481   S;
10482
10483   /* Use a control ping for synchronization */
10484   {
10485     vl_api_control_ping_t *mp;
10486     M (CONTROL_PING, control_ping);
10487     S;
10488   }
10489   W;
10490 }
10491
10492 static int
10493 api_ip_dump (vat_main_t * vam)
10494 {
10495   vl_api_ip_dump_t *mp;
10496   unformat_input_t *in = vam->input;
10497   int ipv4_set = 0;
10498   int ipv6_set = 0;
10499   int is_ipv6;
10500   f64 timeout;
10501   int i;
10502
10503   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10504     {
10505       if (unformat (in, "ipv4"))
10506         ipv4_set = 1;
10507       else if (unformat (in, "ipv6"))
10508         ipv6_set = 1;
10509       else
10510         break;
10511     }
10512
10513   if (ipv4_set && ipv6_set)
10514     {
10515       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10516       return -99;
10517     }
10518
10519   if ((!ipv4_set) && (!ipv6_set))
10520     {
10521       errmsg ("no ipv4 nor ipv6 flag set\n");
10522       return -99;
10523     }
10524
10525   is_ipv6 = ipv6_set;
10526   vam->is_ipv6 = is_ipv6;
10527
10528   /* free old data */
10529   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10530     {
10531       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10532     }
10533   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10534
10535   M (IP_DUMP, ip_dump);
10536   mp->is_ipv6 = ipv6_set;
10537   S;
10538
10539   /* Use a control ping for synchronization */
10540   {
10541     vl_api_control_ping_t *mp;
10542     M (CONTROL_PING, control_ping);
10543     S;
10544   }
10545   W;
10546 }
10547
10548 static int
10549 api_ipsec_spd_add_del (vat_main_t * vam)
10550 {
10551 #if DPDK > 0
10552   unformat_input_t *i = vam->input;
10553   vl_api_ipsec_spd_add_del_t *mp;
10554   f64 timeout;
10555   u32 spd_id = ~0;
10556   u8 is_add = 1;
10557
10558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10559     {
10560       if (unformat (i, "spd_id %d", &spd_id))
10561         ;
10562       else if (unformat (i, "del"))
10563         is_add = 0;
10564       else
10565         {
10566           clib_warning ("parse error '%U'", format_unformat_error, i);
10567           return -99;
10568         }
10569     }
10570   if (spd_id == ~0)
10571     {
10572       errmsg ("spd_id must be set\n");
10573       return -99;
10574     }
10575
10576   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10577
10578   mp->spd_id = ntohl (spd_id);
10579   mp->is_add = is_add;
10580
10581   S;
10582   W;
10583   /* NOTREACHED */
10584   return 0;
10585 #else
10586   clib_warning ("unsupported (no dpdk)");
10587   return -99;
10588 #endif
10589 }
10590
10591 static int
10592 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10593 {
10594 #if DPDK > 0
10595   unformat_input_t *i = vam->input;
10596   vl_api_ipsec_interface_add_del_spd_t *mp;
10597   f64 timeout;
10598   u32 sw_if_index;
10599   u8 sw_if_index_set = 0;
10600   u32 spd_id = (u32) ~ 0;
10601   u8 is_add = 1;
10602
10603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10604     {
10605       if (unformat (i, "del"))
10606         is_add = 0;
10607       else if (unformat (i, "spd_id %d", &spd_id))
10608         ;
10609       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10610         sw_if_index_set = 1;
10611       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10612         sw_if_index_set = 1;
10613       else
10614         {
10615           clib_warning ("parse error '%U'", format_unformat_error, i);
10616           return -99;
10617         }
10618
10619     }
10620
10621   if (spd_id == (u32) ~ 0)
10622     {
10623       errmsg ("spd_id must be set\n");
10624       return -99;
10625     }
10626
10627   if (sw_if_index_set == 0)
10628     {
10629       errmsg ("missing interface name or sw_if_index\n");
10630       return -99;
10631     }
10632
10633   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10634
10635   mp->spd_id = ntohl (spd_id);
10636   mp->sw_if_index = ntohl (sw_if_index);
10637   mp->is_add = is_add;
10638
10639   S;
10640   W;
10641   /* NOTREACHED */
10642   return 0;
10643 #else
10644   clib_warning ("unsupported (no dpdk)");
10645   return -99;
10646 #endif
10647 }
10648
10649 static int
10650 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10651 {
10652 #if DPDK > 0
10653   unformat_input_t *i = vam->input;
10654   vl_api_ipsec_spd_add_del_entry_t *mp;
10655   f64 timeout;
10656   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10657   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10658   i32 priority = 0;
10659   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10660   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10661   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10662   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10663
10664   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10665   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10666   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10667   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10668   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10669   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10670
10671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10672     {
10673       if (unformat (i, "del"))
10674         is_add = 0;
10675       if (unformat (i, "outbound"))
10676         is_outbound = 1;
10677       if (unformat (i, "inbound"))
10678         is_outbound = 0;
10679       else if (unformat (i, "spd_id %d", &spd_id))
10680         ;
10681       else if (unformat (i, "sa_id %d", &sa_id))
10682         ;
10683       else if (unformat (i, "priority %d", &priority))
10684         ;
10685       else if (unformat (i, "protocol %d", &protocol))
10686         ;
10687       else if (unformat (i, "lport_start %d", &lport_start))
10688         ;
10689       else if (unformat (i, "lport_stop %d", &lport_stop))
10690         ;
10691       else if (unformat (i, "rport_start %d", &rport_start))
10692         ;
10693       else if (unformat (i, "rport_stop %d", &rport_stop))
10694         ;
10695       else
10696         if (unformat
10697             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10698         {
10699           is_ipv6 = 0;
10700           is_ip_any = 0;
10701         }
10702       else
10703         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10704         {
10705           is_ipv6 = 0;
10706           is_ip_any = 0;
10707         }
10708       else
10709         if (unformat
10710             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
10711         {
10712           is_ipv6 = 0;
10713           is_ip_any = 0;
10714         }
10715       else
10716         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
10717         {
10718           is_ipv6 = 0;
10719           is_ip_any = 0;
10720         }
10721       else
10722         if (unformat
10723             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
10724         {
10725           is_ipv6 = 1;
10726           is_ip_any = 0;
10727         }
10728       else
10729         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
10730         {
10731           is_ipv6 = 1;
10732           is_ip_any = 0;
10733         }
10734       else
10735         if (unformat
10736             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
10737         {
10738           is_ipv6 = 1;
10739           is_ip_any = 0;
10740         }
10741       else
10742         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
10743         {
10744           is_ipv6 = 1;
10745           is_ip_any = 0;
10746         }
10747       else
10748         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10749         {
10750           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10751             {
10752               clib_warning ("unsupported action: 'resolve'");
10753               return -99;
10754             }
10755         }
10756       else
10757         {
10758           clib_warning ("parse error '%U'", format_unformat_error, i);
10759           return -99;
10760         }
10761
10762     }
10763
10764   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
10765
10766   mp->spd_id = ntohl (spd_id);
10767   mp->priority = ntohl (priority);
10768   mp->is_outbound = is_outbound;
10769
10770   mp->is_ipv6 = is_ipv6;
10771   if (is_ipv6 || is_ip_any)
10772     {
10773       clib_memcpy (mp->remote_address_start, &raddr6_start,
10774                    sizeof (ip6_address_t));
10775       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
10776                    sizeof (ip6_address_t));
10777       clib_memcpy (mp->local_address_start, &laddr6_start,
10778                    sizeof (ip6_address_t));
10779       clib_memcpy (mp->local_address_stop, &laddr6_stop,
10780                    sizeof (ip6_address_t));
10781     }
10782   else
10783     {
10784       clib_memcpy (mp->remote_address_start, &raddr4_start,
10785                    sizeof (ip4_address_t));
10786       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
10787                    sizeof (ip4_address_t));
10788       clib_memcpy (mp->local_address_start, &laddr4_start,
10789                    sizeof (ip4_address_t));
10790       clib_memcpy (mp->local_address_stop, &laddr4_stop,
10791                    sizeof (ip4_address_t));
10792     }
10793   mp->protocol = (u8) protocol;
10794   mp->local_port_start = ntohs ((u16) lport_start);
10795   mp->local_port_stop = ntohs ((u16) lport_stop);
10796   mp->remote_port_start = ntohs ((u16) rport_start);
10797   mp->remote_port_stop = ntohs ((u16) rport_stop);
10798   mp->policy = (u8) policy;
10799   mp->sa_id = ntohl (sa_id);
10800   mp->is_add = is_add;
10801   mp->is_ip_any = is_ip_any;
10802   S;
10803   W;
10804   /* NOTREACHED */
10805   return 0;
10806 #else
10807   clib_warning ("unsupported (no dpdk)");
10808   return -99;
10809 #endif
10810 }
10811
10812 static int
10813 api_ipsec_sad_add_del_entry (vat_main_t * vam)
10814 {
10815 #if DPDK > 0
10816   unformat_input_t *i = vam->input;
10817   vl_api_ipsec_sad_add_del_entry_t *mp;
10818   f64 timeout;
10819   u32 sad_id = 0, spi = 0;
10820   u8 *ck = 0, *ik = 0;
10821   u8 is_add = 1;
10822
10823   u8 protocol = IPSEC_PROTOCOL_AH;
10824   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
10825   u32 crypto_alg = 0, integ_alg = 0;
10826   ip4_address_t tun_src4;
10827   ip4_address_t tun_dst4;
10828   ip6_address_t tun_src6;
10829   ip6_address_t tun_dst6;
10830
10831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10832     {
10833       if (unformat (i, "del"))
10834         is_add = 0;
10835       else if (unformat (i, "sad_id %d", &sad_id))
10836         ;
10837       else if (unformat (i, "spi %d", &spi))
10838         ;
10839       else if (unformat (i, "esp"))
10840         protocol = IPSEC_PROTOCOL_ESP;
10841       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
10842         {
10843           is_tunnel = 1;
10844           is_tunnel_ipv6 = 0;
10845         }
10846       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
10847         {
10848           is_tunnel = 1;
10849           is_tunnel_ipv6 = 0;
10850         }
10851       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
10852         {
10853           is_tunnel = 1;
10854           is_tunnel_ipv6 = 1;
10855         }
10856       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
10857         {
10858           is_tunnel = 1;
10859           is_tunnel_ipv6 = 1;
10860         }
10861       else
10862         if (unformat
10863             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
10864         {
10865           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
10866               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
10867             {
10868               clib_warning ("unsupported crypto-alg: '%U'",
10869                             format_ipsec_crypto_alg, crypto_alg);
10870               return -99;
10871             }
10872         }
10873       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10874         ;
10875       else
10876         if (unformat
10877             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
10878         {
10879           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
10880               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
10881             {
10882               clib_warning ("unsupported integ-alg: '%U'",
10883                             format_ipsec_integ_alg, integ_alg);
10884               return -99;
10885             }
10886         }
10887       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10888         ;
10889       else
10890         {
10891           clib_warning ("parse error '%U'", format_unformat_error, i);
10892           return -99;
10893         }
10894
10895     }
10896
10897   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
10898
10899   mp->sad_id = ntohl (sad_id);
10900   mp->is_add = is_add;
10901   mp->protocol = protocol;
10902   mp->spi = ntohl (spi);
10903   mp->is_tunnel = is_tunnel;
10904   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
10905   mp->crypto_algorithm = crypto_alg;
10906   mp->integrity_algorithm = integ_alg;
10907   mp->crypto_key_length = vec_len (ck);
10908   mp->integrity_key_length = vec_len (ik);
10909
10910   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10911     mp->crypto_key_length = sizeof (mp->crypto_key);
10912
10913   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10914     mp->integrity_key_length = sizeof (mp->integrity_key);
10915
10916   if (ck)
10917     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10918   if (ik)
10919     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10920
10921   if (is_tunnel)
10922     {
10923       if (is_tunnel_ipv6)
10924         {
10925           clib_memcpy (mp->tunnel_src_address, &tun_src6,
10926                        sizeof (ip6_address_t));
10927           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
10928                        sizeof (ip6_address_t));
10929         }
10930       else
10931         {
10932           clib_memcpy (mp->tunnel_src_address, &tun_src4,
10933                        sizeof (ip4_address_t));
10934           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
10935                        sizeof (ip4_address_t));
10936         }
10937     }
10938
10939   S;
10940   W;
10941   /* NOTREACHED */
10942   return 0;
10943 #else
10944   clib_warning ("unsupported (no dpdk)");
10945   return -99;
10946 #endif
10947 }
10948
10949 static int
10950 api_ipsec_sa_set_key (vat_main_t * vam)
10951 {
10952 #if DPDK > 0
10953   unformat_input_t *i = vam->input;
10954   vl_api_ipsec_sa_set_key_t *mp;
10955   f64 timeout;
10956   u32 sa_id;
10957   u8 *ck = 0, *ik = 0;
10958
10959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10960     {
10961       if (unformat (i, "sa_id %d", &sa_id))
10962         ;
10963       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10964         ;
10965       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10966         ;
10967       else
10968         {
10969           clib_warning ("parse error '%U'", format_unformat_error, i);
10970           return -99;
10971         }
10972     }
10973
10974   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
10975
10976   mp->sa_id = ntohl (sa_id);
10977   mp->crypto_key_length = vec_len (ck);
10978   mp->integrity_key_length = vec_len (ik);
10979
10980   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10981     mp->crypto_key_length = sizeof (mp->crypto_key);
10982
10983   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10984     mp->integrity_key_length = sizeof (mp->integrity_key);
10985
10986   if (ck)
10987     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10988   if (ik)
10989     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10990
10991   S;
10992   W;
10993   /* NOTREACHED */
10994   return 0;
10995 #else
10996   clib_warning ("unsupported (no dpdk)");
10997   return -99;
10998 #endif
10999 }
11000
11001 static int
11002 api_ikev2_profile_add_del (vat_main_t * vam)
11003 {
11004 #if DPDK > 0
11005   unformat_input_t *i = vam->input;
11006   vl_api_ikev2_profile_add_del_t *mp;
11007   f64 timeout;
11008   u8 is_add = 1;
11009   u8 *name = 0;
11010
11011   const char *valid_chars = "a-zA-Z0-9_";
11012
11013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11014     {
11015       if (unformat (i, "del"))
11016         is_add = 0;
11017       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11018         vec_add1 (name, 0);
11019       else
11020         {
11021           errmsg ("parse error '%U'", format_unformat_error, i);
11022           return -99;
11023         }
11024     }
11025
11026   if (!vec_len (name))
11027     {
11028       errmsg ("profile name must be specified");
11029       return -99;
11030     }
11031
11032   if (vec_len (name) > 64)
11033     {
11034       errmsg ("profile name too long");
11035       return -99;
11036     }
11037
11038   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11039
11040   clib_memcpy (mp->name, name, vec_len (name));
11041   mp->is_add = is_add;
11042   vec_free (name);
11043
11044   S;
11045   W;
11046   /* NOTREACHED */
11047   return 0;
11048 #else
11049   clib_warning ("unsupported (no dpdk)");
11050   return -99;
11051 #endif
11052 }
11053
11054 static int
11055 api_ikev2_profile_set_auth (vat_main_t * vam)
11056 {
11057 #if DPDK > 0
11058   unformat_input_t *i = vam->input;
11059   vl_api_ikev2_profile_set_auth_t *mp;
11060   f64 timeout;
11061   u8 *name = 0;
11062   u8 *data = 0;
11063   u32 auth_method = 0;
11064   u8 is_hex = 0;
11065
11066   const char *valid_chars = "a-zA-Z0-9_";
11067
11068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11069     {
11070       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11071         vec_add1 (name, 0);
11072       else if (unformat (i, "auth_method %U",
11073                          unformat_ikev2_auth_method, &auth_method))
11074         ;
11075       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11076         is_hex = 1;
11077       else if (unformat (i, "auth_data %v", &data))
11078         ;
11079       else
11080         {
11081           errmsg ("parse error '%U'", format_unformat_error, i);
11082           return -99;
11083         }
11084     }
11085
11086   if (!vec_len (name))
11087     {
11088       errmsg ("profile name must be specified");
11089       return -99;
11090     }
11091
11092   if (vec_len (name) > 64)
11093     {
11094       errmsg ("profile name too long");
11095       return -99;
11096     }
11097
11098   if (!vec_len (data))
11099     {
11100       errmsg ("auth_data must be specified");
11101       return -99;
11102     }
11103
11104   if (!auth_method)
11105     {
11106       errmsg ("auth_method must be specified");
11107       return -99;
11108     }
11109
11110   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11111
11112   mp->is_hex = is_hex;
11113   mp->auth_method = (u8) auth_method;
11114   mp->data_len = vec_len (data);
11115   clib_memcpy (mp->name, name, vec_len (name));
11116   clib_memcpy (mp->data, data, vec_len (data));
11117   vec_free (name);
11118   vec_free (data);
11119
11120   S;
11121   W;
11122   /* NOTREACHED */
11123   return 0;
11124 #else
11125   clib_warning ("unsupported (no dpdk)");
11126   return -99;
11127 #endif
11128 }
11129
11130 static int
11131 api_ikev2_profile_set_id (vat_main_t * vam)
11132 {
11133 #if DPDK > 0
11134   unformat_input_t *i = vam->input;
11135   vl_api_ikev2_profile_set_id_t *mp;
11136   f64 timeout;
11137   u8 *name = 0;
11138   u8 *data = 0;
11139   u8 is_local = 0;
11140   u32 id_type = 0;
11141   ip4_address_t ip4;
11142
11143   const char *valid_chars = "a-zA-Z0-9_";
11144
11145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11146     {
11147       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11148         vec_add1 (name, 0);
11149       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11150         ;
11151       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11152         {
11153           data = vec_new (u8, 4);
11154           clib_memcpy (data, ip4.as_u8, 4);
11155         }
11156       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11157         ;
11158       else if (unformat (i, "id_data %v", &data))
11159         ;
11160       else if (unformat (i, "local"))
11161         is_local = 1;
11162       else if (unformat (i, "remote"))
11163         is_local = 0;
11164       else
11165         {
11166           errmsg ("parse error '%U'", format_unformat_error, i);
11167           return -99;
11168         }
11169     }
11170
11171   if (!vec_len (name))
11172     {
11173       errmsg ("profile name must be specified");
11174       return -99;
11175     }
11176
11177   if (vec_len (name) > 64)
11178     {
11179       errmsg ("profile name too long");
11180       return -99;
11181     }
11182
11183   if (!vec_len (data))
11184     {
11185       errmsg ("id_data must be specified");
11186       return -99;
11187     }
11188
11189   if (!id_type)
11190     {
11191       errmsg ("id_type must be specified");
11192       return -99;
11193     }
11194
11195   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11196
11197   mp->is_local = is_local;
11198   mp->id_type = (u8) id_type;
11199   mp->data_len = vec_len (data);
11200   clib_memcpy (mp->name, name, vec_len (name));
11201   clib_memcpy (mp->data, data, vec_len (data));
11202   vec_free (name);
11203   vec_free (data);
11204
11205   S;
11206   W;
11207   /* NOTREACHED */
11208   return 0;
11209 #else
11210   clib_warning ("unsupported (no dpdk)");
11211   return -99;
11212 #endif
11213 }
11214
11215 static int
11216 api_ikev2_profile_set_ts (vat_main_t * vam)
11217 {
11218 #if DPDK > 0
11219   unformat_input_t *i = vam->input;
11220   vl_api_ikev2_profile_set_ts_t *mp;
11221   f64 timeout;
11222   u8 *name = 0;
11223   u8 is_local = 0;
11224   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11225   ip4_address_t start_addr, end_addr;
11226
11227   const char *valid_chars = "a-zA-Z0-9_";
11228
11229   start_addr.as_u32 = 0;
11230   end_addr.as_u32 = (u32) ~ 0;
11231
11232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11233     {
11234       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11235         vec_add1 (name, 0);
11236       else if (unformat (i, "protocol %d", &proto))
11237         ;
11238       else if (unformat (i, "start_port %d", &start_port))
11239         ;
11240       else if (unformat (i, "end_port %d", &end_port))
11241         ;
11242       else
11243         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11244         ;
11245       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11246         ;
11247       else if (unformat (i, "local"))
11248         is_local = 1;
11249       else if (unformat (i, "remote"))
11250         is_local = 0;
11251       else
11252         {
11253           errmsg ("parse error '%U'", format_unformat_error, i);
11254           return -99;
11255         }
11256     }
11257
11258   if (!vec_len (name))
11259     {
11260       errmsg ("profile name must be specified");
11261       return -99;
11262     }
11263
11264   if (vec_len (name) > 64)
11265     {
11266       errmsg ("profile name too long");
11267       return -99;
11268     }
11269
11270   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11271
11272   mp->is_local = is_local;
11273   mp->proto = (u8) proto;
11274   mp->start_port = (u16) start_port;
11275   mp->end_port = (u16) end_port;
11276   mp->start_addr = start_addr.as_u32;
11277   mp->end_addr = end_addr.as_u32;
11278   clib_memcpy (mp->name, name, vec_len (name));
11279   vec_free (name);
11280
11281   S;
11282   W;
11283   /* NOTREACHED */
11284   return 0;
11285 #else
11286   clib_warning ("unsupported (no dpdk)");
11287   return -99;
11288 #endif
11289 }
11290
11291 static int
11292 api_ikev2_set_local_key (vat_main_t * vam)
11293 {
11294 #if DPDK > 0
11295   unformat_input_t *i = vam->input;
11296   vl_api_ikev2_set_local_key_t *mp;
11297   f64 timeout;
11298   u8 *file = 0;
11299
11300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11301     {
11302       if (unformat (i, "file %v", &file))
11303         vec_add1 (file, 0);
11304       else
11305         {
11306           errmsg ("parse error '%U'", format_unformat_error, i);
11307           return -99;
11308         }
11309     }
11310
11311   if (!vec_len (file))
11312     {
11313       errmsg ("RSA key file must be specified");
11314       return -99;
11315     }
11316
11317   if (vec_len (file) > 256)
11318     {
11319       errmsg ("file name too long");
11320       return -99;
11321     }
11322
11323   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11324
11325   clib_memcpy (mp->key_file, file, vec_len (file));
11326   vec_free (file);
11327
11328   S;
11329   W;
11330   /* NOTREACHED */
11331   return 0;
11332 #else
11333   clib_warning ("unsupported (no dpdk)");
11334   return -99;
11335 #endif
11336 }
11337
11338 /*
11339  * MAP
11340  */
11341 static int
11342 api_map_add_domain (vat_main_t * vam)
11343 {
11344   unformat_input_t *i = vam->input;
11345   vl_api_map_add_domain_t *mp;
11346   f64 timeout;
11347
11348   ip4_address_t ip4_prefix;
11349   ip6_address_t ip6_prefix;
11350   ip6_address_t ip6_src;
11351   u32 num_m_args = 0;
11352   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11353     0, psid_length = 0;
11354   u8 is_translation = 0;
11355   u32 mtu = 0;
11356   u32 ip6_src_len = 128;
11357
11358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11359     {
11360       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11361                     &ip4_prefix, &ip4_prefix_len))
11362         num_m_args++;
11363       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11364                          &ip6_prefix, &ip6_prefix_len))
11365         num_m_args++;
11366       else
11367         if (unformat
11368             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11369              &ip6_src_len))
11370         num_m_args++;
11371       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11372         num_m_args++;
11373       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11374         num_m_args++;
11375       else if (unformat (i, "psid-offset %d", &psid_offset))
11376         num_m_args++;
11377       else if (unformat (i, "psid-len %d", &psid_length))
11378         num_m_args++;
11379       else if (unformat (i, "mtu %d", &mtu))
11380         num_m_args++;
11381       else if (unformat (i, "map-t"))
11382         is_translation = 1;
11383       else
11384         {
11385           clib_warning ("parse error '%U'", format_unformat_error, i);
11386           return -99;
11387         }
11388     }
11389
11390   if (num_m_args < 3)
11391     {
11392       errmsg ("mandatory argument(s) missing\n");
11393       return -99;
11394     }
11395
11396   /* Construct the API message */
11397   M (MAP_ADD_DOMAIN, map_add_domain);
11398
11399   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11400   mp->ip4_prefix_len = ip4_prefix_len;
11401
11402   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11403   mp->ip6_prefix_len = ip6_prefix_len;
11404
11405   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11406   mp->ip6_src_prefix_len = ip6_src_len;
11407
11408   mp->ea_bits_len = ea_bits_len;
11409   mp->psid_offset = psid_offset;
11410   mp->psid_length = psid_length;
11411   mp->is_translation = is_translation;
11412   mp->mtu = htons (mtu);
11413
11414   /* send it... */
11415   S;
11416
11417   /* Wait for a reply, return good/bad news  */
11418   W;
11419 }
11420
11421 static int
11422 api_map_del_domain (vat_main_t * vam)
11423 {
11424   unformat_input_t *i = vam->input;
11425   vl_api_map_del_domain_t *mp;
11426   f64 timeout;
11427
11428   u32 num_m_args = 0;
11429   u32 index;
11430
11431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11432     {
11433       if (unformat (i, "index %d", &index))
11434         num_m_args++;
11435       else
11436         {
11437           clib_warning ("parse error '%U'", format_unformat_error, i);
11438           return -99;
11439         }
11440     }
11441
11442   if (num_m_args != 1)
11443     {
11444       errmsg ("mandatory argument(s) missing\n");
11445       return -99;
11446     }
11447
11448   /* Construct the API message */
11449   M (MAP_DEL_DOMAIN, map_del_domain);
11450
11451   mp->index = ntohl (index);
11452
11453   /* send it... */
11454   S;
11455
11456   /* Wait for a reply, return good/bad news  */
11457   W;
11458 }
11459
11460 static int
11461 api_map_add_del_rule (vat_main_t * vam)
11462 {
11463   unformat_input_t *i = vam->input;
11464   vl_api_map_add_del_rule_t *mp;
11465   f64 timeout;
11466   u8 is_add = 1;
11467   ip6_address_t ip6_dst;
11468   u32 num_m_args = 0, index, psid = 0;
11469
11470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11471     {
11472       if (unformat (i, "index %d", &index))
11473         num_m_args++;
11474       else if (unformat (i, "psid %d", &psid))
11475         num_m_args++;
11476       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11477         num_m_args++;
11478       else if (unformat (i, "del"))
11479         {
11480           is_add = 0;
11481         }
11482       else
11483         {
11484           clib_warning ("parse error '%U'", format_unformat_error, i);
11485           return -99;
11486         }
11487     }
11488
11489   /* Construct the API message */
11490   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11491
11492   mp->index = ntohl (index);
11493   mp->is_add = is_add;
11494   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11495   mp->psid = ntohs (psid);
11496
11497   /* send it... */
11498   S;
11499
11500   /* Wait for a reply, return good/bad news  */
11501   W;
11502 }
11503
11504 static int
11505 api_map_domain_dump (vat_main_t * vam)
11506 {
11507   vl_api_map_domain_dump_t *mp;
11508   f64 timeout;
11509
11510   /* Construct the API message */
11511   M (MAP_DOMAIN_DUMP, map_domain_dump);
11512
11513   /* send it... */
11514   S;
11515
11516   /* Use a control ping for synchronization */
11517   {
11518     vl_api_control_ping_t *mp;
11519     M (CONTROL_PING, control_ping);
11520     S;
11521   }
11522   W;
11523 }
11524
11525 static int
11526 api_map_rule_dump (vat_main_t * vam)
11527 {
11528   unformat_input_t *i = vam->input;
11529   vl_api_map_rule_dump_t *mp;
11530   f64 timeout;
11531   u32 domain_index = ~0;
11532
11533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11534     {
11535       if (unformat (i, "index %u", &domain_index))
11536         ;
11537       else
11538         break;
11539     }
11540
11541   if (domain_index == ~0)
11542     {
11543       clib_warning ("parse error: domain index expected");
11544       return -99;
11545     }
11546
11547   /* Construct the API message */
11548   M (MAP_RULE_DUMP, map_rule_dump);
11549
11550   mp->domain_index = htonl (domain_index);
11551
11552   /* send it... */
11553   S;
11554
11555   /* Use a control ping for synchronization */
11556   {
11557     vl_api_control_ping_t *mp;
11558     M (CONTROL_PING, control_ping);
11559     S;
11560   }
11561   W;
11562 }
11563
11564 static void vl_api_map_add_domain_reply_t_handler
11565   (vl_api_map_add_domain_reply_t * mp)
11566 {
11567   vat_main_t *vam = &vat_main;
11568   i32 retval = ntohl (mp->retval);
11569
11570   if (vam->async_mode)
11571     {
11572       vam->async_errors += (retval < 0);
11573     }
11574   else
11575     {
11576       vam->retval = retval;
11577       vam->result_ready = 1;
11578     }
11579 }
11580
11581 static void vl_api_map_add_domain_reply_t_handler_json
11582   (vl_api_map_add_domain_reply_t * mp)
11583 {
11584   vat_main_t *vam = &vat_main;
11585   vat_json_node_t node;
11586
11587   vat_json_init_object (&node);
11588   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11589   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11590
11591   vat_json_print (vam->ofp, &node);
11592   vat_json_free (&node);
11593
11594   vam->retval = ntohl (mp->retval);
11595   vam->result_ready = 1;
11596 }
11597
11598 static int
11599 api_get_first_msg_id (vat_main_t * vam)
11600 {
11601   vl_api_get_first_msg_id_t *mp;
11602   f64 timeout;
11603   unformat_input_t *i = vam->input;
11604   u8 *name;
11605   u8 name_set = 0;
11606
11607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11608     {
11609       if (unformat (i, "client %s", &name))
11610         name_set = 1;
11611       else
11612         break;
11613     }
11614
11615   if (name_set == 0)
11616     {
11617       errmsg ("missing client name\n");
11618       return -99;
11619     }
11620   vec_add1 (name, 0);
11621
11622   if (vec_len (name) > 63)
11623     {
11624       errmsg ("client name too long\n");
11625       return -99;
11626     }
11627
11628   M (GET_FIRST_MSG_ID, get_first_msg_id);
11629   clib_memcpy (mp->name, name, vec_len (name));
11630   S;
11631   W;
11632   /* NOTREACHED */
11633   return 0;
11634 }
11635
11636 static int
11637 api_cop_interface_enable_disable (vat_main_t * vam)
11638 {
11639   unformat_input_t *line_input = vam->input;
11640   vl_api_cop_interface_enable_disable_t *mp;
11641   f64 timeout;
11642   u32 sw_if_index = ~0;
11643   u8 enable_disable = 1;
11644
11645   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11646     {
11647       if (unformat (line_input, "disable"))
11648         enable_disable = 0;
11649       if (unformat (line_input, "enable"))
11650         enable_disable = 1;
11651       else if (unformat (line_input, "%U", unformat_sw_if_index,
11652                          vam, &sw_if_index))
11653         ;
11654       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11655         ;
11656       else
11657         break;
11658     }
11659
11660   if (sw_if_index == ~0)
11661     {
11662       errmsg ("missing interface name or sw_if_index\n");
11663       return -99;
11664     }
11665
11666   /* Construct the API message */
11667   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11668   mp->sw_if_index = ntohl (sw_if_index);
11669   mp->enable_disable = enable_disable;
11670
11671   /* send it... */
11672   S;
11673   /* Wait for the reply */
11674   W;
11675 }
11676
11677 static int
11678 api_cop_whitelist_enable_disable (vat_main_t * vam)
11679 {
11680   unformat_input_t *line_input = vam->input;
11681   vl_api_cop_whitelist_enable_disable_t *mp;
11682   f64 timeout;
11683   u32 sw_if_index = ~0;
11684   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11685   u32 fib_id = 0;
11686
11687   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11688     {
11689       if (unformat (line_input, "ip4"))
11690         ip4 = 1;
11691       else if (unformat (line_input, "ip6"))
11692         ip6 = 1;
11693       else if (unformat (line_input, "default"))
11694         default_cop = 1;
11695       else if (unformat (line_input, "%U", unformat_sw_if_index,
11696                          vam, &sw_if_index))
11697         ;
11698       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11699         ;
11700       else if (unformat (line_input, "fib-id %d", &fib_id))
11701         ;
11702       else
11703         break;
11704     }
11705
11706   if (sw_if_index == ~0)
11707     {
11708       errmsg ("missing interface name or sw_if_index\n");
11709       return -99;
11710     }
11711
11712   /* Construct the API message */
11713   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
11714   mp->sw_if_index = ntohl (sw_if_index);
11715   mp->fib_id = ntohl (fib_id);
11716   mp->ip4 = ip4;
11717   mp->ip6 = ip6;
11718   mp->default_cop = default_cop;
11719
11720   /* send it... */
11721   S;
11722   /* Wait for the reply */
11723   W;
11724 }
11725
11726 static int
11727 api_get_node_graph (vat_main_t * vam)
11728 {
11729   vl_api_get_node_graph_t *mp;
11730   f64 timeout;
11731
11732   M (GET_NODE_GRAPH, get_node_graph);
11733
11734   /* send it... */
11735   S;
11736   /* Wait for the reply */
11737   W;
11738 }
11739
11740 /* *INDENT-OFF* */
11741 /** Used for parsing LISP eids */
11742 typedef CLIB_PACKED(struct{
11743   u8 addr[16];   /**< eid address */
11744   u32 len;       /**< prefix length if IP */
11745   u8 type;      /**< type of eid */
11746 }) lisp_eid_vat_t;
11747 /* *INDENT-ON* */
11748
11749 static uword
11750 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
11751 {
11752   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
11753
11754   memset (a, 0, sizeof (a[0]));
11755
11756   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
11757     {
11758       a->type = 0;              /* ipv4 type */
11759     }
11760   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
11761     {
11762       a->type = 1;              /* ipv6 type */
11763     }
11764   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
11765     {
11766       a->type = 2;              /* mac type */
11767     }
11768   else
11769     {
11770       return 0;
11771     }
11772
11773   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
11774     {
11775       return 0;
11776     }
11777
11778   return 1;
11779 }
11780
11781 static int
11782 lisp_eid_size_vat (u8 type)
11783 {
11784   switch (type)
11785     {
11786     case 0:
11787       return 4;
11788     case 1:
11789       return 16;
11790     case 2:
11791       return 6;
11792     }
11793   return 0;
11794 }
11795
11796 static void
11797 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
11798 {
11799   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
11800 }
11801
11802 /* *INDENT-OFF* */
11803 /** Used for transferring locators via VPP API */
11804 typedef CLIB_PACKED(struct
11805 {
11806   u32 sw_if_index; /**< locator sw_if_index */
11807   u8 priority; /**< locator priority */
11808   u8 weight;   /**< locator weight */
11809 }) ls_locator_t;
11810 /* *INDENT-ON* */
11811
11812 static int
11813 api_lisp_add_del_locator_set (vat_main_t * vam)
11814 {
11815   unformat_input_t *input = vam->input;
11816   vl_api_lisp_add_del_locator_set_t *mp;
11817   f64 timeout = ~0;
11818   u8 is_add = 1;
11819   u8 *locator_set_name = NULL;
11820   u8 locator_set_name_set = 0;
11821   ls_locator_t locator, *locators = 0;
11822   u32 sw_if_index, priority, weight;
11823
11824   /* Parse args required to build the message */
11825   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11826     {
11827       if (unformat (input, "del"))
11828         {
11829           is_add = 0;
11830         }
11831       else if (unformat (input, "locator-set %s", &locator_set_name))
11832         {
11833           locator_set_name_set = 1;
11834         }
11835       else if (unformat (input, "sw_if_index %u p %u w %u",
11836                          &sw_if_index, &priority, &weight))
11837         {
11838           locator.sw_if_index = htonl (sw_if_index);
11839           locator.priority = priority;
11840           locator.weight = weight;
11841           vec_add1 (locators, locator);
11842         }
11843       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
11844                          vam, &sw_if_index, &priority, &weight))
11845         {
11846           locator.sw_if_index = htonl (sw_if_index);
11847           locator.priority = priority;
11848           locator.weight = weight;
11849           vec_add1 (locators, locator);
11850         }
11851       else
11852         break;
11853     }
11854
11855   if (locator_set_name_set == 0)
11856     {
11857       errmsg ("missing locator-set name");
11858       vec_free (locators);
11859       return -99;
11860     }
11861
11862   if (vec_len (locator_set_name) > 64)
11863     {
11864       errmsg ("locator-set name too long\n");
11865       vec_free (locator_set_name);
11866       vec_free (locators);
11867       return -99;
11868     }
11869   vec_add1 (locator_set_name, 0);
11870
11871   /* Construct the API message */
11872   M (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
11873
11874   mp->is_add = is_add;
11875   clib_memcpy (mp->locator_set_name, locator_set_name,
11876                vec_len (locator_set_name));
11877   vec_free (locator_set_name);
11878
11879   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
11880   if (locators)
11881     clib_memcpy (mp->locators, locators,
11882                  (sizeof (ls_locator_t) * vec_len (locators)));
11883   vec_free (locators);
11884
11885   /* send it... */
11886   S;
11887
11888   /* Wait for a reply... */
11889   W;
11890
11891   /* NOTREACHED */
11892   return 0;
11893 }
11894
11895 static int
11896 api_lisp_add_del_locator (vat_main_t * vam)
11897 {
11898   unformat_input_t *input = vam->input;
11899   vl_api_lisp_add_del_locator_t *mp;
11900   f64 timeout = ~0;
11901   u32 tmp_if_index = ~0;
11902   u32 sw_if_index = ~0;
11903   u8 sw_if_index_set = 0;
11904   u8 sw_if_index_if_name_set = 0;
11905   u32 priority = ~0;
11906   u8 priority_set = 0;
11907   u32 weight = ~0;
11908   u8 weight_set = 0;
11909   u8 is_add = 1;
11910   u8 *locator_set_name = NULL;
11911   u8 locator_set_name_set = 0;
11912
11913   /* Parse args required to build the message */
11914   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11915     {
11916       if (unformat (input, "del"))
11917         {
11918           is_add = 0;
11919         }
11920       else if (unformat (input, "locator-set %s", &locator_set_name))
11921         {
11922           locator_set_name_set = 1;
11923         }
11924       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
11925                          &tmp_if_index))
11926         {
11927           sw_if_index_if_name_set = 1;
11928           sw_if_index = tmp_if_index;
11929         }
11930       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
11931         {
11932           sw_if_index_set = 1;
11933           sw_if_index = tmp_if_index;
11934         }
11935       else if (unformat (input, "p %d", &priority))
11936         {
11937           priority_set = 1;
11938         }
11939       else if (unformat (input, "w %d", &weight))
11940         {
11941           weight_set = 1;
11942         }
11943       else
11944         break;
11945     }
11946
11947   if (locator_set_name_set == 0)
11948     {
11949       errmsg ("missing locator-set name");
11950       return -99;
11951     }
11952
11953   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
11954     {
11955       errmsg ("missing sw_if_index");
11956       vec_free (locator_set_name);
11957       return -99;
11958     }
11959
11960   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
11961     {
11962       errmsg ("cannot use both params interface name and sw_if_index");
11963       vec_free (locator_set_name);
11964       return -99;
11965     }
11966
11967   if (priority_set == 0)
11968     {
11969       errmsg ("missing locator-set priority\n");
11970       vec_free (locator_set_name);
11971       return -99;
11972     }
11973
11974   if (weight_set == 0)
11975     {
11976       errmsg ("missing locator-set weight\n");
11977       vec_free (locator_set_name);
11978       return -99;
11979     }
11980
11981   if (vec_len (locator_set_name) > 64)
11982     {
11983       errmsg ("locator-set name too long\n");
11984       vec_free (locator_set_name);
11985       return -99;
11986     }
11987   vec_add1 (locator_set_name, 0);
11988
11989   /* Construct the API message */
11990   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
11991
11992   mp->is_add = is_add;
11993   mp->sw_if_index = ntohl (sw_if_index);
11994   mp->priority = priority;
11995   mp->weight = weight;
11996   clib_memcpy (mp->locator_set_name, locator_set_name,
11997                vec_len (locator_set_name));
11998   vec_free (locator_set_name);
11999
12000   /* send it... */
12001   S;
12002
12003   /* Wait for a reply... */
12004   W;
12005
12006   /* NOTREACHED */
12007   return 0;
12008 }
12009
12010 static int
12011 api_lisp_add_del_local_eid (vat_main_t * vam)
12012 {
12013   unformat_input_t *input = vam->input;
12014   vl_api_lisp_add_del_local_eid_t *mp;
12015   f64 timeout = ~0;
12016   u8 is_add = 1;
12017   u8 eid_set = 0;
12018   lisp_eid_vat_t _eid, *eid = &_eid;
12019   u8 *locator_set_name = 0;
12020   u8 locator_set_name_set = 0;
12021   u32 vni = 0;
12022
12023   /* Parse args required to build the message */
12024   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12025     {
12026       if (unformat (input, "del"))
12027         {
12028           is_add = 0;
12029         }
12030       else if (unformat (input, "vni %d", &vni))
12031         {
12032           ;
12033         }
12034       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12035         {
12036           eid_set = 1;
12037         }
12038       else if (unformat (input, "locator-set %s", &locator_set_name))
12039         {
12040           locator_set_name_set = 1;
12041         }
12042       else
12043         break;
12044     }
12045
12046   if (locator_set_name_set == 0)
12047     {
12048       errmsg ("missing locator-set name\n");
12049       return -99;
12050     }
12051
12052   if (0 == eid_set)
12053     {
12054       errmsg ("EID address not set!");
12055       vec_free (locator_set_name);
12056       return -99;
12057     }
12058
12059   if (vec_len (locator_set_name) > 64)
12060     {
12061       errmsg ("locator-set name too long\n");
12062       vec_free (locator_set_name);
12063       return -99;
12064     }
12065   vec_add1 (locator_set_name, 0);
12066
12067   /* Construct the API message */
12068   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12069
12070   mp->is_add = is_add;
12071   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12072   mp->eid_type = eid->type;
12073   mp->prefix_len = eid->len;
12074   mp->vni = clib_host_to_net_u32 (vni);
12075   clib_memcpy (mp->locator_set_name, locator_set_name,
12076                vec_len (locator_set_name));
12077
12078   vec_free (locator_set_name);
12079
12080   /* send it... */
12081   S;
12082
12083   /* Wait for a reply... */
12084   W;
12085
12086   /* NOTREACHED */
12087   return 0;
12088 }
12089
12090 /* *INDENT-OFF* */
12091 /** Used for transferring locators via VPP API */
12092 typedef CLIB_PACKED(struct
12093 {
12094   u8 is_ip4; /**< is locator an IPv4 address? */
12095   u8 priority; /**< locator priority */
12096   u8 weight;   /**< locator weight */
12097   u8 addr[16]; /**< IPv4/IPv6 address */
12098 }) rloc_t;
12099 /* *INDENT-ON* */
12100
12101 static int
12102 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12103 {
12104   unformat_input_t *input = vam->input;
12105   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12106   f64 timeout = ~0;
12107   u8 is_add = 1;
12108   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12109   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12110   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12111   u32 action = ~0, p, w;
12112   ip4_address_t rmt_rloc4, lcl_rloc4;
12113   ip6_address_t rmt_rloc6, lcl_rloc6;
12114   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12115
12116   memset (&rloc, 0, sizeof (rloc));
12117
12118   /* Parse args required to build the message */
12119   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12120     {
12121       if (unformat (input, "del"))
12122         {
12123           is_add = 0;
12124         }
12125       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12126         {
12127           rmt_eid_set = 1;
12128         }
12129       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12130         {
12131           lcl_eid_set = 1;
12132         }
12133       else if (unformat (input, "p %d w %d", &p, &w))
12134         {
12135           if (!curr_rloc)
12136             {
12137               errmsg ("No RLOC configured for setting priority/weight!");
12138               return -99;
12139             }
12140           curr_rloc->priority = p;
12141           curr_rloc->weight = w;
12142         }
12143       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12144                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12145         {
12146           rloc.is_ip4 = 1;
12147
12148           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12149           rloc.priority = rloc.weight = 0;
12150           vec_add1 (lcl_locs, rloc);
12151
12152           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12153           vec_add1 (rmt_locs, rloc);
12154           /* priority and weight saved in rmt loc */
12155           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12156         }
12157       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12158                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12159         {
12160           rloc.is_ip4 = 0;
12161           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12162           rloc.priority = rloc.weight = 0;
12163           vec_add1 (lcl_locs, rloc);
12164
12165           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12166           vec_add1 (rmt_locs, rloc);
12167           /* priority and weight saved in rmt loc */
12168           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12169         }
12170       else if (unformat (input, "action %d", &action))
12171         {
12172           ;
12173         }
12174       else
12175         {
12176           clib_warning ("parse error '%U'", format_unformat_error, input);
12177           return -99;
12178         }
12179     }
12180
12181   if (!rmt_eid_set)
12182     {
12183       errmsg ("remote eid addresses not set\n");
12184       return -99;
12185     }
12186
12187   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12188     {
12189       errmsg ("eid types don't match\n");
12190       return -99;
12191     }
12192
12193   if (0 == rmt_locs && (u32) ~ 0 == action)
12194     {
12195       errmsg ("action not set for negative mapping\n");
12196       return -99;
12197     }
12198
12199   /* Construct the API message */
12200   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12201
12202   mp->is_add = is_add;
12203   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12204   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12205   mp->eid_type = rmt_eid->type;
12206   mp->rmt_len = rmt_eid->len;
12207   mp->lcl_len = lcl_eid->len;
12208   mp->action = action;
12209
12210   if (0 != rmt_locs && 0 != lcl_locs)
12211     {
12212       mp->loc_num = vec_len (rmt_locs);
12213       clib_memcpy (mp->lcl_locs, lcl_locs,
12214                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12215       clib_memcpy (mp->rmt_locs, rmt_locs,
12216                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12217     }
12218   vec_free (lcl_locs);
12219   vec_free (rmt_locs);
12220
12221   /* send it... */
12222   S;
12223
12224   /* Wait for a reply... */
12225   W;
12226
12227   /* NOTREACHED */
12228   return 0;
12229 }
12230
12231 static int
12232 api_lisp_add_del_map_resolver (vat_main_t * vam)
12233 {
12234   unformat_input_t *input = vam->input;
12235   vl_api_lisp_add_del_map_resolver_t *mp;
12236   f64 timeout = ~0;
12237   u8 is_add = 1;
12238   u8 ipv4_set = 0;
12239   u8 ipv6_set = 0;
12240   ip4_address_t ipv4;
12241   ip6_address_t ipv6;
12242
12243   /* Parse args required to build the message */
12244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12245     {
12246       if (unformat (input, "del"))
12247         {
12248           is_add = 0;
12249         }
12250       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12251         {
12252           ipv4_set = 1;
12253         }
12254       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12255         {
12256           ipv6_set = 1;
12257         }
12258       else
12259         break;
12260     }
12261
12262   if (ipv4_set && ipv6_set)
12263     {
12264       errmsg ("both eid v4 and v6 addresses set\n");
12265       return -99;
12266     }
12267
12268   if (!ipv4_set && !ipv6_set)
12269     {
12270       errmsg ("eid addresses not set\n");
12271       return -99;
12272     }
12273
12274   /* Construct the API message */
12275   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12276
12277   mp->is_add = is_add;
12278   if (ipv6_set)
12279     {
12280       mp->is_ipv6 = 1;
12281       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12282     }
12283   else
12284     {
12285       mp->is_ipv6 = 0;
12286       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12287     }
12288
12289   /* send it... */
12290   S;
12291
12292   /* Wait for a reply... */
12293   W;
12294
12295   /* NOTREACHED */
12296   return 0;
12297 }
12298
12299 static int
12300 api_lisp_gpe_enable_disable (vat_main_t * vam)
12301 {
12302   unformat_input_t *input = vam->input;
12303   vl_api_lisp_gpe_enable_disable_t *mp;
12304   f64 timeout = ~0;
12305   u8 is_set = 0;
12306   u8 is_en = 1;
12307
12308   /* Parse args required to build the message */
12309   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12310     {
12311       if (unformat (input, "enable"))
12312         {
12313           is_set = 1;
12314           is_en = 1;
12315         }
12316       else if (unformat (input, "disable"))
12317         {
12318           is_set = 1;
12319           is_en = 0;
12320         }
12321       else
12322         break;
12323     }
12324
12325   if (is_set == 0)
12326     {
12327       errmsg ("Value not set\n");
12328       return -99;
12329     }
12330
12331   /* Construct the API message */
12332   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12333
12334   mp->is_en = is_en;
12335
12336   /* send it... */
12337   S;
12338
12339   /* Wait for a reply... */
12340   W;
12341
12342   /* NOTREACHED */
12343   return 0;
12344 }
12345
12346 static int
12347 api_lisp_enable_disable (vat_main_t * vam)
12348 {
12349   unformat_input_t *input = vam->input;
12350   vl_api_lisp_enable_disable_t *mp;
12351   f64 timeout = ~0;
12352   u8 is_set = 0;
12353   u8 is_en = 0;
12354
12355   /* Parse args required to build the message */
12356   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12357     {
12358       if (unformat (input, "enable"))
12359         {
12360           is_set = 1;
12361           is_en = 1;
12362         }
12363       else if (unformat (input, "disable"))
12364         {
12365           is_set = 1;
12366         }
12367       else
12368         break;
12369     }
12370
12371   if (!is_set)
12372     {
12373       errmsg ("Value not set\n");
12374       return -99;
12375     }
12376
12377   /* Construct the API message */
12378   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12379
12380   mp->is_en = is_en;
12381
12382   /* send it... */
12383   S;
12384
12385   /* Wait for a reply... */
12386   W;
12387
12388   /* NOTREACHED */
12389   return 0;
12390 }
12391
12392 /**
12393  * Enable/disable LISP proxy ITR.
12394  *
12395  * @param vam vpp API test context
12396  * @return return code
12397  */
12398 static int
12399 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12400 {
12401   f64 timeout = ~0;
12402   u8 ls_name_set = 0;
12403   unformat_input_t *input = vam->input;
12404   vl_api_lisp_pitr_set_locator_set_t *mp;
12405   u8 is_add = 1;
12406   u8 *ls_name = 0;
12407
12408   /* Parse args required to build the message */
12409   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12410     {
12411       if (unformat (input, "del"))
12412         is_add = 0;
12413       else if (unformat (input, "locator-set %s", &ls_name))
12414         ls_name_set = 1;
12415       else
12416         {
12417           errmsg ("parse error '%U'", format_unformat_error, input);
12418           return -99;
12419         }
12420     }
12421
12422   if (!ls_name_set)
12423     {
12424       errmsg ("locator-set name not set!");
12425       return -99;
12426     }
12427
12428   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12429
12430   mp->is_add = is_add;
12431   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12432   vec_free (ls_name);
12433
12434   /* send */
12435   S;
12436
12437   /* wait for reply */
12438   W;
12439
12440   /* notreached */
12441   return 0;
12442 }
12443
12444 static int
12445 api_show_lisp_pitr (vat_main_t * vam)
12446 {
12447   vl_api_show_lisp_pitr_t *mp;
12448   f64 timeout = ~0;
12449
12450   if (!vam->json_output)
12451     {
12452       fformat (vam->ofp, "%=20s\n", "lisp status:");
12453     }
12454
12455   M (SHOW_LISP_PITR, show_lisp_pitr);
12456   /* send it... */
12457   S;
12458
12459   /* Wait for a reply... */
12460   W;
12461
12462   /* NOTREACHED */
12463   return 0;
12464 }
12465
12466 /**
12467  * Add/delete mapping between vni and vrf
12468  */
12469 static int
12470 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12471 {
12472   f64 timeout = ~0;
12473   unformat_input_t *input = vam->input;
12474   vl_api_lisp_eid_table_add_del_map_t *mp;
12475   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12476   u32 vni, vrf, bd_index;
12477
12478   /* Parse args required to build the message */
12479   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12480     {
12481       if (unformat (input, "del"))
12482         is_add = 0;
12483       else if (unformat (input, "vrf %d", &vrf))
12484         vrf_set = 1;
12485       else if (unformat (input, "bd_index %d", &bd_index))
12486         bd_index_set = 1;
12487       else if (unformat (input, "vni %d", &vni))
12488         vni_set = 1;
12489       else
12490         break;
12491     }
12492
12493   if (!vni_set || (!vrf_set && !bd_index_set))
12494     {
12495       errmsg ("missing arguments!");
12496       return -99;
12497     }
12498
12499   if (vrf_set && bd_index_set)
12500     {
12501       errmsg ("error: both vrf and bd entered!");
12502       return -99;
12503     }
12504
12505   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12506
12507   mp->is_add = is_add;
12508   mp->vni = htonl (vni);
12509   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
12510   mp->is_l2 = bd_index_set;
12511
12512   /* send */
12513   S;
12514
12515   /* wait for reply */
12516   W;
12517
12518   /* notreached */
12519   return 0;
12520 }
12521
12522 /**
12523  * Add/del remote mapping to/from LISP control plane
12524  *
12525  * @param vam vpp API test context
12526  * @return return code
12527  */
12528 static int
12529 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12530 {
12531   unformat_input_t *input = vam->input;
12532   vl_api_lisp_add_del_remote_mapping_t *mp;
12533   f64 timeout = ~0;
12534   u32 vni = 0;
12535   //TODO: seid need remove
12536   lisp_eid_vat_t _eid, *eid = &_eid;
12537   lisp_eid_vat_t _seid, *seid = &_seid;
12538   u8 is_add = 1, del_all = 0, eid_set = 0;
12539   u32 action = ~0, p, w;
12540   ip4_address_t rloc4;
12541   ip6_address_t rloc6;
12542   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12543
12544   memset (&rloc, 0, sizeof (rloc));
12545
12546   /* Parse args required to build the message */
12547   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12548     {
12549       if (unformat (input, "del-all"))
12550         {
12551           del_all = 1;
12552         }
12553       else if (unformat (input, "del"))
12554         {
12555           is_add = 0;
12556         }
12557       else if (unformat (input, "add"))
12558         {
12559           is_add = 1;
12560         }
12561       else if (unformat (input, "deid %U", unformat_lisp_eid_vat, eid))
12562         {
12563           eid_set = 1;
12564         }
12565       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, &seid))
12566         {
12567           //TODO: Need remove, but first must be remove from CSIT test
12568         }
12569       else if (unformat (input, "vni %d", &vni))
12570         {
12571           ;
12572         }
12573       else if (unformat (input, "p %d w %d", &p, &w))
12574         {
12575           if (!curr_rloc)
12576             {
12577               errmsg ("No RLOC configured for setting priority/weight!");
12578               return -99;
12579             }
12580           curr_rloc->priority = p;
12581           curr_rloc->weight = w;
12582         }
12583       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12584         {
12585           rloc.is_ip4 = 1;
12586           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12587           vec_add1 (rlocs, rloc);
12588           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12589         }
12590       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12591         {
12592           rloc.is_ip4 = 0;
12593           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12594           vec_add1 (rlocs, rloc);
12595           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12596         }
12597       else if (unformat (input, "action %d", &action))
12598         {
12599           ;
12600         }
12601       else
12602         {
12603           clib_warning ("parse error '%U'", format_unformat_error, input);
12604           return -99;
12605         }
12606     }
12607
12608   if (0 == eid_set)
12609     {
12610       errmsg ("missing params!");
12611       return -99;
12612     }
12613
12614   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12615     {
12616       errmsg ("no action set for negative map-reply!");
12617       return -99;
12618     }
12619
12620   M (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
12621   mp->is_add = is_add;
12622   mp->vni = htonl (vni);
12623   mp->action = (u8) action;
12624   mp->eid_len = eid->len;
12625   mp->del_all = del_all;
12626   mp->eid_type = eid->type;
12627   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12628
12629   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
12630   clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
12631   vec_free (rlocs);
12632
12633   /* send it... */
12634   S;
12635
12636   /* Wait for a reply... */
12637   W;
12638
12639   /* NOTREACHED */
12640   return 0;
12641 }
12642
12643 /**
12644  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
12645  * forwarding entries in data-plane accordingly.
12646  *
12647  * @param vam vpp API test context
12648  * @return return code
12649  */
12650 static int
12651 api_lisp_add_del_adjacency (vat_main_t * vam)
12652 {
12653   unformat_input_t *input = vam->input;
12654   vl_api_lisp_add_del_adjacency_t *mp;
12655   f64 timeout = ~0;
12656   u32 vni = 0;
12657   ip4_address_t seid4, deid4;
12658   ip6_address_t seid6, deid6;
12659   u8 deid_mac[6] = { 0 };
12660   u8 seid_mac[6] = { 0 };
12661   u8 deid_type, seid_type;
12662   u32 seid_len = 0, deid_len = 0, len;
12663   u8 is_add = 1;
12664
12665   seid_type = deid_type = (u8) ~ 0;
12666
12667   /* Parse args required to build the message */
12668   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12669     {
12670       if (unformat (input, "del"))
12671         {
12672           is_add = 0;
12673         }
12674       else if (unformat (input, "add"))
12675         {
12676           is_add = 1;
12677         }
12678       else if (unformat (input, "deid %U/%d", unformat_ip4_address,
12679                          &deid4, &len))
12680         {
12681           deid_type = 0;        /* ipv4 */
12682           deid_len = len;
12683         }
12684       else if (unformat (input, "deid %U/%d", unformat_ip6_address,
12685                          &deid6, &len))
12686         {
12687           deid_type = 1;        /* ipv6 */
12688           deid_len = len;
12689         }
12690       else if (unformat (input, "deid %U", unformat_ethernet_address,
12691                          deid_mac))
12692         {
12693           deid_type = 2;        /* mac */
12694         }
12695       else if (unformat (input, "seid %U/%d", unformat_ip4_address,
12696                          &seid4, &len))
12697         {
12698           seid_type = 0;        /* ipv4 */
12699           seid_len = len;
12700         }
12701       else if (unformat (input, "seid %U/%d", unformat_ip6_address,
12702                          &seid6, &len))
12703         {
12704           seid_type = 1;        /* ipv6 */
12705           seid_len = len;
12706         }
12707       else if (unformat (input, "seid %U", unformat_ethernet_address,
12708                          seid_mac))
12709         {
12710           seid_type = 2;        /* mac */
12711         }
12712       else if (unformat (input, "vni %d", &vni))
12713         {
12714           ;
12715         }
12716       else
12717         {
12718           errmsg ("parse error '%U'", format_unformat_error, input);
12719           return -99;
12720         }
12721     }
12722
12723   if ((u8) ~ 0 == deid_type)
12724     {
12725       errmsg ("missing params!");
12726       return -99;
12727     }
12728
12729   if (seid_type != deid_type)
12730     {
12731       errmsg ("source and destination EIDs are of different types!");
12732       return -99;
12733     }
12734
12735   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
12736   mp->is_add = is_add;
12737   mp->vni = htonl (vni);
12738   mp->seid_len = seid_len;
12739   mp->deid_len = deid_len;
12740   mp->eid_type = deid_type;
12741
12742   switch (mp->eid_type)
12743     {
12744     case 0:
12745       clib_memcpy (mp->seid, &seid4, sizeof (seid4));
12746       clib_memcpy (mp->deid, &deid4, sizeof (deid4));
12747       break;
12748     case 1:
12749       clib_memcpy (mp->seid, &seid6, sizeof (seid6));
12750       clib_memcpy (mp->deid, &deid6, sizeof (deid6));
12751       break;
12752     case 2:
12753       clib_memcpy (mp->seid, seid_mac, 6);
12754       clib_memcpy (mp->deid, deid_mac, 6);
12755       break;
12756     default:
12757       errmsg ("unknown EID type %d!", mp->eid_type);
12758       return 0;
12759     }
12760
12761   /* send it... */
12762   S;
12763
12764   /* Wait for a reply... */
12765   W;
12766
12767   /* NOTREACHED */
12768   return 0;
12769 }
12770
12771 static int
12772 api_lisp_gpe_add_del_iface (vat_main_t * vam)
12773 {
12774   unformat_input_t *input = vam->input;
12775   vl_api_lisp_gpe_add_del_iface_t *mp;
12776   f64 timeout = ~0;
12777   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
12778   u32 dp_table = 0, vni = 0;
12779
12780   /* Parse args required to build the message */
12781   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12782     {
12783       if (unformat (input, "up"))
12784         {
12785           action_set = 1;
12786           is_add = 1;
12787         }
12788       else if (unformat (input, "down"))
12789         {
12790           action_set = 1;
12791           is_add = 0;
12792         }
12793       else if (unformat (input, "table_id %d", &dp_table))
12794         {
12795           dp_table_set = 1;
12796         }
12797       else if (unformat (input, "bd_id %d", &dp_table))
12798         {
12799           dp_table_set = 1;
12800           is_l2 = 1;
12801         }
12802       else if (unformat (input, "vni %d", &vni))
12803         {
12804           vni_set = 1;
12805         }
12806       else
12807         break;
12808     }
12809
12810   if (action_set == 0)
12811     {
12812       errmsg ("Action not set\n");
12813       return -99;
12814     }
12815   if (dp_table_set == 0 || vni_set == 0)
12816     {
12817       errmsg ("vni and dp_table must be set\n");
12818       return -99;
12819     }
12820
12821   /* Construct the API message */
12822   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
12823
12824   mp->is_add = is_add;
12825   mp->dp_table = dp_table;
12826   mp->is_l2 = is_l2;
12827   mp->vni = vni;
12828
12829   /* send it... */
12830   S;
12831
12832   /* Wait for a reply... */
12833   W;
12834
12835   /* NOTREACHED */
12836   return 0;
12837 }
12838
12839 /**
12840  * Add/del map request itr rlocs from LISP control plane and updates
12841  *
12842  * @param vam vpp API test context
12843  * @return return code
12844  */
12845 static int
12846 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
12847 {
12848   unformat_input_t *input = vam->input;
12849   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
12850   f64 timeout = ~0;
12851   u8 *locator_set_name = 0;
12852   u8 locator_set_name_set = 0;
12853   u8 is_add = 1;
12854
12855   /* Parse args required to build the message */
12856   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12857     {
12858       if (unformat (input, "del"))
12859         {
12860           is_add = 0;
12861         }
12862       else if (unformat (input, "%_%v%_", &locator_set_name))
12863         {
12864           locator_set_name_set = 1;
12865         }
12866       else
12867         {
12868           clib_warning ("parse error '%U'", format_unformat_error, input);
12869           return -99;
12870         }
12871     }
12872
12873   if (is_add && !locator_set_name_set)
12874     {
12875       errmsg ("itr-rloc is not set!");
12876       return -99;
12877     }
12878
12879   if (is_add && vec_len (locator_set_name) > 64)
12880     {
12881       errmsg ("itr-rloc locator-set name too long\n");
12882       vec_free (locator_set_name);
12883       return -99;
12884     }
12885
12886   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
12887   mp->is_add = is_add;
12888   if (is_add)
12889     {
12890       clib_memcpy (mp->locator_set_name, locator_set_name,
12891                    vec_len (locator_set_name));
12892     }
12893   else
12894     {
12895       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
12896     }
12897   vec_free (locator_set_name);
12898
12899   /* send it... */
12900   S;
12901
12902   /* Wait for a reply... */
12903   W;
12904
12905   /* NOTREACHED */
12906   return 0;
12907 }
12908
12909 static int
12910 lisp_locator_dump_send_msg (vat_main_t * vam, u32 locator_set_index,
12911                             u8 filter)
12912 {
12913   vl_api_lisp_locator_dump_t *mp;
12914   f64 timeout = ~0;
12915
12916   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
12917
12918   mp->locator_set_index = htonl (locator_set_index);
12919   mp->filter = filter;
12920
12921   /* send it... */
12922   S;
12923
12924   /* Use a control ping for synchronization */
12925   {
12926     vl_api_noprint_control_ping_t *mp;
12927     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12928     S;
12929   }
12930   /* Wait for a reply... */
12931   W;
12932 }
12933
12934 static inline void
12935 clean_locator_set_message (vat_main_t * vam)
12936 {
12937   locator_set_msg_t *ls = 0;
12938
12939   vec_foreach (ls, vam->locator_set_msg)
12940   {
12941     vec_free (ls->locator_set_name);
12942   }
12943
12944   vec_free (vam->locator_set_msg);
12945 }
12946
12947 static int
12948 print_locator_in_locator_set (vat_main_t * vam, u8 filter)
12949 {
12950   locator_set_msg_t *ls;
12951   locator_msg_t *loc;
12952   u8 *tmp_str = 0;
12953   int i = 0, ret = 0;
12954
12955   vec_foreach (ls, vam->locator_set_msg)
12956   {
12957     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12958     if (ret)
12959       {
12960         vec_free (vam->locator_msg);
12961         clean_locator_set_message (vam);
12962         return ret;
12963       }
12964
12965     tmp_str = format (0, "%=20s%=16d%s", ls->locator_set_name,
12966                       ls->locator_set_index,
12967                       vec_len (vam->locator_msg) ? "" : "\n");
12968     i = 0;
12969     vec_foreach (loc, vam->locator_msg)
12970     {
12971       if (i)
12972         {
12973           tmp_str = format (tmp_str, "%=37s", " ");
12974         }
12975       if (loc->local)
12976         {
12977           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
12978                             loc->sw_if_index, loc->priority, loc->weight);
12979         }
12980       else
12981         {
12982           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
12983                             loc->is_ipv6 ? format_ip6_address :
12984                             format_ip4_address,
12985                             loc->ip_address, loc->priority, loc->weight);
12986         }
12987       i++;
12988     }
12989
12990     fformat (vam->ofp, "%s", tmp_str);
12991     vec_free (tmp_str);
12992     vec_free (vam->locator_msg);
12993   }
12994
12995   clean_locator_set_message (vam);
12996
12997   return ret;
12998 }
12999
13000 static int
13001 json_locator_in_locator_set (vat_main_t * vam, u8 filter)
13002 {
13003   locator_set_msg_t *ls;
13004   locator_msg_t *loc;
13005   vat_json_node_t *node = NULL;
13006   vat_json_node_t *locator_array;
13007   vat_json_node_t *locator;
13008   struct in6_addr ip6;
13009   struct in_addr ip4;
13010   int ret = 0;
13011
13012   if (!vec_len (vam->locator_set_msg))
13013     {
13014       /* just print [] */
13015       vat_json_init_array (&vam->json_tree);
13016       vat_json_print (vam->ofp, &vam->json_tree);
13017       vam->json_tree.type = VAT_JSON_NONE;
13018       return ret;
13019     }
13020
13021   if (VAT_JSON_ARRAY != vam->json_tree.type)
13022     {
13023       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13024       vat_json_init_array (&vam->json_tree);
13025     }
13026
13027   vec_foreach (ls, vam->locator_set_msg)
13028   {
13029     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
13030     if (ret)
13031       {
13032         vec_free (ls->locator_set_name);
13033         vec_free (vam->locator_msg);
13034         vec_free (vam->locator_set_msg);
13035         vat_json_free (&vam->json_tree);
13036         vam->json_tree.type = VAT_JSON_NONE;
13037         return ret;
13038       }
13039
13040     node = vat_json_array_add (&vam->json_tree);
13041     vat_json_init_object (node);
13042
13043     vat_json_object_add_uint (node, "locator-set-index",
13044                               ls->locator_set_index);
13045     vat_json_object_add_string_copy (node, "locator-set",
13046                                      ls->locator_set_name);
13047     locator_array = vat_json_object_add_list (node, "locator");
13048     vec_foreach (loc, vam->locator_msg)
13049     {
13050       locator = vat_json_array_add (locator_array);
13051       vat_json_init_object (locator);
13052       if (loc->local)
13053         {
13054           vat_json_object_add_uint (locator, "locator-index",
13055                                     loc->sw_if_index);
13056         }
13057       else
13058         {
13059           if (loc->is_ipv6)
13060             {
13061               clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
13062               vat_json_object_add_ip6 (locator, "locator", ip6);
13063             }
13064           else
13065             {
13066               clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
13067               vat_json_object_add_ip4 (locator, "locator", ip4);
13068             }
13069         }
13070       vat_json_object_add_uint (locator, "priority", loc->priority);
13071       vat_json_object_add_uint (locator, "weight", loc->weight);
13072     }
13073
13074     vec_free (ls->locator_set_name);
13075     vec_free (vam->locator_msg);
13076   }
13077
13078   vat_json_print (vam->ofp, &vam->json_tree);
13079   vat_json_free (&vam->json_tree);
13080   vam->json_tree.type = VAT_JSON_NONE;
13081
13082   vec_free (vam->locator_set_msg);
13083
13084   return ret;
13085 }
13086
13087 static int
13088 get_locator_set_index_from_msg (vat_main_t * vam, u8 * locator_set,
13089                                 u32 * locator_set_index)
13090 {
13091   locator_set_msg_t *ls;
13092   int ret = 0;
13093
13094   *locator_set_index = ~0;
13095
13096   if (!vec_len (vam->locator_set_msg))
13097     {
13098       return ret;
13099     }
13100
13101   vec_foreach (ls, vam->locator_set_msg)
13102   {
13103     if (!strcmp ((char *) locator_set, (char *) ls->locator_set_name))
13104       {
13105         *locator_set_index = ls->locator_set_index;
13106         vec_free (vam->locator_set_msg);
13107         return ret;
13108       }
13109   }
13110
13111   vec_free (vam->locator_set_msg);
13112
13113   return ret;
13114 }
13115
13116 static int
13117 get_locator_set_index (vat_main_t * vam, u8 * locator_set,
13118                        u32 * locator_set_index)
13119 {
13120   vl_api_lisp_locator_set_dump_t *mp;
13121   f64 timeout = ~0;
13122
13123   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13124   /* send it... */
13125   S;
13126
13127   /* Use a control ping for synchronization */
13128   {
13129     vl_api_noprint_control_ping_t *mp;
13130     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13131     S;
13132   }
13133
13134   vam->noprint_msg = 1;
13135   /* Wait for a reply... */
13136   /* *INDENT-OFF* */
13137   W_L
13138   ({
13139     get_locator_set_index_from_msg (vam, locator_set, locator_set_index);
13140     vam->noprint_msg = 0;
13141   });
13142   /* *INDENT-ON* */
13143
13144   /* NOTREACHED */
13145   return 0;
13146 }
13147
13148 static inline int
13149 lisp_locator_dump (vat_main_t * vam, u32 locator_set_index, u8 * locator_set,
13150                    u8 filter)
13151 {
13152   int ret = 0;
13153
13154   ASSERT (vam);
13155
13156   if (!vam->json_output)
13157     {
13158       fformat (vam->ofp, "%=20s%=16s%=16s\n",
13159                "locator", "priority", "weight");
13160     }
13161
13162   if (locator_set)
13163     {
13164       ret = get_locator_set_index (vam, locator_set, &locator_set_index);
13165     }
13166
13167   if (!ret && ~0 == locator_set_index)
13168     {
13169       return -99;
13170     }
13171
13172   ret = lisp_locator_dump_send_msg (vam, locator_set_index, filter);
13173
13174   return ret;
13175 }
13176
13177 static int
13178 lisp_locator_set_dump (vat_main_t * vam, u8 filter)
13179 {
13180   vl_api_lisp_locator_set_dump_t *mp;
13181   f64 timeout = ~0;
13182
13183   if (!vam->json_output)
13184     {
13185       fformat (vam->ofp, "%=20s%=16s%=16s%=16s%=16s\n",
13186                "locator-set", "locator-set-index", "locator", "priority",
13187                "weight");
13188     }
13189
13190   vam->noprint_msg = 1;
13191
13192   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13193
13194   mp->filter = filter;
13195
13196   /* send it... */
13197   S;
13198
13199   /* Use a control ping for synchronization */
13200   {
13201     vl_api_noprint_control_ping_t *mp;
13202     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13203     S;
13204   }
13205
13206   /* Wait for a reply... */
13207   /* *INDENT-OFF* */
13208   W_L
13209   ({
13210     if (vam->noprint_msg)
13211       {
13212         if (!vam->json_output)
13213           {
13214             print_locator_in_locator_set(vam, filter);
13215           }
13216         else
13217           {
13218             json_locator_in_locator_set(vam, filter);
13219           }
13220       }
13221     vam->noprint_msg = 0;
13222   });
13223   /* *INDENT-ON* */
13224
13225   /* NOTREACHED */
13226   return 0;
13227 }
13228
13229 static int
13230 api_lisp_locator_set_dump (vat_main_t * vam)
13231 {
13232   unformat_input_t *input = vam->input;
13233   vam->noprint_msg = 0;
13234   u32 locator_set_index = ~0;
13235   u8 locator_set_index_set = 0;
13236   u8 *locator_set = 0;
13237   u8 locator_set_set = 0;
13238   u8 filter = 0;
13239   int ret = 0;
13240
13241   /* Parse args required to build the message */
13242   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13243     {
13244       if (unformat (input, "locator-set-index %u", &locator_set_index))
13245         {
13246           locator_set_index_set = 1;
13247         }
13248       else if (unformat (input, "locator-set %s", &locator_set))
13249         {
13250           locator_set_set = 1;
13251         }
13252       else if (unformat (input, "local"))
13253         {
13254           filter = 1;
13255         }
13256       else if (unformat (input, "remote"))
13257         {
13258           filter = 2;
13259         }
13260       else
13261         {
13262           break;
13263         }
13264     }
13265
13266   if (locator_set_index_set && locator_set_set)
13267     {
13268       errmsg ("use only input parameter!\n");
13269       return -99;
13270     }
13271
13272   if (locator_set_index_set || locator_set_set)
13273     {
13274       ret = lisp_locator_dump (vam, locator_set_index, locator_set, filter);
13275     }
13276   else
13277     {
13278       ret = lisp_locator_set_dump (vam, filter);
13279     }
13280
13281   vec_free (locator_set);
13282
13283   return ret;
13284 }
13285
13286 static int
13287 api_lisp_eid_table_map_dump (vat_main_t * vam)
13288 {
13289   u8 is_l2 = 0;
13290   u8 mode_set = 0;
13291   unformat_input_t *input = vam->input;
13292   vl_api_lisp_eid_table_map_dump_t *mp;
13293   f64 timeout = ~0;
13294
13295   /* Parse args required to build the message */
13296   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13297     {
13298       if (unformat (input, "l2"))
13299         {
13300           is_l2 = 1;
13301           mode_set = 1;
13302         }
13303       else if (unformat (input, "l3"))
13304         {
13305           is_l2 = 0;
13306           mode_set = 1;
13307         }
13308       else
13309         {
13310           errmsg ("parse error '%U'", format_unformat_error, input);
13311           return -99;
13312         }
13313     }
13314
13315   if (!mode_set)
13316     {
13317       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13318       return -99;
13319     }
13320
13321   if (!vam->json_output)
13322     {
13323       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13324     }
13325
13326   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13327   mp->is_l2 = is_l2;
13328
13329   /* send it... */
13330   S;
13331
13332   /* Use a control ping for synchronization */
13333   {
13334     vl_api_control_ping_t *mp;
13335     M (CONTROL_PING, control_ping);
13336     S;
13337   }
13338   /* Wait for a reply... */
13339   W;
13340
13341   /* NOTREACHED */
13342   return 0;
13343 }
13344
13345 static int
13346 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13347 {
13348   vl_api_lisp_eid_table_vni_dump_t *mp;
13349   f64 timeout = ~0;
13350
13351   if (!vam->json_output)
13352     {
13353       fformat (vam->ofp, "VNI\n");
13354     }
13355
13356   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13357
13358   /* send it... */
13359   S;
13360
13361   /* Use a control ping for synchronization */
13362   {
13363     vl_api_control_ping_t *mp;
13364     M (CONTROL_PING, control_ping);
13365     S;
13366   }
13367   /* Wait for a reply... */
13368   W;
13369
13370   /* NOTREACHED */
13371   return 0;
13372 }
13373
13374 static int
13375 get_locator_set (vat_main_t * vam)
13376 {
13377   vl_api_lisp_locator_set_dump_t *mp;
13378   f64 timeout = ~0;
13379
13380   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13381   /* send it... */
13382   S;
13383
13384   /* Use a control ping for synchronization */
13385   {
13386     vl_api_noprint_control_ping_t *mp;
13387     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13388     S;
13389   }
13390
13391   /* Wait for a reply... */
13392   W;
13393
13394   /* NOTREACHED */
13395   return 0;
13396 }
13397
13398 static inline u8 *
13399 format_eid_for_eid_table (vat_main_t * vam, u8 * str, eid_table_t * eid_table,
13400                           int *ret)
13401 {
13402   u8 *(*format_eid) (u8 *, va_list *) = 0;
13403
13404   ASSERT (vam != NULL);
13405   ASSERT (eid_table != NULL);
13406
13407   if (ret)
13408     {
13409       *ret = 0;
13410     }
13411
13412   switch (eid_table->eid_type)
13413     {
13414     case 0:
13415     case 1:
13416       format_eid = (eid_table->eid_type ? format_ip6_address :
13417                     format_ip4_address);
13418       str = format (0, "[%d] %U/%d", eid_table->vni,
13419                     format_eid, eid_table->eid, eid_table->eid_prefix_len);
13420       break;
13421     case 2:
13422       str = format (0, "[%d] %U", eid_table->vni,
13423                     format_ethernet_address, eid_table->eid);
13424       break;
13425     default:
13426       errmsg ("unknown EID type %d!", eid_table->eid_type);
13427       if (ret)
13428         {
13429           *ret = -99;
13430         }
13431       return 0;
13432     }
13433
13434   return str;
13435 }
13436
13437 static inline u8 *
13438 format_locator_set_for_eid_table (vat_main_t * vam, u8 * str,
13439                                   eid_table_t * eid_table)
13440 {
13441   locator_set_msg_t *ls = 0;
13442
13443   ASSERT (vam != NULL);
13444   ASSERT (eid_table != NULL);
13445
13446   if (eid_table->is_local)
13447     {
13448       vec_foreach (ls, vam->locator_set_msg)
13449       {
13450         if (ls->locator_set_index == eid_table->locator_set_index)
13451           {
13452             str = format (0, "local(%s)", ls->locator_set_name);
13453             return str;
13454           }
13455       }
13456
13457       str = format (0, "local(N/A)");
13458     }
13459   else
13460     {
13461       str = format (0, "remote");
13462     }
13463
13464   return str;
13465 }
13466
13467 static inline u8 *
13468 format_locator_for_eid_table (vat_main_t * vam, u8 * str,
13469                               eid_table_t * eid_table)
13470 {
13471   locator_msg_t *loc = 0;
13472   int first_line = 1;
13473
13474   ASSERT (vam != NULL);
13475   ASSERT (eid_table != NULL);
13476
13477   if (~0 == eid_table->locator_set_index)
13478     {
13479       return format (0, "action: %d\n", eid_table->action);
13480     }
13481
13482   vec_foreach (loc, vam->locator_msg)
13483   {
13484     if (!first_line)
13485       {
13486         if (loc->local)
13487           {
13488             str = format (str, "%-55s%-d\n", " ", loc->sw_if_index);
13489           }
13490         else
13491           {
13492             str = format (str, "%=55s%-U\n", " ",
13493                           loc->is_ipv6 ? format_ip6_address :
13494                           format_ip4_address, loc->ip_address);
13495           }
13496
13497         continue;
13498       }
13499
13500     if (loc->local)
13501       {
13502         str = format (str, "%-30d%-20u%-u\n", loc->sw_if_index,
13503                       eid_table->ttl, eid_table->authoritative);
13504       }
13505     else
13506       {
13507         str = format (str, "%-30U%-20u%-u\n",
13508                       loc->is_ipv6 ? format_ip6_address :
13509                       format_ip4_address,
13510                       loc->ip_address, eid_table->ttl,
13511                       eid_table->authoritative);
13512       }
13513     first_line = 0;
13514   }
13515
13516   return str;
13517 }
13518
13519 static int
13520 print_lisp_eid_table_dump (vat_main_t * vam)
13521 {
13522   eid_table_t *eid_table = 0;
13523   u8 *tmp_str = 0, *tmp_str2 = 0;
13524   int ret = 0;
13525
13526   ASSERT (vam != NULL);
13527
13528   ret = get_locator_set (vam);
13529   if (ret)
13530     {
13531       vec_free (vam->eid_tables);
13532       return ret;
13533     }
13534
13535   fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type", "locators",
13536            "ttl", "authoritative");
13537
13538   vec_foreach (eid_table, vam->eid_tables)
13539   {
13540     if (~0 != eid_table->locator_set_index)
13541       {
13542         ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index,
13543                                           0);
13544         if (ret)
13545           {
13546             vec_free (vam->locator_msg);
13547             clean_locator_set_message (vam);
13548             vec_free (vam->eid_tables);
13549             return ret;
13550           }
13551       }
13552
13553     tmp_str2 = format_eid_for_eid_table (vam, tmp_str2, eid_table, &ret);
13554     if (ret)
13555       {
13556         vec_free (vam->locator_msg);
13557         clean_locator_set_message (vam);
13558         vec_free (vam->eid_tables);
13559         return ret;
13560       }
13561
13562     tmp_str = format (0, "%-35s", tmp_str2);
13563     vec_free (tmp_str2);
13564
13565     tmp_str2 = format_locator_set_for_eid_table (vam, tmp_str2, eid_table);
13566     tmp_str = format (tmp_str, "%-20s", tmp_str2);
13567     vec_free (tmp_str2);
13568
13569     tmp_str2 = format_locator_for_eid_table (vam, tmp_str2, eid_table);
13570     tmp_str = format (tmp_str, "%-s", tmp_str2);
13571     vec_free (tmp_str2);
13572
13573     fformat (vam->ofp, "%s", tmp_str);
13574     vec_free (tmp_str);
13575     vec_free (vam->locator_msg);
13576   }
13577
13578   clean_locator_set_message (vam);
13579   vec_free (vam->eid_tables);
13580
13581   return ret;
13582 }
13583
13584 static inline void
13585 json_locator_set_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13586                                 eid_table_t * eid_table)
13587 {
13588   locator_set_msg_t *ls = 0;
13589   u8 *s = 0;
13590
13591   ASSERT (vam != NULL);
13592   ASSERT (node != NULL);
13593   ASSERT (eid_table != NULL);
13594
13595   if (eid_table->is_local)
13596     {
13597       vec_foreach (ls, vam->locator_set_msg)
13598       {
13599         if (ls->locator_set_index == eid_table->locator_set_index)
13600           {
13601             vat_json_object_add_string_copy (node, "locator-set",
13602                                              ls->locator_set_name);
13603             return;
13604           }
13605       }
13606
13607       s = format (0, "N/A");
13608       vec_add1 (s, 0);
13609       vat_json_object_add_string_copy (node, "locator-set", s);
13610       vec_free (s);
13611     }
13612   else
13613     {
13614       s = format (0, "remote");
13615       vec_add1 (s, 0);
13616       vat_json_object_add_string_copy (node, "locator-set", s);
13617       vec_free (s);
13618     }
13619 }
13620
13621 static inline int
13622 json_eid_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13623                         eid_table_t * eid_table)
13624 {
13625   u8 *s = 0;
13626   struct in6_addr ip6;
13627   struct in_addr ip4;
13628
13629   ASSERT (vam != NULL);
13630   ASSERT (node != NULL);
13631   ASSERT (eid_table != NULL);
13632
13633   switch (eid_table->eid_type)
13634     {
13635     case 0:
13636       clib_memcpy (&ip4, eid_table->eid, sizeof (ip4));
13637       vat_json_object_add_ip4 (node, "eid", ip4);
13638       vat_json_object_add_uint (node, "eid-prefix-len",
13639                                 eid_table->eid_prefix_len);
13640       break;
13641     case 1:
13642       clib_memcpy (&ip6, eid_table->eid, sizeof (ip6));
13643       vat_json_object_add_ip6 (node, "eid", ip6);
13644       vat_json_object_add_uint (node, "eid-prefix-len",
13645                                 eid_table->eid_prefix_len);
13646       break;
13647     case 2:
13648       s = format (0, "%U", format_ethernet_address, eid_table->eid);
13649       vec_add1 (s, 0);
13650       vat_json_object_add_string_copy (node, "eid", s);
13651       vec_free (s);
13652       break;
13653     default:
13654       errmsg ("unknown EID type %d!", eid_table->eid_type);
13655       return -99;
13656     }
13657
13658   return 0;
13659 }
13660
13661 static inline void
13662 json_locator_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13663                             eid_table_t * eid_table)
13664 {
13665   locator_msg_t *loc = 0;
13666   vat_json_node_t *locator_array = 0;
13667   vat_json_node_t *locator = 0;
13668   struct in6_addr ip6;
13669   struct in_addr ip4;
13670
13671   ASSERT (vam != NULL);
13672   ASSERT (node != NULL);
13673   ASSERT (eid_table != NULL);
13674
13675   locator_array = vat_json_object_add_list (node, "locator");
13676   vec_foreach (loc, vam->locator_msg)
13677   {
13678     locator = vat_json_array_add (locator_array);
13679     vat_json_init_object (locator);
13680     if (loc->local)
13681       {
13682         vat_json_object_add_uint (locator, "locator-index", loc->sw_if_index);
13683       }
13684     else
13685       {
13686         if (loc->is_ipv6)
13687           {
13688             clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
13689             vat_json_object_add_ip6 (locator, "locator", ip6);
13690           }
13691         else
13692           {
13693             clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
13694             vat_json_object_add_ip4 (locator, "locator", ip4);
13695           }
13696       }
13697   }
13698 }
13699
13700 static int
13701 json_lisp_eid_table_dump (vat_main_t * vam)
13702 {
13703   eid_table_t *eid_table;
13704   vat_json_node_t *node = 0;
13705   int ret = 0;
13706
13707   ASSERT (vam != NULL);
13708
13709   ret = get_locator_set (vam);
13710   if (ret)
13711     {
13712       vec_free (vam->eid_tables);
13713       return ret;
13714     }
13715
13716   if (!vec_len (vam->eid_tables))
13717     {
13718       /* just print [] */
13719       vat_json_init_array (&vam->json_tree);
13720       vat_json_print (vam->ofp, &vam->json_tree);
13721       vam->json_tree.type = VAT_JSON_NONE;
13722       return ret;
13723     }
13724
13725   if (VAT_JSON_ARRAY != vam->json_tree.type)
13726     {
13727       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13728       vat_json_init_array (&vam->json_tree);
13729     }
13730
13731   vec_foreach (eid_table, vam->eid_tables)
13732   {
13733     ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index, 0);
13734     if (ret)
13735       {
13736         vec_free (vam->locator_msg);
13737         vec_free (vam->eid_tables);
13738         clean_locator_set_message (vam);
13739         vat_json_free (&vam->json_tree);
13740         vam->json_tree.type = VAT_JSON_NONE;
13741         return ret;
13742       }
13743
13744     node = vat_json_array_add (&vam->json_tree);
13745     vat_json_init_object (node);
13746
13747     vat_json_object_add_uint (node, "vni", eid_table->vni);
13748
13749     json_locator_set_for_eid_table (vam, node, eid_table);
13750     ret = json_eid_for_eid_table (vam, node, eid_table);
13751     if (ret)
13752       {
13753         vec_free (vam->locator_msg);
13754         vec_free (vam->eid_tables);
13755         clean_locator_set_message (vam);
13756         vat_json_free (&vam->json_tree);
13757         vam->json_tree.type = VAT_JSON_NONE;
13758         return ret;
13759       }
13760
13761     json_locator_for_eid_table (vam, node, eid_table);
13762
13763     vat_json_object_add_uint (node, "ttl", eid_table->ttl);
13764     vat_json_object_add_uint (node, "authoritative",
13765                               eid_table->authoritative);
13766
13767     vec_free (vam->locator_msg);
13768   }
13769
13770   vat_json_print (vam->ofp, &vam->json_tree);
13771   vat_json_free (&vam->json_tree);
13772   vam->json_tree.type = VAT_JSON_NONE;
13773
13774   clean_locator_set_message (vam);
13775   vec_free (vam->eid_tables);
13776
13777   return ret;
13778 }
13779
13780 static int
13781 api_lisp_eid_table_dump (vat_main_t * vam)
13782 {
13783   unformat_input_t *i = vam->input;
13784   vl_api_lisp_eid_table_dump_t *mp;
13785   f64 timeout = ~0;
13786   struct in_addr ip4;
13787   struct in6_addr ip6;
13788   u8 mac[6];
13789   u8 eid_type = ~0, eid_set = 0;
13790   u32 prefix_length = ~0, t, vni = 0;
13791   u8 filter = 0;
13792
13793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13794     {
13795       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13796         {
13797           eid_set = 1;
13798           eid_type = 0;
13799           prefix_length = t;
13800         }
13801       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13802         {
13803           eid_set = 1;
13804           eid_type = 1;
13805           prefix_length = t;
13806         }
13807       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13808         {
13809           eid_set = 1;
13810           eid_type = 2;
13811         }
13812       else if (unformat (i, "vni %d", &t))
13813         {
13814           vni = t;
13815         }
13816       else if (unformat (i, "local"))
13817         {
13818           filter = 1;
13819         }
13820       else if (unformat (i, "remote"))
13821         {
13822           filter = 2;
13823         }
13824       else
13825         {
13826           errmsg ("parse error '%U'", format_unformat_error, i);
13827           return -99;
13828         }
13829     }
13830
13831   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13832
13833   mp->filter = filter;
13834   if (eid_set)
13835     {
13836       mp->eid_set = 1;
13837       mp->vni = htonl (vni);
13838       mp->eid_type = eid_type;
13839       switch (eid_type)
13840         {
13841         case 0:
13842           mp->prefix_length = prefix_length;
13843           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13844           break;
13845         case 1:
13846           mp->prefix_length = prefix_length;
13847           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13848           break;
13849         case 2:
13850           clib_memcpy (mp->eid, mac, sizeof (mac));
13851           break;
13852         default:
13853           errmsg ("unknown EID type %d!", eid_type);
13854           return -99;
13855         }
13856     }
13857
13858   vam->noprint_msg = 1;
13859
13860   /* send it... */
13861   S;
13862
13863   /* Use a control ping for synchronization */
13864   {
13865     vl_api_noprint_control_ping_t *mp;
13866     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13867     S;
13868   }
13869
13870   /* Wait for a reply... */
13871   /* *INDENT-OFF* */
13872   W_L
13873   ({
13874     if (vam->noprint_msg)
13875       {
13876         if (!vam->json_output)
13877           {
13878             vam->retval = print_lisp_eid_table_dump(vam);
13879           }
13880         else
13881           {
13882             vam->retval = json_lisp_eid_table_dump(vam);
13883           }
13884       }
13885     vam->noprint_msg = 0;
13886   });
13887   /* *INDENT-ON* */
13888
13889   /* NOTREACHED */
13890   return 0;
13891 }
13892
13893 static int
13894 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13895 {
13896   vl_api_lisp_gpe_tunnel_dump_t *mp;
13897   f64 timeout = ~0;
13898
13899   if (!vam->json_output)
13900     {
13901       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13902                "%=16s%=16s%=16s%=16s%=16s\n",
13903                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13904                "Decap next", "Lisp version", "Flags", "Next protocol",
13905                "ver_res", "res", "iid");
13906     }
13907
13908   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13909   /* send it... */
13910   S;
13911
13912   /* Use a control ping for synchronization */
13913   {
13914     vl_api_control_ping_t *mp;
13915     M (CONTROL_PING, control_ping);
13916     S;
13917   }
13918   /* Wait for a reply... */
13919   W;
13920
13921   /* NOTREACHED */
13922   return 0;
13923 }
13924
13925 static int
13926 api_lisp_map_resolver_dump (vat_main_t * vam)
13927 {
13928   vl_api_lisp_map_resolver_dump_t *mp;
13929   f64 timeout = ~0;
13930
13931   if (!vam->json_output)
13932     {
13933       fformat (vam->ofp, "%=20s\n", "Map resolver");
13934     }
13935
13936   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13937   /* send it... */
13938   S;
13939
13940   /* Use a control ping for synchronization */
13941   {
13942     vl_api_control_ping_t *mp;
13943     M (CONTROL_PING, control_ping);
13944     S;
13945   }
13946   /* Wait for a reply... */
13947   W;
13948
13949   /* NOTREACHED */
13950   return 0;
13951 }
13952
13953 static int
13954 api_show_lisp_status (vat_main_t * vam)
13955 {
13956   vl_api_show_lisp_status_t *mp;
13957   f64 timeout = ~0;
13958
13959   if (!vam->json_output)
13960     {
13961       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13962     }
13963
13964   M (SHOW_LISP_STATUS, show_lisp_status);
13965   /* send it... */
13966   S;
13967   /* Wait for a reply... */
13968   W;
13969
13970   /* NOTREACHED */
13971   return 0;
13972 }
13973
13974 static int
13975 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13976 {
13977   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13978   f64 timeout = ~0;
13979
13980   if (!vam->json_output)
13981     {
13982       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13983     }
13984
13985   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13986   /* send it... */
13987   S;
13988   /* Wait for a reply... */
13989   W;
13990
13991   /* NOTREACHED */
13992   return 0;
13993 }
13994
13995 static int
13996 api_af_packet_create (vat_main_t * vam)
13997 {
13998   unformat_input_t *i = vam->input;
13999   vl_api_af_packet_create_t *mp;
14000   f64 timeout;
14001   u8 *host_if_name = 0;
14002   u8 hw_addr[6];
14003   u8 random_hw_addr = 1;
14004
14005   memset (hw_addr, 0, sizeof (hw_addr));
14006
14007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14008     {
14009       if (unformat (i, "name %s", &host_if_name))
14010         vec_add1 (host_if_name, 0);
14011       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14012         random_hw_addr = 0;
14013       else
14014         break;
14015     }
14016
14017   if (!vec_len (host_if_name))
14018     {
14019       errmsg ("host-interface name must be specified");
14020       return -99;
14021     }
14022
14023   if (vec_len (host_if_name) > 64)
14024     {
14025       errmsg ("host-interface name too long");
14026       return -99;
14027     }
14028
14029   M (AF_PACKET_CREATE, af_packet_create);
14030
14031   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14032   clib_memcpy (mp->hw_addr, hw_addr, 6);
14033   mp->use_random_hw_addr = random_hw_addr;
14034   vec_free (host_if_name);
14035
14036   S;
14037   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14038   /* NOTREACHED */
14039   return 0;
14040 }
14041
14042 static int
14043 api_af_packet_delete (vat_main_t * vam)
14044 {
14045   unformat_input_t *i = vam->input;
14046   vl_api_af_packet_delete_t *mp;
14047   f64 timeout;
14048   u8 *host_if_name = 0;
14049
14050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14051     {
14052       if (unformat (i, "name %s", &host_if_name))
14053         vec_add1 (host_if_name, 0);
14054       else
14055         break;
14056     }
14057
14058   if (!vec_len (host_if_name))
14059     {
14060       errmsg ("host-interface name must be specified");
14061       return -99;
14062     }
14063
14064   if (vec_len (host_if_name) > 64)
14065     {
14066       errmsg ("host-interface name too long");
14067       return -99;
14068     }
14069
14070   M (AF_PACKET_DELETE, af_packet_delete);
14071
14072   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14073   vec_free (host_if_name);
14074
14075   S;
14076   W;
14077   /* NOTREACHED */
14078   return 0;
14079 }
14080
14081 static int
14082 api_policer_add_del (vat_main_t * vam)
14083 {
14084   unformat_input_t *i = vam->input;
14085   vl_api_policer_add_del_t *mp;
14086   f64 timeout;
14087   u8 is_add = 1;
14088   u8 *name = 0;
14089   u32 cir = 0;
14090   u32 eir = 0;
14091   u64 cb = 0;
14092   u64 eb = 0;
14093   u8 rate_type = 0;
14094   u8 round_type = 0;
14095   u8 type = 0;
14096   u8 color_aware = 0;
14097   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14098
14099   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14100   conform_action.dscp = 0;
14101   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14102   exceed_action.dscp = 0;
14103   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14104   violate_action.dscp = 0;
14105
14106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14107     {
14108       if (unformat (i, "del"))
14109         is_add = 0;
14110       else if (unformat (i, "name %s", &name))
14111         vec_add1 (name, 0);
14112       else if (unformat (i, "cir %u", &cir))
14113         ;
14114       else if (unformat (i, "eir %u", &eir))
14115         ;
14116       else if (unformat (i, "cb %u", &cb))
14117         ;
14118       else if (unformat (i, "eb %u", &eb))
14119         ;
14120       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14121                          &rate_type))
14122         ;
14123       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14124                          &round_type))
14125         ;
14126       else if (unformat (i, "type %U", unformat_policer_type, &type))
14127         ;
14128       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14129                          &conform_action))
14130         ;
14131       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14132                          &exceed_action))
14133         ;
14134       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14135                          &violate_action))
14136         ;
14137       else if (unformat (i, "color-aware"))
14138         color_aware = 1;
14139       else
14140         break;
14141     }
14142
14143   if (!vec_len (name))
14144     {
14145       errmsg ("policer name must be specified");
14146       return -99;
14147     }
14148
14149   if (vec_len (name) > 64)
14150     {
14151       errmsg ("policer name too long");
14152       return -99;
14153     }
14154
14155   M (POLICER_ADD_DEL, policer_add_del);
14156
14157   clib_memcpy (mp->name, name, vec_len (name));
14158   vec_free (name);
14159   mp->is_add = is_add;
14160   mp->cir = cir;
14161   mp->eir = eir;
14162   mp->cb = cb;
14163   mp->eb = eb;
14164   mp->rate_type = rate_type;
14165   mp->round_type = round_type;
14166   mp->type = type;
14167   mp->conform_action_type = conform_action.action_type;
14168   mp->conform_dscp = conform_action.dscp;
14169   mp->exceed_action_type = exceed_action.action_type;
14170   mp->exceed_dscp = exceed_action.dscp;
14171   mp->violate_action_type = violate_action.action_type;
14172   mp->violate_dscp = violate_action.dscp;
14173   mp->color_aware = color_aware;
14174
14175   S;
14176   W;
14177   /* NOTREACHED */
14178   return 0;
14179 }
14180
14181 static int
14182 api_policer_dump (vat_main_t * vam)
14183 {
14184   unformat_input_t *i = vam->input;
14185   vl_api_policer_dump_t *mp;
14186   f64 timeout = ~0;
14187   u8 *match_name = 0;
14188   u8 match_name_valid = 0;
14189
14190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14191     {
14192       if (unformat (i, "name %s", &match_name))
14193         {
14194           vec_add1 (match_name, 0);
14195           match_name_valid = 1;
14196         }
14197       else
14198         break;
14199     }
14200
14201   M (POLICER_DUMP, policer_dump);
14202   mp->match_name_valid = match_name_valid;
14203   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14204   vec_free (match_name);
14205   /* send it... */
14206   S;
14207
14208   /* Use a control ping for synchronization */
14209   {
14210     vl_api_control_ping_t *mp;
14211     M (CONTROL_PING, control_ping);
14212     S;
14213   }
14214   /* Wait for a reply... */
14215   W;
14216
14217   /* NOTREACHED */
14218   return 0;
14219 }
14220
14221 static int
14222 api_policer_classify_set_interface (vat_main_t * vam)
14223 {
14224   unformat_input_t *i = vam->input;
14225   vl_api_policer_classify_set_interface_t *mp;
14226   f64 timeout;
14227   u32 sw_if_index;
14228   int sw_if_index_set;
14229   u32 ip4_table_index = ~0;
14230   u32 ip6_table_index = ~0;
14231   u32 l2_table_index = ~0;
14232   u8 is_add = 1;
14233
14234   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14235     {
14236       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14237         sw_if_index_set = 1;
14238       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14239         sw_if_index_set = 1;
14240       else if (unformat (i, "del"))
14241         is_add = 0;
14242       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14243         ;
14244       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14245         ;
14246       else if (unformat (i, "l2-table %d", &l2_table_index))
14247         ;
14248       else
14249         {
14250           clib_warning ("parse error '%U'", format_unformat_error, i);
14251           return -99;
14252         }
14253     }
14254
14255   if (sw_if_index_set == 0)
14256     {
14257       errmsg ("missing interface name or sw_if_index\n");
14258       return -99;
14259     }
14260
14261   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14262
14263   mp->sw_if_index = ntohl (sw_if_index);
14264   mp->ip4_table_index = ntohl (ip4_table_index);
14265   mp->ip6_table_index = ntohl (ip6_table_index);
14266   mp->l2_table_index = ntohl (l2_table_index);
14267   mp->is_add = is_add;
14268
14269   S;
14270   W;
14271   /* NOTREACHED */
14272   return 0;
14273 }
14274
14275 static int
14276 api_policer_classify_dump (vat_main_t * vam)
14277 {
14278   unformat_input_t *i = vam->input;
14279   vl_api_policer_classify_dump_t *mp;
14280   f64 timeout = ~0;
14281   u8 type = POLICER_CLASSIFY_N_TABLES;
14282
14283   if (unformat (i, "type %U", unformat_classify_table_type, &type))
14284     ;
14285   else
14286     {
14287       errmsg ("classify table type must be specified\n");
14288       return -99;
14289     }
14290
14291   if (!vam->json_output)
14292     {
14293       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14294     }
14295
14296   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14297   mp->type = type;
14298   /* send it... */
14299   S;
14300
14301   /* Use a control ping for synchronization */
14302   {
14303     vl_api_control_ping_t *mp;
14304     M (CONTROL_PING, control_ping);
14305     S;
14306   }
14307   /* Wait for a reply... */
14308   W;
14309
14310   /* NOTREACHED */
14311   return 0;
14312 }
14313
14314 static int
14315 api_netmap_create (vat_main_t * vam)
14316 {
14317   unformat_input_t *i = vam->input;
14318   vl_api_netmap_create_t *mp;
14319   f64 timeout;
14320   u8 *if_name = 0;
14321   u8 hw_addr[6];
14322   u8 random_hw_addr = 1;
14323   u8 is_pipe = 0;
14324   u8 is_master = 0;
14325
14326   memset (hw_addr, 0, sizeof (hw_addr));
14327
14328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14329     {
14330       if (unformat (i, "name %s", &if_name))
14331         vec_add1 (if_name, 0);
14332       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14333         random_hw_addr = 0;
14334       else if (unformat (i, "pipe"))
14335         is_pipe = 1;
14336       else if (unformat (i, "master"))
14337         is_master = 1;
14338       else if (unformat (i, "slave"))
14339         is_master = 0;
14340       else
14341         break;
14342     }
14343
14344   if (!vec_len (if_name))
14345     {
14346       errmsg ("interface name must be specified");
14347       return -99;
14348     }
14349
14350   if (vec_len (if_name) > 64)
14351     {
14352       errmsg ("interface name too long");
14353       return -99;
14354     }
14355
14356   M (NETMAP_CREATE, netmap_create);
14357
14358   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14359   clib_memcpy (mp->hw_addr, hw_addr, 6);
14360   mp->use_random_hw_addr = random_hw_addr;
14361   mp->is_pipe = is_pipe;
14362   mp->is_master = is_master;
14363   vec_free (if_name);
14364
14365   S;
14366   W;
14367   /* NOTREACHED */
14368   return 0;
14369 }
14370
14371 static int
14372 api_netmap_delete (vat_main_t * vam)
14373 {
14374   unformat_input_t *i = vam->input;
14375   vl_api_netmap_delete_t *mp;
14376   f64 timeout;
14377   u8 *if_name = 0;
14378
14379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14380     {
14381       if (unformat (i, "name %s", &if_name))
14382         vec_add1 (if_name, 0);
14383       else
14384         break;
14385     }
14386
14387   if (!vec_len (if_name))
14388     {
14389       errmsg ("interface name must be specified");
14390       return -99;
14391     }
14392
14393   if (vec_len (if_name) > 64)
14394     {
14395       errmsg ("interface name too long");
14396       return -99;
14397     }
14398
14399   M (NETMAP_DELETE, netmap_delete);
14400
14401   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14402   vec_free (if_name);
14403
14404   S;
14405   W;
14406   /* NOTREACHED */
14407   return 0;
14408 }
14409
14410 static void vl_api_mpls_gre_tunnel_details_t_handler
14411   (vl_api_mpls_gre_tunnel_details_t * mp)
14412 {
14413   vat_main_t *vam = &vat_main;
14414   i32 i;
14415   i32 len = ntohl (mp->nlabels);
14416
14417   if (mp->l2_only == 0)
14418     {
14419       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14420                ntohl (mp->tunnel_index),
14421                format_ip4_address, &mp->tunnel_src,
14422                format_ip4_address, &mp->tunnel_dst,
14423                format_ip4_address, &mp->intfc_address,
14424                ntohl (mp->mask_width));
14425       for (i = 0; i < len; i++)
14426         {
14427           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14428         }
14429       fformat (vam->ofp, "\n");
14430       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14431                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14432     }
14433   else
14434     {
14435       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14436                ntohl (mp->tunnel_index),
14437                format_ip4_address, &mp->tunnel_src,
14438                format_ip4_address, &mp->tunnel_dst,
14439                format_ip4_address, &mp->intfc_address);
14440       for (i = 0; i < len; i++)
14441         {
14442           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14443         }
14444       fformat (vam->ofp, "\n");
14445       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14446                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14447     }
14448 }
14449
14450 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14451   (vl_api_mpls_gre_tunnel_details_t * mp)
14452 {
14453   vat_main_t *vam = &vat_main;
14454   vat_json_node_t *node = NULL;
14455   struct in_addr ip4;
14456   i32 i;
14457   i32 len = ntohl (mp->nlabels);
14458
14459   if (VAT_JSON_ARRAY != vam->json_tree.type)
14460     {
14461       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14462       vat_json_init_array (&vam->json_tree);
14463     }
14464   node = vat_json_array_add (&vam->json_tree);
14465
14466   vat_json_init_object (node);
14467   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14468   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14469   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14470   vat_json_object_add_uint (node, "inner_fib_index",
14471                             ntohl (mp->inner_fib_index));
14472   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14473   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14474   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14475   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14476   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14477   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14478   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14479   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14480   vat_json_object_add_uint (node, "outer_fib_index",
14481                             ntohl (mp->outer_fib_index));
14482   vat_json_object_add_uint (node, "label_count", len);
14483   for (i = 0; i < len; i++)
14484     {
14485       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14486     }
14487 }
14488
14489 static int
14490 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14491 {
14492   vl_api_mpls_gre_tunnel_dump_t *mp;
14493   f64 timeout;
14494   i32 index = -1;
14495
14496   /* Parse args required to build the message */
14497   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14498     {
14499       if (!unformat (vam->input, "tunnel_index %d", &index))
14500         {
14501           index = -1;
14502           break;
14503         }
14504     }
14505
14506   fformat (vam->ofp, "  tunnel_index %d\n", index);
14507
14508   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14509   mp->tunnel_index = htonl (index);
14510   S;
14511
14512   /* Use a control ping for synchronization */
14513   {
14514     vl_api_control_ping_t *mp;
14515     M (CONTROL_PING, control_ping);
14516     S;
14517   }
14518   W;
14519 }
14520
14521 static void vl_api_mpls_eth_tunnel_details_t_handler
14522   (vl_api_mpls_eth_tunnel_details_t * mp)
14523 {
14524   vat_main_t *vam = &vat_main;
14525   i32 i;
14526   i32 len = ntohl (mp->nlabels);
14527
14528   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14529            ntohl (mp->tunnel_index),
14530            format_ethernet_address, &mp->tunnel_dst_mac,
14531            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14532   for (i = 0; i < len; i++)
14533     {
14534       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14535     }
14536   fformat (vam->ofp, "\n");
14537   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14538            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14539 }
14540
14541 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14542   (vl_api_mpls_eth_tunnel_details_t * mp)
14543 {
14544   vat_main_t *vam = &vat_main;
14545   vat_json_node_t *node = NULL;
14546   struct in_addr ip4;
14547   i32 i;
14548   i32 len = ntohl (mp->nlabels);
14549
14550   if (VAT_JSON_ARRAY != vam->json_tree.type)
14551     {
14552       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14553       vat_json_init_array (&vam->json_tree);
14554     }
14555   node = vat_json_array_add (&vam->json_tree);
14556
14557   vat_json_init_object (node);
14558   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14559   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14560   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14561   vat_json_object_add_uint (node, "inner_fib_index",
14562                             ntohl (mp->inner_fib_index));
14563   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14564   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14565   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14566   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14567   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14568                                    format (0, "%U", format_ethernet_address,
14569                                            &mp->tunnel_dst_mac));
14570   vat_json_object_add_uint (node, "tx_sw_if_index",
14571                             ntohl (mp->tx_sw_if_index));
14572   vat_json_object_add_uint (node, "label_count", len);
14573   for (i = 0; i < len; i++)
14574     {
14575       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14576     }
14577 }
14578
14579 static int
14580 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14581 {
14582   vl_api_mpls_eth_tunnel_dump_t *mp;
14583   f64 timeout;
14584   i32 index = -1;
14585
14586   /* Parse args required to build the message */
14587   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14588     {
14589       if (!unformat (vam->input, "tunnel_index %d", &index))
14590         {
14591           index = -1;
14592           break;
14593         }
14594     }
14595
14596   fformat (vam->ofp, "  tunnel_index %d\n", index);
14597
14598   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14599   mp->tunnel_index = htonl (index);
14600   S;
14601
14602   /* Use a control ping for synchronization */
14603   {
14604     vl_api_control_ping_t *mp;
14605     M (CONTROL_PING, control_ping);
14606     S;
14607   }
14608   W;
14609 }
14610
14611 static void vl_api_mpls_fib_encap_details_t_handler
14612   (vl_api_mpls_fib_encap_details_t * mp)
14613 {
14614   vat_main_t *vam = &vat_main;
14615   i32 i;
14616   i32 len = ntohl (mp->nlabels);
14617
14618   fformat (vam->ofp, "table %d, dest %U, label ",
14619            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14620   for (i = 0; i < len; i++)
14621     {
14622       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14623     }
14624   fformat (vam->ofp, "\n");
14625 }
14626
14627 static void vl_api_mpls_fib_encap_details_t_handler_json
14628   (vl_api_mpls_fib_encap_details_t * mp)
14629 {
14630   vat_main_t *vam = &vat_main;
14631   vat_json_node_t *node = NULL;
14632   i32 i;
14633   i32 len = ntohl (mp->nlabels);
14634   struct in_addr ip4;
14635
14636   if (VAT_JSON_ARRAY != vam->json_tree.type)
14637     {
14638       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14639       vat_json_init_array (&vam->json_tree);
14640     }
14641   node = vat_json_array_add (&vam->json_tree);
14642
14643   vat_json_init_object (node);
14644   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14645   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14646   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14647   vat_json_object_add_ip4 (node, "dest", ip4);
14648   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14649   vat_json_object_add_uint (node, "label_count", len);
14650   for (i = 0; i < len; i++)
14651     {
14652       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14653     }
14654 }
14655
14656 static int
14657 api_mpls_fib_encap_dump (vat_main_t * vam)
14658 {
14659   vl_api_mpls_fib_encap_dump_t *mp;
14660   f64 timeout;
14661
14662   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14663   S;
14664
14665   /* Use a control ping for synchronization */
14666   {
14667     vl_api_control_ping_t *mp;
14668     M (CONTROL_PING, control_ping);
14669     S;
14670   }
14671   W;
14672 }
14673
14674 static void vl_api_mpls_fib_decap_details_t_handler
14675   (vl_api_mpls_fib_decap_details_t * mp)
14676 {
14677   vat_main_t *vam = &vat_main;
14678
14679   fformat (vam->ofp,
14680            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14681            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14682            ntohl (mp->label), ntohl (mp->s_bit));
14683 }
14684
14685 static void vl_api_mpls_fib_decap_details_t_handler_json
14686   (vl_api_mpls_fib_decap_details_t * mp)
14687 {
14688   vat_main_t *vam = &vat_main;
14689   vat_json_node_t *node = NULL;
14690   struct in_addr ip4;
14691
14692   if (VAT_JSON_ARRAY != vam->json_tree.type)
14693     {
14694       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14695       vat_json_init_array (&vam->json_tree);
14696     }
14697   node = vat_json_array_add (&vam->json_tree);
14698
14699   vat_json_init_object (node);
14700   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14701   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14702   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14703   vat_json_object_add_ip4 (node, "dest", ip4);
14704   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14705   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14706   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14707   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14708   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14709 }
14710
14711 static int
14712 api_mpls_fib_decap_dump (vat_main_t * vam)
14713 {
14714   vl_api_mpls_fib_decap_dump_t *mp;
14715   f64 timeout;
14716
14717   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14718   S;
14719
14720   /* Use a control ping for synchronization */
14721   {
14722     vl_api_control_ping_t *mp;
14723     M (CONTROL_PING, control_ping);
14724     S;
14725   }
14726   W;
14727 }
14728
14729 int
14730 api_classify_table_ids (vat_main_t * vam)
14731 {
14732   vl_api_classify_table_ids_t *mp;
14733   f64 timeout;
14734
14735   /* Construct the API message */
14736   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14737   mp->context = 0;
14738
14739   S;
14740   W;
14741   /* NOTREACHED */
14742   return 0;
14743 }
14744
14745 int
14746 api_classify_table_by_interface (vat_main_t * vam)
14747 {
14748   unformat_input_t *input = vam->input;
14749   vl_api_classify_table_by_interface_t *mp;
14750   f64 timeout;
14751
14752   u32 sw_if_index = ~0;
14753   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14754     {
14755       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14756         ;
14757       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14758         ;
14759       else
14760         break;
14761     }
14762   if (sw_if_index == ~0)
14763     {
14764       errmsg ("missing interface name or sw_if_index\n");
14765       return -99;
14766     }
14767
14768   /* Construct the API message */
14769   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14770   mp->context = 0;
14771   mp->sw_if_index = ntohl (sw_if_index);
14772
14773   S;
14774   W;
14775   /* NOTREACHED */
14776   return 0;
14777 }
14778
14779 int
14780 api_classify_table_info (vat_main_t * vam)
14781 {
14782   unformat_input_t *input = vam->input;
14783   vl_api_classify_table_info_t *mp;
14784   f64 timeout;
14785
14786   u32 table_id = ~0;
14787   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14788     {
14789       if (unformat (input, "table_id %d", &table_id))
14790         ;
14791       else
14792         break;
14793     }
14794   if (table_id == ~0)
14795     {
14796       errmsg ("missing table id\n");
14797       return -99;
14798     }
14799
14800   /* Construct the API message */
14801   M (CLASSIFY_TABLE_INFO, classify_table_info);
14802   mp->context = 0;
14803   mp->table_id = ntohl (table_id);
14804
14805   S;
14806   W;
14807   /* NOTREACHED */
14808   return 0;
14809 }
14810
14811 int
14812 api_classify_session_dump (vat_main_t * vam)
14813 {
14814   unformat_input_t *input = vam->input;
14815   vl_api_classify_session_dump_t *mp;
14816   f64 timeout;
14817
14818   u32 table_id = ~0;
14819   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14820     {
14821       if (unformat (input, "table_id %d", &table_id))
14822         ;
14823       else
14824         break;
14825     }
14826   if (table_id == ~0)
14827     {
14828       errmsg ("missing table id\n");
14829       return -99;
14830     }
14831
14832   /* Construct the API message */
14833   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14834   mp->context = 0;
14835   mp->table_id = ntohl (table_id);
14836   S;
14837
14838   /* Use a control ping for synchronization */
14839   {
14840     vl_api_control_ping_t *mp;
14841     M (CONTROL_PING, control_ping);
14842     S;
14843   }
14844   W;
14845   /* NOTREACHED */
14846   return 0;
14847 }
14848
14849 static void
14850 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
14851 {
14852   vat_main_t *vam = &vat_main;
14853
14854   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14855            "src_address %U, vrf_id %d, path_mtu %u, "
14856            "template_interval %u, udp_checksum %d\n",
14857            format_ip4_address, mp->collector_address,
14858            ntohs (mp->collector_port),
14859            format_ip4_address, mp->src_address,
14860            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
14861            ntohl (mp->template_interval), mp->udp_checksum);
14862
14863   vam->retval = 0;
14864   vam->result_ready = 1;
14865 }
14866
14867 static void
14868   vl_api_ipfix_exporter_details_t_handler_json
14869   (vl_api_ipfix_exporter_details_t * mp)
14870 {
14871   vat_main_t *vam = &vat_main;
14872   vat_json_node_t node;
14873   struct in_addr collector_address;
14874   struct in_addr src_address;
14875
14876   vat_json_init_object (&node);
14877   clib_memcpy (&collector_address, &mp->collector_address,
14878                sizeof (collector_address));
14879   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14880   vat_json_object_add_uint (&node, "collector_port",
14881                             ntohs (mp->collector_port));
14882   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14883   vat_json_object_add_ip4 (&node, "src_address", src_address);
14884   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
14885   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14886   vat_json_object_add_uint (&node, "template_interval",
14887                             ntohl (mp->template_interval));
14888   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
14889
14890   vat_json_print (vam->ofp, &node);
14891   vat_json_free (&node);
14892   vam->retval = 0;
14893   vam->result_ready = 1;
14894 }
14895
14896 int
14897 api_ipfix_exporter_dump (vat_main_t * vam)
14898 {
14899   vl_api_ipfix_exporter_dump_t *mp;
14900   f64 timeout;
14901
14902   /* Construct the API message */
14903   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
14904   mp->context = 0;
14905
14906   S;
14907   W;
14908   /* NOTREACHED */
14909   return 0;
14910 }
14911
14912 static int
14913 api_ipfix_classify_stream_dump (vat_main_t * vam)
14914 {
14915   vl_api_ipfix_classify_stream_dump_t *mp;
14916   f64 timeout;
14917
14918   /* Construct the API message */
14919   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
14920   mp->context = 0;
14921
14922   S;
14923   W;
14924   /* NOTREACHED */
14925   return 0;
14926 }
14927
14928 static void
14929   vl_api_ipfix_classify_stream_details_t_handler
14930   (vl_api_ipfix_classify_stream_details_t * mp)
14931 {
14932   vat_main_t *vam = &vat_main;
14933   fformat (vam->ofp, "domain_id %d, src_port %d\n",
14934            ntohl (mp->domain_id), ntohs (mp->src_port));
14935   vam->retval = 0;
14936   vam->result_ready = 1;
14937 }
14938
14939 static void
14940   vl_api_ipfix_classify_stream_details_t_handler_json
14941   (vl_api_ipfix_classify_stream_details_t * mp)
14942 {
14943   vat_main_t *vam = &vat_main;
14944   vat_json_node_t node;
14945
14946   vat_json_init_object (&node);
14947   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
14948   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
14949
14950   vat_json_print (vam->ofp, &node);
14951   vat_json_free (&node);
14952   vam->retval = 0;
14953   vam->result_ready = 1;
14954 }
14955
14956 static int
14957 api_ipfix_classify_table_dump (vat_main_t * vam)
14958 {
14959   vl_api_ipfix_classify_table_dump_t *mp;
14960   f64 timeout;
14961
14962   if (!vam->json_output)
14963     {
14964       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
14965                "transport_protocol");
14966     }
14967
14968   /* Construct the API message */
14969   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
14970
14971   /* send it... */
14972   S;
14973
14974   /* Use a control ping for synchronization */
14975   {
14976     vl_api_control_ping_t *mp;
14977     M (CONTROL_PING, control_ping);
14978     S;
14979   }
14980   W;
14981 }
14982
14983 static void
14984   vl_api_ipfix_classify_table_details_t_handler
14985   (vl_api_ipfix_classify_table_details_t * mp)
14986 {
14987   vat_main_t *vam = &vat_main;
14988   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
14989            mp->transport_protocol);
14990 }
14991
14992 static void
14993   vl_api_ipfix_classify_table_details_t_handler_json
14994   (vl_api_ipfix_classify_table_details_t * mp)
14995 {
14996   vat_json_node_t *node = NULL;
14997   vat_main_t *vam = &vat_main;
14998
14999   if (VAT_JSON_ARRAY != vam->json_tree.type)
15000     {
15001       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15002       vat_json_init_array (&vam->json_tree);
15003     }
15004
15005   node = vat_json_array_add (&vam->json_tree);
15006   vat_json_init_object (node);
15007
15008   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15009   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15010   vat_json_object_add_uint (node, "transport_protocol",
15011                             mp->transport_protocol);
15012 }
15013
15014 int
15015 api_pg_create_interface (vat_main_t * vam)
15016 {
15017   unformat_input_t *input = vam->input;
15018   vl_api_pg_create_interface_t *mp;
15019   f64 timeout;
15020
15021   u32 if_id = ~0;
15022   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15023     {
15024       if (unformat (input, "if_id %d", &if_id))
15025         ;
15026       else
15027         break;
15028     }
15029   if (if_id == ~0)
15030     {
15031       errmsg ("missing pg interface index\n");
15032       return -99;
15033     }
15034
15035   /* Construct the API message */
15036   M (PG_CREATE_INTERFACE, pg_create_interface);
15037   mp->context = 0;
15038   mp->interface_id = ntohl (if_id);
15039
15040   S;
15041   W;
15042   /* NOTREACHED */
15043   return 0;
15044 }
15045
15046 int
15047 api_pg_capture (vat_main_t * vam)
15048 {
15049   unformat_input_t *input = vam->input;
15050   vl_api_pg_capture_t *mp;
15051   f64 timeout;
15052
15053   u32 if_id = ~0;
15054   u8 enable = 1;
15055   u32 count = 1;
15056   u8 pcap_file_set = 0;
15057   u8 *pcap_file = 0;
15058   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15059     {
15060       if (unformat (input, "if_id %d", &if_id))
15061         ;
15062       else if (unformat (input, "pcap %s", &pcap_file))
15063         pcap_file_set = 1;
15064       else if (unformat (input, "count %d", &count))
15065         ;
15066       else if (unformat (input, "disable"))
15067         enable = 0;
15068       else
15069         break;
15070     }
15071   if (if_id == ~0)
15072     {
15073       errmsg ("missing pg interface index\n");
15074       return -99;
15075     }
15076   if (pcap_file_set > 0)
15077     {
15078       if (vec_len (pcap_file) > 255)
15079         {
15080           errmsg ("pcap file name is too long\n");
15081           return -99;
15082         }
15083     }
15084
15085   u32 name_len = vec_len (pcap_file);
15086   /* Construct the API message */
15087   M (PG_CAPTURE, pg_capture);
15088   mp->context = 0;
15089   mp->interface_id = ntohl (if_id);
15090   mp->is_enabled = enable;
15091   mp->count = ntohl (count);
15092   mp->pcap_name_length = ntohl (name_len);
15093   if (pcap_file_set != 0)
15094     {
15095       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15096     }
15097   vec_free (pcap_file);
15098
15099   S;
15100   W;
15101   /* NOTREACHED */
15102   return 0;
15103 }
15104
15105 int
15106 api_pg_enable_disable (vat_main_t * vam)
15107 {
15108   unformat_input_t *input = vam->input;
15109   vl_api_pg_enable_disable_t *mp;
15110   f64 timeout;
15111
15112   u8 enable = 1;
15113   u8 stream_name_set = 0;
15114   u8 *stream_name = 0;
15115   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15116     {
15117       if (unformat (input, "stream %s", &stream_name))
15118         stream_name_set = 1;
15119       else if (unformat (input, "disable"))
15120         enable = 0;
15121       else
15122         break;
15123     }
15124
15125   if (stream_name_set > 0)
15126     {
15127       if (vec_len (stream_name) > 255)
15128         {
15129           errmsg ("stream name too long\n");
15130           return -99;
15131         }
15132     }
15133
15134   u32 name_len = vec_len (stream_name);
15135   /* Construct the API message */
15136   M (PG_ENABLE_DISABLE, pg_enable_disable);
15137   mp->context = 0;
15138   mp->is_enabled = enable;
15139   if (stream_name_set != 0)
15140     {
15141       mp->stream_name_length = ntohl (name_len);
15142       clib_memcpy (mp->stream_name, stream_name, name_len);
15143     }
15144   vec_free (stream_name);
15145
15146   S;
15147   W;
15148   /* NOTREACHED */
15149   return 0;
15150 }
15151
15152 int
15153 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15154 {
15155   unformat_input_t *input = vam->input;
15156   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15157   f64 timeout;
15158
15159   u16 *low_ports = 0;
15160   u16 *high_ports = 0;
15161   u16 this_low;
15162   u16 this_hi;
15163   ip4_address_t ip4_addr;
15164   ip6_address_t ip6_addr;
15165   u32 length;
15166   u32 tmp, tmp2;
15167   u8 prefix_set = 0;
15168   u32 vrf_id = ~0;
15169   u8 is_add = 1;
15170   u8 is_ipv6 = 0;
15171
15172   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15173     {
15174       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15175         {
15176           prefix_set = 1;
15177         }
15178       else
15179         if (unformat
15180             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15181         {
15182           prefix_set = 1;
15183           is_ipv6 = 1;
15184         }
15185       else if (unformat (input, "vrf %d", &vrf_id))
15186         ;
15187       else if (unformat (input, "del"))
15188         is_add = 0;
15189       else if (unformat (input, "port %d", &tmp))
15190         {
15191           if (tmp == 0 || tmp > 65535)
15192             {
15193               errmsg ("port %d out of range", tmp);
15194               return -99;
15195             }
15196           this_low = tmp;
15197           this_hi = this_low + 1;
15198           vec_add1 (low_ports, this_low);
15199           vec_add1 (high_ports, this_hi);
15200         }
15201       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15202         {
15203           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15204             {
15205               errmsg ("incorrect range parameters\n");
15206               return -99;
15207             }
15208           this_low = tmp;
15209           /* Note: in debug CLI +1 is added to high before
15210              passing to real fn that does "the work"
15211              (ip_source_and_port_range_check_add_del).
15212              This fn is a wrapper around the binary API fn a
15213              control plane will call, which expects this increment
15214              to have occurred. Hence letting the binary API control
15215              plane fn do the increment for consistency between VAT
15216              and other control planes.
15217            */
15218           this_hi = tmp2;
15219           vec_add1 (low_ports, this_low);
15220           vec_add1 (high_ports, this_hi);
15221         }
15222       else
15223         break;
15224     }
15225
15226   if (prefix_set == 0)
15227     {
15228       errmsg ("<address>/<mask> not specified\n");
15229       return -99;
15230     }
15231
15232   if (vrf_id == ~0)
15233     {
15234       errmsg ("VRF ID required, not specified\n");
15235       return -99;
15236     }
15237
15238   if (vrf_id == 0)
15239     {
15240       errmsg
15241         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15242       return -99;
15243     }
15244
15245   if (vec_len (low_ports) == 0)
15246     {
15247       errmsg ("At least one port or port range required\n");
15248       return -99;
15249     }
15250
15251   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15252      ip_source_and_port_range_check_add_del);
15253
15254   mp->is_add = is_add;
15255
15256   if (is_ipv6)
15257     {
15258       mp->is_ipv6 = 1;
15259       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15260     }
15261   else
15262     {
15263       mp->is_ipv6 = 0;
15264       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15265     }
15266
15267   mp->mask_length = length;
15268   mp->number_of_ranges = vec_len (low_ports);
15269
15270   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15271   vec_free (low_ports);
15272
15273   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15274   vec_free (high_ports);
15275
15276   mp->vrf_id = ntohl (vrf_id);
15277
15278   S;
15279   W;
15280   /* NOTREACHED */
15281   return 0;
15282 }
15283
15284 int
15285 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15286 {
15287   unformat_input_t *input = vam->input;
15288   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15289   f64 timeout;
15290   u32 sw_if_index = ~0;
15291   int vrf_set = 0;
15292   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15293   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15294   u8 is_add = 1;
15295
15296   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15297     {
15298       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15299         ;
15300       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15301         ;
15302       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15303         vrf_set = 1;
15304       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15305         vrf_set = 1;
15306       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15307         vrf_set = 1;
15308       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15309         vrf_set = 1;
15310       else if (unformat (input, "del"))
15311         is_add = 0;
15312       else
15313         break;
15314     }
15315
15316   if (sw_if_index == ~0)
15317     {
15318       errmsg ("Interface required but not specified\n");
15319       return -99;
15320     }
15321
15322   if (vrf_set == 0)
15323     {
15324       errmsg ("VRF ID required but not specified\n");
15325       return -99;
15326     }
15327
15328   if (tcp_out_vrf_id == 0
15329       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15330     {
15331       errmsg
15332         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15333       return -99;
15334     }
15335
15336   /* Construct the API message */
15337   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15338      ip_source_and_port_range_check_interface_add_del);
15339
15340   mp->sw_if_index = ntohl (sw_if_index);
15341   mp->is_add = is_add;
15342   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15343   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15344   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15345   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15346
15347   /* send it... */
15348   S;
15349
15350   /* Wait for a reply... */
15351   W;
15352 }
15353
15354 static int
15355 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15356 {
15357   unformat_input_t *i = vam->input;
15358   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15359   f64 timeout;
15360   u32 local_sa_id = 0;
15361   u32 remote_sa_id = 0;
15362   ip4_address_t src_address;
15363   ip4_address_t dst_address;
15364   u8 is_add = 1;
15365
15366   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15367     {
15368       if (unformat (i, "local_sa %d", &local_sa_id))
15369         ;
15370       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15371         ;
15372       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15373         ;
15374       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15375         ;
15376       else if (unformat (i, "del"))
15377         is_add = 0;
15378       else
15379         {
15380           clib_warning ("parse error '%U'", format_unformat_error, i);
15381           return -99;
15382         }
15383     }
15384
15385   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15386
15387   mp->local_sa_id = ntohl (local_sa_id);
15388   mp->remote_sa_id = ntohl (remote_sa_id);
15389   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15390   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15391   mp->is_add = is_add;
15392
15393   S;
15394   W;
15395   /* NOTREACHED */
15396   return 0;
15397 }
15398
15399 static void vl_api_ipsec_gre_tunnel_details_t_handler
15400   (vl_api_ipsec_gre_tunnel_details_t * mp)
15401 {
15402   vat_main_t *vam = &vat_main;
15403
15404   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15405            ntohl (mp->sw_if_index),
15406            format_ip4_address, &mp->src_address,
15407            format_ip4_address, &mp->dst_address,
15408            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15409 }
15410
15411 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15412   (vl_api_ipsec_gre_tunnel_details_t * mp)
15413 {
15414   vat_main_t *vam = &vat_main;
15415   vat_json_node_t *node = NULL;
15416   struct in_addr ip4;
15417
15418   if (VAT_JSON_ARRAY != vam->json_tree.type)
15419     {
15420       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15421       vat_json_init_array (&vam->json_tree);
15422     }
15423   node = vat_json_array_add (&vam->json_tree);
15424
15425   vat_json_init_object (node);
15426   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15427   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15428   vat_json_object_add_ip4 (node, "src_address", ip4);
15429   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15430   vat_json_object_add_ip4 (node, "dst_address", ip4);
15431   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15432   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15433 }
15434
15435 static int
15436 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15437 {
15438   unformat_input_t *i = vam->input;
15439   vl_api_ipsec_gre_tunnel_dump_t *mp;
15440   f64 timeout;
15441   u32 sw_if_index;
15442   u8 sw_if_index_set = 0;
15443
15444   /* Parse args required to build the message */
15445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15446     {
15447       if (unformat (i, "sw_if_index %d", &sw_if_index))
15448         sw_if_index_set = 1;
15449       else
15450         break;
15451     }
15452
15453   if (sw_if_index_set == 0)
15454     {
15455       sw_if_index = ~0;
15456     }
15457
15458   if (!vam->json_output)
15459     {
15460       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15461                "sw_if_index", "src_address", "dst_address",
15462                "local_sa_id", "remote_sa_id");
15463     }
15464
15465   /* Get list of gre-tunnel interfaces */
15466   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15467
15468   mp->sw_if_index = htonl (sw_if_index);
15469
15470   S;
15471
15472   /* Use a control ping for synchronization */
15473   {
15474     vl_api_control_ping_t *mp;
15475     M (CONTROL_PING, control_ping);
15476     S;
15477   }
15478   W;
15479 }
15480
15481 static int
15482 api_delete_subif (vat_main_t * vam)
15483 {
15484   unformat_input_t *i = vam->input;
15485   vl_api_delete_subif_t *mp;
15486   f64 timeout;
15487   u32 sw_if_index = ~0;
15488
15489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15490     {
15491       if (unformat (i, "sw_if_index %d", &sw_if_index))
15492         ;
15493       else
15494         break;
15495     }
15496
15497   if (sw_if_index == ~0)
15498     {
15499       errmsg ("missing sw_if_index\n");
15500       return -99;
15501     }
15502
15503   /* Construct the API message */
15504   M (DELETE_SUBIF, delete_subif);
15505   mp->sw_if_index = ntohl (sw_if_index);
15506
15507   S;
15508   W;
15509 }
15510
15511 static int
15512 q_or_quit (vat_main_t * vam)
15513 {
15514   longjmp (vam->jump_buf, 1);
15515   return 0;                     /* not so much */
15516 }
15517
15518 static int
15519 q (vat_main_t * vam)
15520 {
15521   return q_or_quit (vam);
15522 }
15523
15524 static int
15525 quit (vat_main_t * vam)
15526 {
15527   return q_or_quit (vam);
15528 }
15529
15530 static int
15531 comment (vat_main_t * vam)
15532 {
15533   return 0;
15534 }
15535
15536 static int
15537 cmd_cmp (void *a1, void *a2)
15538 {
15539   u8 **c1 = a1;
15540   u8 **c2 = a2;
15541
15542   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15543 }
15544
15545 static int
15546 help (vat_main_t * vam)
15547 {
15548   u8 **cmds = 0;
15549   u8 *name = 0;
15550   hash_pair_t *p;
15551   unformat_input_t *i = vam->input;
15552   int j;
15553
15554   if (unformat (i, "%s", &name))
15555     {
15556       uword *hs;
15557
15558       vec_add1 (name, 0);
15559
15560       hs = hash_get_mem (vam->help_by_name, name);
15561       if (hs)
15562         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15563       else
15564         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15565       vec_free (name);
15566       return 0;
15567     }
15568
15569   fformat (vam->ofp, "Help is available for the following:\n");
15570
15571     /* *INDENT-OFF* */
15572     hash_foreach_pair (p, vam->function_by_name,
15573     ({
15574       vec_add1 (cmds, (u8 *)(p->key));
15575     }));
15576     /* *INDENT-ON* */
15577
15578   vec_sort_with_function (cmds, cmd_cmp);
15579
15580   for (j = 0; j < vec_len (cmds); j++)
15581     fformat (vam->ofp, "%s\n", cmds[j]);
15582
15583   vec_free (cmds);
15584   return 0;
15585 }
15586
15587 static int
15588 set (vat_main_t * vam)
15589 {
15590   u8 *name = 0, *value = 0;
15591   unformat_input_t *i = vam->input;
15592
15593   if (unformat (i, "%s", &name))
15594     {
15595       /* The input buffer is a vector, not a string. */
15596       value = vec_dup (i->buffer);
15597       vec_delete (value, i->index, 0);
15598       /* Almost certainly has a trailing newline */
15599       if (value[vec_len (value) - 1] == '\n')
15600         value[vec_len (value) - 1] = 0;
15601       /* Make sure it's a proper string, one way or the other */
15602       vec_add1 (value, 0);
15603       (void) clib_macro_set_value (&vam->macro_main,
15604                                    (char *) name, (char *) value);
15605     }
15606   else
15607     errmsg ("usage: set <name> <value>\n");
15608
15609   vec_free (name);
15610   vec_free (value);
15611   return 0;
15612 }
15613
15614 static int
15615 unset (vat_main_t * vam)
15616 {
15617   u8 *name = 0;
15618
15619   if (unformat (vam->input, "%s", &name))
15620     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15621       errmsg ("unset: %s wasn't set\n", name);
15622   vec_free (name);
15623   return 0;
15624 }
15625
15626 typedef struct
15627 {
15628   u8 *name;
15629   u8 *value;
15630 } macro_sort_t;
15631
15632
15633 static int
15634 macro_sort_cmp (void *a1, void *a2)
15635 {
15636   macro_sort_t *s1 = a1;
15637   macro_sort_t *s2 = a2;
15638
15639   return strcmp ((char *) (s1->name), (char *) (s2->name));
15640 }
15641
15642 static int
15643 dump_macro_table (vat_main_t * vam)
15644 {
15645   macro_sort_t *sort_me = 0, *sm;
15646   int i;
15647   hash_pair_t *p;
15648
15649     /* *INDENT-OFF* */
15650     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15651     ({
15652       vec_add2 (sort_me, sm, 1);
15653       sm->name = (u8 *)(p->key);
15654       sm->value = (u8 *) (p->value[0]);
15655     }));
15656     /* *INDENT-ON* */
15657
15658   vec_sort_with_function (sort_me, macro_sort_cmp);
15659
15660   if (vec_len (sort_me))
15661     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15662   else
15663     fformat (vam->ofp, "The macro table is empty...\n");
15664
15665   for (i = 0; i < vec_len (sort_me); i++)
15666     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15667   return 0;
15668 }
15669
15670 static int
15671 dump_node_table (vat_main_t * vam)
15672 {
15673   int i, j;
15674   vlib_node_t *node, *next_node;
15675
15676   if (vec_len (vam->graph_nodes) == 0)
15677     {
15678       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15679       return 0;
15680     }
15681
15682   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15683     {
15684       node = vam->graph_nodes[i];
15685       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15686       for (j = 0; j < vec_len (node->next_nodes); j++)
15687         {
15688           if (node->next_nodes[j] != ~0)
15689             {
15690               next_node = vam->graph_nodes[node->next_nodes[j]];
15691               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15692             }
15693         }
15694     }
15695   return 0;
15696 }
15697
15698 static int
15699 search_node_table (vat_main_t * vam)
15700 {
15701   unformat_input_t *line_input = vam->input;
15702   u8 *node_to_find;
15703   int j;
15704   vlib_node_t *node, *next_node;
15705   uword *p;
15706
15707   if (vam->graph_node_index_by_name == 0)
15708     {
15709       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15710       return 0;
15711     }
15712
15713   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15714     {
15715       if (unformat (line_input, "%s", &node_to_find))
15716         {
15717           vec_add1 (node_to_find, 0);
15718           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15719           if (p == 0)
15720             {
15721               fformat (vam->ofp, "%s not found...\n", node_to_find);
15722               goto out;
15723             }
15724           node = vam->graph_nodes[p[0]];
15725           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15726           for (j = 0; j < vec_len (node->next_nodes); j++)
15727             {
15728               if (node->next_nodes[j] != ~0)
15729                 {
15730                   next_node = vam->graph_nodes[node->next_nodes[j]];
15731                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15732                 }
15733             }
15734         }
15735
15736       else
15737         {
15738           clib_warning ("parse error '%U'", format_unformat_error,
15739                         line_input);
15740           return -99;
15741         }
15742
15743     out:
15744       vec_free (node_to_find);
15745
15746     }
15747
15748   return 0;
15749 }
15750
15751
15752 static int
15753 script (vat_main_t * vam)
15754 {
15755   u8 *s = 0;
15756   char *save_current_file;
15757   unformat_input_t save_input;
15758   jmp_buf save_jump_buf;
15759   u32 save_line_number;
15760
15761   FILE *new_fp, *save_ifp;
15762
15763   if (unformat (vam->input, "%s", &s))
15764     {
15765       new_fp = fopen ((char *) s, "r");
15766       if (new_fp == 0)
15767         {
15768           errmsg ("Couldn't open script file %s\n", s);
15769           vec_free (s);
15770           return -99;
15771         }
15772     }
15773   else
15774     {
15775       errmsg ("Missing script name\n");
15776       return -99;
15777     }
15778
15779   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15780   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15781   save_ifp = vam->ifp;
15782   save_line_number = vam->input_line_number;
15783   save_current_file = (char *) vam->current_file;
15784
15785   vam->input_line_number = 0;
15786   vam->ifp = new_fp;
15787   vam->current_file = s;
15788   do_one_file (vam);
15789
15790   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15791   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15792   vam->ifp = save_ifp;
15793   vam->input_line_number = save_line_number;
15794   vam->current_file = (u8 *) save_current_file;
15795   vec_free (s);
15796
15797   return 0;
15798 }
15799
15800 static int
15801 echo (vat_main_t * vam)
15802 {
15803   fformat (vam->ofp, "%v", vam->input->buffer);
15804   return 0;
15805 }
15806
15807 /* List of API message constructors, CLI names map to api_xxx */
15808 #define foreach_vpe_api_msg                                             \
15809 _(create_loopback,"[mac <mac-addr>]")                                   \
15810 _(sw_interface_dump,"")                                                 \
15811 _(sw_interface_set_flags,                                               \
15812   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15813 _(sw_interface_add_del_address,                                         \
15814   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15815 _(sw_interface_set_table,                                               \
15816   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15817 _(sw_interface_set_vpath,                                               \
15818   "<intfc> | sw_if_index <id> enable | disable")                        \
15819 _(sw_interface_set_l2_xconnect,                                         \
15820   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15821   "enable | disable")                                                   \
15822 _(sw_interface_set_l2_bridge,                                           \
15823   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15824   "[shg <split-horizon-group>] [bvi]\n"                                 \
15825   "enable | disable")                                                   \
15826 _(bridge_domain_add_del,                                                \
15827   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15828 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15829 _(l2fib_add_del,                                                        \
15830   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15831 _(l2_flags,                                                             \
15832   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15833 _(bridge_flags,                                                         \
15834   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15835 _(tap_connect,                                                          \
15836   "tapname <name> mac <mac-addr> | random-mac")                         \
15837 _(tap_modify,                                                           \
15838   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15839 _(tap_delete,                                                           \
15840   "<vpp-if-name> | sw_if_index <id>")                                   \
15841 _(sw_interface_tap_dump, "")                                            \
15842 _(ip_add_del_route,                                                     \
15843   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15844   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15845   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15846   "[multipath] [count <n>]")                                            \
15847 _(proxy_arp_add_del,                                                    \
15848   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15849 _(proxy_arp_intfc_enable_disable,                                       \
15850   "<intfc> | sw_if_index <id> enable | disable")                        \
15851 _(mpls_add_del_encap,                                                   \
15852   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15853 _(mpls_add_del_decap,                                                   \
15854   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15855 _(mpls_gre_add_del_tunnel,                                              \
15856   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15857   "adj <ip4-address>/<mask-width> [del]")                               \
15858 _(sw_interface_set_unnumbered,                                          \
15859   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15860 _(ip_neighbor_add_del,                                                  \
15861   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15862   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15863 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15864 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15865 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15866   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15867   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15868   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15869 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15870 _(reset_fib, "vrf <n> [ipv6]")                                          \
15871 _(dhcp_proxy_config,                                                    \
15872   "svr <v46-address> src <v46-address>\n"                               \
15873    "insert-cid <n> [del]")                                              \
15874 _(dhcp_proxy_config_2,                                                  \
15875   "svr <v46-address> src <v46-address>\n"                               \
15876    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15877 _(dhcp_proxy_set_vss,                                                   \
15878   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15879 _(dhcp_client_config,                                                   \
15880   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15881 _(set_ip_flow_hash,                                                     \
15882   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15883 _(sw_interface_ip6_enable_disable,                                      \
15884   "<intfc> | sw_if_index <id> enable | disable")                        \
15885 _(sw_interface_ip6_set_link_local_address,                              \
15886   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15887 _(sw_interface_ip6nd_ra_prefix,                                         \
15888   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15889   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15890   "[nolink] [isno]")                                                    \
15891 _(sw_interface_ip6nd_ra_config,                                         \
15892   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15893   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15894   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15895 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15896 _(l2_patch_add_del,                                                     \
15897   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15898   "enable | disable")                                                   \
15899 _(mpls_ethernet_add_del_tunnel,                                         \
15900   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15901   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15902 _(mpls_ethernet_add_del_tunnel_2,                                       \
15903   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15904   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15905 _(sr_tunnel_add_del,                                                    \
15906   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15907   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15908   "[policy <policy_name>]")                                             \
15909 _(sr_policy_add_del,                                                    \
15910   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15911 _(sr_multicast_map_add_del,                                             \
15912   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15913 _(classify_add_del_table,                                               \
15914   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15915   "[del] mask <mask-value>\n"                                           \
15916   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15917 _(classify_add_del_session,                                             \
15918   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15919   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15920   "  [l3 [ip4|ip6]]")                                                   \
15921 _(classify_set_interface_ip_table,                                      \
15922   "<intfc> | sw_if_index <nn> table <nn>")                              \
15923 _(classify_set_interface_l2_tables,                                     \
15924   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15925   "  [other-table <nn>]")                                               \
15926 _(get_node_index, "node <node-name")                                    \
15927 _(add_node_next, "node <node-name> next <next-node-name>")              \
15928 _(l2tpv3_create_tunnel,                                                 \
15929   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15930   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15931   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15932 _(l2tpv3_set_tunnel_cookies,                                            \
15933   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15934   "[new_remote_cookie <nn>]\n")                                         \
15935 _(l2tpv3_interface_enable_disable,                                      \
15936   "<intfc> | sw_if_index <nn> enable | disable")                        \
15937 _(l2tpv3_set_lookup_key,                                                \
15938   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15939 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15940 _(vxlan_add_del_tunnel,                                                 \
15941   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15942   " [decap-next l2|ip4|ip6] [del]")                                     \
15943 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15944 _(gre_add_del_tunnel,                                                   \
15945   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n")          \
15946 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15947 _(l2_fib_clear_table, "")                                               \
15948 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15949 _(l2_interface_vlan_tag_rewrite,                                        \
15950   "<intfc> | sw_if_index <nn> \n"                                       \
15951   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15952   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15953 _(create_vhost_user_if,                                                 \
15954         "socket <filename> [server] [renumber <dev_instance>] "         \
15955         "[mac <mac_address>]")                                          \
15956 _(modify_vhost_user_if,                                                 \
15957         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15958         "[server] [renumber <dev_instance>]")                           \
15959 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15960 _(sw_interface_vhost_user_dump, "")                                     \
15961 _(show_version, "")                                                     \
15962 _(vxlan_gpe_add_del_tunnel,                                             \
15963   "local <addr> remote <addr> vni <nn>\n"                               \
15964     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15965   "[next-ethernet] [next-nsh]\n")                                       \
15966 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15967 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15968 _(interface_name_renumber,                                              \
15969   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15970 _(input_acl_set_interface,                                              \
15971   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15972   "  [l2-table <nn>] [del]")                                            \
15973 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15974 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
15975 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15976 _(ip_dump, "ipv4 | ipv6")                                               \
15977 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15978 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15979   "  spid_id <n> ")                                                     \
15980 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15981   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15982   "  integ_alg <alg> integ_key <hex>")                                  \
15983 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15984   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15985   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15986   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15987 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15988 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15989 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15990   "(auth_data 0x<data> | auth_data <data>)")                            \
15991 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15992   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15993 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15994   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15995   "(local|remote)")                                                     \
15996 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15997 _(delete_loopback,"sw_if_index <nn>")                                   \
15998 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15999 _(map_add_domain,                                                       \
16000   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16001   "ip6-src <ip6addr> "                                                  \
16002   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16003 _(map_del_domain, "index <n>")                                          \
16004 _(map_add_del_rule,                                                     \
16005   "index <n> psid <n> dst <ip6addr> [del]")                             \
16006 _(map_domain_dump, "")                                                  \
16007 _(map_rule_dump, "index <map-domain>")                                  \
16008 _(want_interface_events,  "enable|disable")                             \
16009 _(want_stats,"enable|disable")                                          \
16010 _(get_first_msg_id, "client <name>")                                    \
16011 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16012 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16013   "fib-id <nn> [ip4][ip6][default]")                                    \
16014 _(get_node_graph, " ")                                                  \
16015 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16016 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16017 _(ioam_disable, "")                                                \
16018 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16019                             " sw_if_index <sw_if_index> p <priority> "  \
16020                             "w <weight>] [del]")                        \
16021 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16022                         "iface <intf> | sw_if_index <sw_if_index> "     \
16023                         "p <priority> w <weight> [del]")                \
16024 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16025                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16026                           "locator-set <locator_name> [del]")           \
16027 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16028   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16029 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16030 _(lisp_gpe_enable_disable, "enable|disable")                            \
16031 _(lisp_enable_disable, "enable|disable")                                \
16032 _(lisp_gpe_add_del_iface, "up|down")                                    \
16033 _(lisp_add_del_remote_mapping, "add|del vni <vni> deid <dest-eid> "     \
16034                                "rloc <locator> p <prio> "               \
16035                                "w <weight> [rloc <loc> ... ] "          \
16036                                "action <action> [del-all]")             \
16037 _(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid "     \
16038                           "<src-eid> rloc <locator> p <prio> w <weight>"\
16039                           "[rloc <loc> ... ] action <action>")          \
16040 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
16041 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
16042 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
16043 _(lisp_locator_set_dump, "[locator-set-index <ls-index> | "             \
16044                          "locator-set <loc-set-name>] [local | remote]")\
16045 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
16046                        "[local] | [remote]")                            \
16047 _(lisp_eid_table_vni_dump, "")                                          \
16048 _(lisp_eid_table_map_dump, "l2|l3")                                     \
16049 _(lisp_gpe_tunnel_dump, "")                                             \
16050 _(lisp_map_resolver_dump, "")                                           \
16051 _(show_lisp_status, "")                                                 \
16052 _(lisp_get_map_request_itr_rlocs, "")                                   \
16053 _(show_lisp_pitr, "")                                                   \
16054 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
16055 _(af_packet_delete, "name <host interface name>")                       \
16056 _(policer_add_del, "name <policer name> <params> [del]")                \
16057 _(policer_dump, "[name <policer name>]")                                \
16058 _(policer_classify_set_interface,                                       \
16059   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16060   "  [l2-table <nn>] [del]")                                            \
16061 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
16062 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
16063     "[master|slave]")                                                   \
16064 _(netmap_delete, "name <interface name>")                               \
16065 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16066 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16067 _(mpls_fib_encap_dump, "")                                              \
16068 _(mpls_fib_decap_dump, "")                                              \
16069 _(classify_table_ids, "")                                               \
16070 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
16071 _(classify_table_info, "table_id <nn>")                                 \
16072 _(classify_session_dump, "table_id <nn>")                               \
16073 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
16074     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
16075     "[template_interval <nn>] [udp_checksum]")                          \
16076 _(ipfix_exporter_dump, "")                                              \
16077 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
16078 _(ipfix_classify_stream_dump, "")                                       \
16079 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
16080 _(ipfix_classify_table_dump, "")                                        \
16081 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
16082 _(pg_create_interface, "if_id <nn>")                                    \
16083 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
16084 _(pg_enable_disable, "[stream <id>] disable")                           \
16085 _(ip_source_and_port_range_check_add_del,                               \
16086   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
16087 _(ip_source_and_port_range_check_interface_add_del,                     \
16088   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
16089   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
16090 _(ipsec_gre_add_del_tunnel,                                             \
16091   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
16092 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
16093 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")
16094
16095 /* List of command functions, CLI names map directly to functions */
16096 #define foreach_cli_function                                    \
16097 _(comment, "usage: comment <ignore-rest-of-line>")              \
16098 _(dump_interface_table, "usage: dump_interface_table")          \
16099 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
16100 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
16101 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
16102 _(dump_stats_table, "usage: dump_stats_table")                  \
16103 _(dump_macro_table, "usage: dump_macro_table ")                 \
16104 _(dump_node_table, "usage: dump_node_table")                    \
16105 _(echo, "usage: echo <message>")                                \
16106 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
16107 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
16108 _(help, "usage: help")                                          \
16109 _(q, "usage: quit")                                             \
16110 _(quit, "usage: quit")                                          \
16111 _(search_node_table, "usage: search_node_table <name>...")      \
16112 _(set, "usage: set <variable-name> <value>")                    \
16113 _(script, "usage: script <file-name>")                          \
16114 _(unset, "usage: unset <variable-name>")
16115
16116 #define _(N,n)                                  \
16117     static void vl_api_##n##_t_handler_uni      \
16118     (vl_api_##n##_t * mp)                       \
16119     {                                           \
16120         vat_main_t * vam = &vat_main;           \
16121         if (vam->json_output) {                 \
16122             vl_api_##n##_t_handler_json(mp);    \
16123         } else {                                \
16124             vl_api_##n##_t_handler(mp);         \
16125         }                                       \
16126     }
16127 foreach_vpe_api_reply_msg;
16128 #undef _
16129
16130 void
16131 vat_api_hookup (vat_main_t * vam)
16132 {
16133 #define _(N,n)                                                  \
16134     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
16135                            vl_api_##n##_t_handler_uni,          \
16136                            vl_noop_handler,                     \
16137                            vl_api_##n##_t_endian,               \
16138                            vl_api_##n##_t_print,                \
16139                            sizeof(vl_api_##n##_t), 1);
16140   foreach_vpe_api_reply_msg;
16141 #undef _
16142
16143   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
16144
16145   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
16146
16147   vam->function_by_name = hash_create_string (0, sizeof (uword));
16148
16149   vam->help_by_name = hash_create_string (0, sizeof (uword));
16150
16151   /* API messages we can send */
16152 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
16153   foreach_vpe_api_msg;
16154 #undef _
16155
16156   /* Help strings */
16157 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16158   foreach_vpe_api_msg;
16159 #undef _
16160
16161   /* CLI functions */
16162 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
16163   foreach_cli_function;
16164 #undef _
16165
16166   /* Help strings */
16167 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16168   foreach_cli_function;
16169 #undef _
16170 }
16171
16172 #undef vl_api_version
16173 #define vl_api_version(n,v) static u32 vpe_api_version = v;
16174 #include <vpp-api/vpe.api.h>
16175 #undef vl_api_version
16176
16177 void
16178 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
16179 {
16180   /*
16181    * Send the main API signature in slot 0. This bit of code must
16182    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
16183    */
16184   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
16185 }
16186
16187 /*
16188  * fd.io coding-style-patch-verification: ON
16189  *
16190  * Local Variables:
16191  * eval: (c-set-style "gnu")
16192  * End:
16193  */