VPP-426: Rename parameter in LISP remote mapping VAT command
[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/mpls.h>
39 #if DPDK > 0
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #else
43 #include <inttypes.h>
44 #endif
45 #include <vnet/map/map.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52
53 #include "vat/json_format.h"
54
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248 #if DPDK > 0
249   u32 *r = va_arg (*args, u32 *);
250
251   if (0);
252 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
253   foreach_ipsec_policy_action
254 #undef _
255     else
256     return 0;
257   return 1;
258 #else
259   return 0;
260 #endif
261 }
262
263 uword
264 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
265 {
266 #if DPDK > 0
267   u32 *r = va_arg (*args, u32 *);
268
269   if (0);
270 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
271   foreach_ipsec_crypto_alg
272 #undef _
273     else
274     return 0;
275   return 1;
276 #else
277   return 0;
278 #endif
279 }
280
281 u8 *
282 format_ipsec_crypto_alg (u8 * s, va_list * args)
283 {
284 #if DPDK > 0
285   u32 i = va_arg (*args, u32);
286   u8 *t = 0;
287
288   switch (i)
289     {
290 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
291       foreach_ipsec_crypto_alg
292 #undef _
293     default:
294       return format (s, "unknown");
295     }
296   return format (s, "%s", t);
297 #else
298   return format (s, "Unimplemented");
299 #endif
300 }
301
302 uword
303 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
304 {
305 #if DPDK > 0
306   u32 *r = va_arg (*args, u32 *);
307
308   if (0);
309 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
310   foreach_ipsec_integ_alg
311 #undef _
312     else
313     return 0;
314   return 1;
315 #else
316   return 0;
317 #endif
318 }
319
320 u8 *
321 format_ipsec_integ_alg (u8 * s, va_list * args)
322 {
323 #if DPDK > 0
324   u32 i = va_arg (*args, u32);
325   u8 *t = 0;
326
327   switch (i)
328     {
329 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
330       foreach_ipsec_integ_alg
331 #undef _
332     default:
333       return format (s, "unknown");
334     }
335   return format (s, "%s", t);
336 #else
337   return format (s, "Unsupported");
338 #endif
339 }
340
341 uword
342 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
343 {
344 #if DPDK > 0
345   u32 *r = va_arg (*args, u32 *);
346
347   if (0);
348 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
349   foreach_ikev2_auth_method
350 #undef _
351     else
352     return 0;
353   return 1;
354 #else
355   return 0;
356 #endif
357 }
358
359 uword
360 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
361 {
362 #if DPDK > 0
363   u32 *r = va_arg (*args, u32 *);
364
365   if (0);
366 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
367   foreach_ikev2_id_type
368 #undef _
369     else
370     return 0;
371   return 1;
372 #else
373   return 0;
374 #endif
375 }
376
377 uword
378 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
379 {
380   u8 *r = va_arg (*args, u8 *);
381
382   if (unformat (input, "kbps"))
383     *r = SSE2_QOS_RATE_KBPS;
384   else if (unformat (input, "pps"))
385     *r = SSE2_QOS_RATE_PPS;
386   else
387     return 0;
388   return 1;
389 }
390
391 uword
392 unformat_policer_round_type (unformat_input_t * input, va_list * args)
393 {
394   u8 *r = va_arg (*args, u8 *);
395
396   if (unformat (input, "closest"))
397     *r = SSE2_QOS_ROUND_TO_CLOSEST;
398   else if (unformat (input, "up"))
399     *r = SSE2_QOS_ROUND_TO_UP;
400   else if (unformat (input, "down"))
401     *r = SSE2_QOS_ROUND_TO_DOWN;
402   else
403     return 0;
404   return 1;
405 }
406
407 uword
408 unformat_policer_type (unformat_input_t * input, va_list * args)
409 {
410   u8 *r = va_arg (*args, u8 *);
411
412   if (unformat (input, "1r2c"))
413     *r = SSE2_QOS_POLICER_TYPE_1R2C;
414   else if (unformat (input, "1r3c"))
415     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
416   else if (unformat (input, "2r3c-2698"))
417     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
418   else if (unformat (input, "2r3c-4115"))
419     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
420   else if (unformat (input, "2r3c-mef5cf1"))
421     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
422   else
423     return 0;
424   return 1;
425 }
426
427 uword
428 unformat_dscp (unformat_input_t * input, va_list * va)
429 {
430   u8 *r = va_arg (*va, u8 *);
431
432   if (0);
433 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
434   foreach_vnet_dscp
435 #undef _
436     else
437     return 0;
438   return 1;
439 }
440
441 uword
442 unformat_policer_action_type (unformat_input_t * input, va_list * va)
443 {
444   sse2_qos_pol_action_params_st *a
445     = va_arg (*va, sse2_qos_pol_action_params_st *);
446
447   if (unformat (input, "drop"))
448     a->action_type = SSE2_QOS_ACTION_DROP;
449   else if (unformat (input, "transmit"))
450     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
451   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
452     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
453   else
454     return 0;
455   return 1;
456 }
457
458 uword
459 unformat_classify_table_type (unformat_input_t * input, va_list * va)
460 {
461   u32 *r = va_arg (*va, u32 *);
462   u32 tid;
463
464   if (unformat (input, "ip4"))
465     tid = POLICER_CLASSIFY_TABLE_IP4;
466   else if (unformat (input, "ip6"))
467     tid = POLICER_CLASSIFY_TABLE_IP6;
468   else if (unformat (input, "l2"))
469     tid = POLICER_CLASSIFY_TABLE_L2;
470   else
471     return 0;
472
473   *r = tid;
474   return 1;
475 }
476
477 u8 *
478 format_ip4_address (u8 * s, va_list * args)
479 {
480   u8 *a = va_arg (*args, u8 *);
481   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
482 }
483
484 u8 *
485 format_ip6_address (u8 * s, va_list * args)
486 {
487   ip6_address_t *a = va_arg (*args, ip6_address_t *);
488   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
489
490   i_max_n_zero = ARRAY_LEN (a->as_u16);
491   max_n_zeros = 0;
492   i_first_zero = i_max_n_zero;
493   n_zeros = 0;
494   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
495     {
496       u32 is_zero = a->as_u16[i] == 0;
497       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
498         {
499           i_first_zero = i;
500           n_zeros = 0;
501         }
502       n_zeros += is_zero;
503       if ((!is_zero && n_zeros > max_n_zeros)
504           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
505         {
506           i_max_n_zero = i_first_zero;
507           max_n_zeros = n_zeros;
508           i_first_zero = ARRAY_LEN (a->as_u16);
509           n_zeros = 0;
510         }
511     }
512
513   last_double_colon = 0;
514   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
515     {
516       if (i == i_max_n_zero && max_n_zeros > 1)
517         {
518           s = format (s, "::");
519           i += max_n_zeros - 1;
520           last_double_colon = 1;
521         }
522       else
523         {
524           s = format (s, "%s%x",
525                       (last_double_colon || i == 0) ? "" : ":",
526                       clib_net_to_host_u16 (a->as_u16[i]));
527           last_double_colon = 0;
528         }
529     }
530
531   return s;
532 }
533
534 /* Format an IP46 address. */
535 u8 *
536 format_ip46_address (u8 * s, va_list * args)
537 {
538   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
539   ip46_type_t type = va_arg (*args, ip46_type_t);
540   int is_ip4 = 1;
541
542   switch (type)
543     {
544     case IP46_TYPE_ANY:
545       is_ip4 = ip46_address_is_ip4 (ip46);
546       break;
547     case IP46_TYPE_IP4:
548       is_ip4 = 1;
549       break;
550     case IP46_TYPE_IP6:
551       is_ip4 = 0;
552       break;
553     }
554
555   return is_ip4 ?
556     format (s, "%U", format_ip4_address, &ip46->ip4) :
557     format (s, "%U", format_ip6_address, &ip46->ip6);
558 }
559
560 u8 *
561 format_ethernet_address (u8 * s, va_list * args)
562 {
563   u8 *a = va_arg (*args, u8 *);
564
565   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
566                  a[0], a[1], a[2], a[3], a[4], a[5]);
567 }
568
569 void
570 increment_v4_address (ip4_address_t * a)
571 {
572   u32 v;
573
574   v = ntohl (a->as_u32) + 1;
575   a->as_u32 = ntohl (v);
576 }
577
578 void
579 increment_v6_address (ip6_address_t * a)
580 {
581   u64 v0, v1;
582
583   v0 = clib_net_to_host_u64 (a->as_u64[0]);
584   v1 = clib_net_to_host_u64 (a->as_u64[1]);
585
586   v1 += 1;
587   if (v1 == 0)
588     v0 += 1;
589   a->as_u64[0] = clib_net_to_host_u64 (v0);
590   a->as_u64[1] = clib_net_to_host_u64 (v1);
591 }
592
593 void
594 increment_mac_address (u64 * mac)
595 {
596   u64 tmp = *mac;
597
598   tmp = clib_net_to_host_u64 (tmp);
599   tmp += 1 << 16;               /* skip unused (least significant) octets */
600   tmp = clib_host_to_net_u64 (tmp);
601   *mac = tmp;
602 }
603
604 static void vl_api_create_loopback_reply_t_handler
605   (vl_api_create_loopback_reply_t * mp)
606 {
607   vat_main_t *vam = &vat_main;
608   i32 retval = ntohl (mp->retval);
609
610   vam->retval = retval;
611   vam->regenerate_interface_table = 1;
612   vam->sw_if_index = ntohl (mp->sw_if_index);
613   vam->result_ready = 1;
614 }
615
616 static void vl_api_create_loopback_reply_t_handler_json
617   (vl_api_create_loopback_reply_t * mp)
618 {
619   vat_main_t *vam = &vat_main;
620   vat_json_node_t node;
621
622   vat_json_init_object (&node);
623   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
624   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
625
626   vat_json_print (vam->ofp, &node);
627   vat_json_free (&node);
628   vam->retval = ntohl (mp->retval);
629   vam->result_ready = 1;
630 }
631
632 static void vl_api_af_packet_create_reply_t_handler
633   (vl_api_af_packet_create_reply_t * mp)
634 {
635   vat_main_t *vam = &vat_main;
636   i32 retval = ntohl (mp->retval);
637
638   vam->retval = retval;
639   vam->regenerate_interface_table = 1;
640   vam->sw_if_index = ntohl (mp->sw_if_index);
641   vam->result_ready = 1;
642 }
643
644 static void vl_api_af_packet_create_reply_t_handler_json
645   (vl_api_af_packet_create_reply_t * mp)
646 {
647   vat_main_t *vam = &vat_main;
648   vat_json_node_t node;
649
650   vat_json_init_object (&node);
651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
652   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
653
654   vat_json_print (vam->ofp, &node);
655   vat_json_free (&node);
656
657   vam->retval = ntohl (mp->retval);
658   vam->result_ready = 1;
659 }
660
661 static void vl_api_create_vlan_subif_reply_t_handler
662   (vl_api_create_vlan_subif_reply_t * mp)
663 {
664   vat_main_t *vam = &vat_main;
665   i32 retval = ntohl (mp->retval);
666
667   vam->retval = retval;
668   vam->regenerate_interface_table = 1;
669   vam->sw_if_index = ntohl (mp->sw_if_index);
670   vam->result_ready = 1;
671 }
672
673 static void vl_api_create_vlan_subif_reply_t_handler_json
674   (vl_api_create_vlan_subif_reply_t * mp)
675 {
676   vat_main_t *vam = &vat_main;
677   vat_json_node_t node;
678
679   vat_json_init_object (&node);
680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
681   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
682
683   vat_json_print (vam->ofp, &node);
684   vat_json_free (&node);
685
686   vam->retval = ntohl (mp->retval);
687   vam->result_ready = 1;
688 }
689
690 static void vl_api_create_subif_reply_t_handler
691   (vl_api_create_subif_reply_t * mp)
692 {
693   vat_main_t *vam = &vat_main;
694   i32 retval = ntohl (mp->retval);
695
696   vam->retval = retval;
697   vam->regenerate_interface_table = 1;
698   vam->sw_if_index = ntohl (mp->sw_if_index);
699   vam->result_ready = 1;
700 }
701
702 static void vl_api_create_subif_reply_t_handler_json
703   (vl_api_create_subif_reply_t * mp)
704 {
705   vat_main_t *vam = &vat_main;
706   vat_json_node_t node;
707
708   vat_json_init_object (&node);
709   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
710   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
711
712   vat_json_print (vam->ofp, &node);
713   vat_json_free (&node);
714
715   vam->retval = ntohl (mp->retval);
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   i32 retval = ntohl (mp->retval);
724
725   vam->retval = retval;
726   vam->regenerate_interface_table = 1;
727   vam->result_ready = 1;
728 }
729
730 static void vl_api_interface_name_renumber_reply_t_handler_json
731   (vl_api_interface_name_renumber_reply_t * mp)
732 {
733   vat_main_t *vam = &vat_main;
734   vat_json_node_t node;
735
736   vat_json_init_object (&node);
737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
738
739   vat_json_print (vam->ofp, &node);
740   vat_json_free (&node);
741
742   vam->retval = ntohl (mp->retval);
743   vam->result_ready = 1;
744 }
745
746 /*
747  * Special-case: build the interface table, maintain
748  * the next loopback sw_if_index vbl.
749  */
750 static void vl_api_sw_interface_details_t_handler
751   (vl_api_sw_interface_details_t * mp)
752 {
753   vat_main_t *vam = &vat_main;
754   u8 *s = format (0, "%s%c", mp->interface_name, 0);
755
756   hash_set_mem (vam->sw_if_index_by_interface_name, s,
757                 ntohl (mp->sw_if_index));
758
759   /* In sub interface case, fill the sub interface table entry */
760   if (mp->sw_if_index != mp->sup_sw_if_index)
761     {
762       sw_interface_subif_t *sub = NULL;
763
764       vec_add2 (vam->sw_if_subif_table, sub, 1);
765
766       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
767       strncpy ((char *) sub->interface_name, (char *) s,
768                vec_len (sub->interface_name));
769       sub->sw_if_index = ntohl (mp->sw_if_index);
770       sub->sub_id = ntohl (mp->sub_id);
771
772       sub->sub_dot1ad = mp->sub_dot1ad;
773       sub->sub_number_of_tags = mp->sub_number_of_tags;
774       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
775       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
776       sub->sub_exact_match = mp->sub_exact_match;
777       sub->sub_default = mp->sub_default;
778       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
779       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
780
781       /* vlan tag rewrite */
782       sub->vtr_op = ntohl (mp->vtr_op);
783       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
784       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
785       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
786     }
787 }
788
789 static void vl_api_sw_interface_details_t_handler_json
790   (vl_api_sw_interface_details_t * mp)
791 {
792   vat_main_t *vam = &vat_main;
793   vat_json_node_t *node = NULL;
794
795   if (VAT_JSON_ARRAY != vam->json_tree.type)
796     {
797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
798       vat_json_init_array (&vam->json_tree);
799     }
800   node = vat_json_array_add (&vam->json_tree);
801
802   vat_json_init_object (node);
803   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
804   vat_json_object_add_uint (node, "sup_sw_if_index",
805                             ntohl (mp->sup_sw_if_index));
806   vat_json_object_add_uint (node, "l2_address_length",
807                             ntohl (mp->l2_address_length));
808   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
809                              sizeof (mp->l2_address));
810   vat_json_object_add_string_copy (node, "interface_name",
811                                    mp->interface_name);
812   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
813   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
814   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
815   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
816   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
817   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
818   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
819   vat_json_object_add_uint (node, "sub_number_of_tags",
820                             mp->sub_number_of_tags);
821   vat_json_object_add_uint (node, "sub_outer_vlan_id",
822                             ntohs (mp->sub_outer_vlan_id));
823   vat_json_object_add_uint (node, "sub_inner_vlan_id",
824                             ntohs (mp->sub_inner_vlan_id));
825   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
826   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
827   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
828                             mp->sub_outer_vlan_id_any);
829   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
830                             mp->sub_inner_vlan_id_any);
831   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
832   vat_json_object_add_uint (node, "vtr_push_dot1q",
833                             ntohl (mp->vtr_push_dot1q));
834   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
835   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   vat_main_t *vam = &vat_main;
842   if (vam->interface_event_display)
843     errmsg ("interface flags: sw_if_index %d %s %s\n",
844             ntohl (mp->sw_if_index),
845             mp->admin_up_down ? "admin-up" : "admin-down",
846             mp->link_up_down ? "link-up" : "link-down");
847 }
848
849 static void vl_api_sw_interface_set_flags_t_handler_json
850   (vl_api_sw_interface_set_flags_t * mp)
851 {
852   /* JSON output not supported */
853 }
854
855 static void
856 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->shmem_result = (u8 *) mp->reply_in_shmem;
863   vam->result_ready = 1;
864 }
865
866 static void
867 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
868 {
869   vat_main_t *vam = &vat_main;
870   vat_json_node_t node;
871   api_main_t *am = &api_main;
872   void *oldheap;
873   u8 *reply;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "reply_in_shmem",
878                             ntohl (mp->reply_in_shmem));
879   /* Toss the shared-memory original... */
880   pthread_mutex_lock (&am->vlib_rp->mutex);
881   oldheap = svm_push_data_heap (am->vlib_rp);
882
883   reply = (u8 *) (mp->reply_in_shmem);
884   vec_free (reply);
885
886   svm_pop_heap (oldheap);
887   pthread_mutex_unlock (&am->vlib_rp->mutex);
888
889   vat_json_print (vam->ofp, &node);
890   vat_json_free (&node);
891
892   vam->retval = ntohl (mp->retval);
893   vam->result_ready = 1;
894 }
895
896 static void
897 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   i32 retval = ntohl (mp->retval);
901
902   vam->retval = retval;
903   vam->cmd_reply = mp->reply;
904   vam->result_ready = 1;
905 }
906
907 static void
908 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
909 {
910   vat_main_t *vam = &vat_main;
911   vat_json_node_t node;
912
913   vat_json_init_object (&node);
914   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
915   vat_json_object_add_string_copy (&node, "reply", mp->reply);
916
917   vat_json_print (vam->ofp, &node);
918   vat_json_free (&node);
919
920   vam->retval = ntohl (mp->retval);
921   vam->result_ready = 1;
922 }
923
924 static void vl_api_classify_add_del_table_reply_t_handler
925   (vl_api_classify_add_del_table_reply_t * mp)
926 {
927   vat_main_t *vam = &vat_main;
928   i32 retval = ntohl (mp->retval);
929   if (vam->async_mode)
930     {
931       vam->async_errors += (retval < 0);
932     }
933   else
934     {
935       vam->retval = retval;
936       if (retval == 0 &&
937           ((mp->new_table_index != 0xFFFFFFFF) ||
938            (mp->skip_n_vectors != 0xFFFFFFFF) ||
939            (mp->match_n_vectors != 0xFFFFFFFF)))
940         /*
941          * Note: this is just barely thread-safe, depends on
942          * the main thread spinning waiting for an answer...
943          */
944         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
945                 ntohl (mp->new_table_index),
946                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
947       vam->result_ready = 1;
948     }
949 }
950
951 static void vl_api_classify_add_del_table_reply_t_handler_json
952   (vl_api_classify_add_del_table_reply_t * mp)
953 {
954   vat_main_t *vam = &vat_main;
955   vat_json_node_t node;
956
957   vat_json_init_object (&node);
958   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
959   vat_json_object_add_uint (&node, "new_table_index",
960                             ntohl (mp->new_table_index));
961   vat_json_object_add_uint (&node, "skip_n_vectors",
962                             ntohl (mp->skip_n_vectors));
963   vat_json_object_add_uint (&node, "match_n_vectors",
964                             ntohl (mp->match_n_vectors));
965
966   vat_json_print (vam->ofp, &node);
967   vat_json_free (&node);
968
969   vam->retval = ntohl (mp->retval);
970   vam->result_ready = 1;
971 }
972
973 static void vl_api_get_node_index_reply_t_handler
974   (vl_api_get_node_index_reply_t * mp)
975 {
976   vat_main_t *vam = &vat_main;
977   i32 retval = ntohl (mp->retval);
978   if (vam->async_mode)
979     {
980       vam->async_errors += (retval < 0);
981     }
982   else
983     {
984       vam->retval = retval;
985       if (retval == 0)
986         errmsg ("node index %d\n", ntohl (mp->node_index));
987       vam->result_ready = 1;
988     }
989 }
990
991 static void vl_api_get_node_index_reply_t_handler_json
992   (vl_api_get_node_index_reply_t * mp)
993 {
994   vat_main_t *vam = &vat_main;
995   vat_json_node_t node;
996
997   vat_json_init_object (&node);
998   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
999   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1000
1001   vat_json_print (vam->ofp, &node);
1002   vat_json_free (&node);
1003
1004   vam->retval = ntohl (mp->retval);
1005   vam->result_ready = 1;
1006 }
1007
1008 static void vl_api_get_next_index_reply_t_handler
1009   (vl_api_get_next_index_reply_t * mp)
1010 {
1011   vat_main_t *vam = &vat_main;
1012   i32 retval = ntohl (mp->retval);
1013   if (vam->async_mode)
1014     {
1015       vam->async_errors += (retval < 0);
1016     }
1017   else
1018     {
1019       vam->retval = retval;
1020       if (retval == 0)
1021         errmsg ("next node index %d\n", ntohl (mp->next_index));
1022       vam->result_ready = 1;
1023     }
1024 }
1025
1026 static void vl_api_get_next_index_reply_t_handler_json
1027   (vl_api_get_next_index_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   vat_json_node_t node;
1031
1032   vat_json_init_object (&node);
1033   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1034   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1035
1036   vat_json_print (vam->ofp, &node);
1037   vat_json_free (&node);
1038
1039   vam->retval = ntohl (mp->retval);
1040   vam->result_ready = 1;
1041 }
1042
1043 static void vl_api_add_node_next_reply_t_handler
1044   (vl_api_add_node_next_reply_t * mp)
1045 {
1046   vat_main_t *vam = &vat_main;
1047   i32 retval = ntohl (mp->retval);
1048   if (vam->async_mode)
1049     {
1050       vam->async_errors += (retval < 0);
1051     }
1052   else
1053     {
1054       vam->retval = retval;
1055       if (retval == 0)
1056         errmsg ("next index %d\n", ntohl (mp->next_index));
1057       vam->result_ready = 1;
1058     }
1059 }
1060
1061 static void vl_api_add_node_next_reply_t_handler_json
1062   (vl_api_add_node_next_reply_t * mp)
1063 {
1064   vat_main_t *vam = &vat_main;
1065   vat_json_node_t node;
1066
1067   vat_json_init_object (&node);
1068   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1069   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1070
1071   vat_json_print (vam->ofp, &node);
1072   vat_json_free (&node);
1073
1074   vam->retval = ntohl (mp->retval);
1075   vam->result_ready = 1;
1076 }
1077
1078 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
1079   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1080 {
1081   vat_main_t *vam = &vat_main;
1082   i32 retval = ntohl (mp->retval);
1083   u32 sw_if_index = ntohl (mp->tunnel_sw_if_index);
1084
1085   if (retval >= 0 && sw_if_index != (u32) ~ 0)
1086     {
1087       errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1088     }
1089   vam->retval = retval;
1090   vam->result_ready = 1;
1091 }
1092
1093 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1094   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1095 {
1096   vat_main_t *vam = &vat_main;
1097   vat_json_node_t node;
1098
1099   vat_json_init_object (&node);
1100   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1101   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1102                             ntohl (mp->tunnel_sw_if_index));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111
1112 static void vl_api_show_version_reply_t_handler
1113   (vl_api_show_version_reply_t * mp)
1114 {
1115   vat_main_t *vam = &vat_main;
1116   i32 retval = ntohl (mp->retval);
1117
1118   if (retval >= 0)
1119     {
1120       errmsg ("        program: %s\n", mp->program);
1121       errmsg ("        version: %s\n", mp->version);
1122       errmsg ("     build date: %s\n", mp->build_date);
1123       errmsg ("build directory: %s\n", mp->build_directory);
1124     }
1125   vam->retval = retval;
1126   vam->result_ready = 1;
1127 }
1128
1129 static void vl_api_show_version_reply_t_handler_json
1130   (vl_api_show_version_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_string_copy (&node, "program", mp->program);
1138   vat_json_object_add_string_copy (&node, "version", mp->version);
1139   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1140   vat_json_object_add_string_copy (&node, "build_directory",
1141                                    mp->build_directory);
1142
1143   vat_json_print (vam->ofp, &node);
1144   vat_json_free (&node);
1145
1146   vam->retval = ntohl (mp->retval);
1147   vam->result_ready = 1;
1148 }
1149
1150 static void
1151 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1152 {
1153   vat_main_t *vam = &vat_main;
1154   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1155           mp->mac_ip ? "mac/ip binding" : "address resolution",
1156           format_ip4_address, &mp->address,
1157           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1158 }
1159
1160 static void
1161 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1162 {
1163   /* JSON output not supported */
1164 }
1165
1166 static void
1167 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1168 {
1169   vat_main_t *vam = &vat_main;
1170   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1171           mp->mac_ip ? "mac/ip binding" : "address resolution",
1172           format_ip6_address, mp->address,
1173           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1174 }
1175
1176 static void
1177 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1178 {
1179   /* JSON output not supported */
1180 }
1181
1182 /*
1183  * Special-case: build the bridge domain table, maintain
1184  * the next bd id vbl.
1185  */
1186 static void vl_api_bridge_domain_details_t_handler
1187   (vl_api_bridge_domain_details_t * mp)
1188 {
1189   vat_main_t *vam = &vat_main;
1190   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1191
1192   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1193            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1194
1195   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1196            ntohl (mp->bd_id), mp->learn, mp->forward,
1197            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1198
1199   if (n_sw_ifs)
1200     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1201              "Interface Name");
1202 }
1203
1204 static void vl_api_bridge_domain_details_t_handler_json
1205   (vl_api_bridge_domain_details_t * mp)
1206 {
1207   vat_main_t *vam = &vat_main;
1208   vat_json_node_t *node, *array = NULL;
1209
1210   if (VAT_JSON_ARRAY != vam->json_tree.type)
1211     {
1212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1213       vat_json_init_array (&vam->json_tree);
1214     }
1215   node = vat_json_array_add (&vam->json_tree);
1216
1217   vat_json_init_object (node);
1218   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1219   vat_json_object_add_uint (node, "flood", mp->flood);
1220   vat_json_object_add_uint (node, "forward", mp->forward);
1221   vat_json_object_add_uint (node, "learn", mp->learn);
1222   vat_json_object_add_uint (node, "bvi_sw_if_index",
1223                             ntohl (mp->bvi_sw_if_index));
1224   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1225   array = vat_json_object_add (node, "sw_if");
1226   vat_json_init_array (array);
1227 }
1228
1229 /*
1230  * Special-case: build the bridge domain sw if table.
1231  */
1232 static void vl_api_bridge_domain_sw_if_details_t_handler
1233   (vl_api_bridge_domain_sw_if_details_t * mp)
1234 {
1235   vat_main_t *vam = &vat_main;
1236   hash_pair_t *p;
1237   u8 *sw_if_name = 0;
1238   u32 sw_if_index;
1239
1240   sw_if_index = ntohl (mp->sw_if_index);
1241   /* *INDENT-OFF* */
1242   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1243   ({
1244     if ((u32) p->value[0] == sw_if_index)
1245       {
1246         sw_if_name = (u8 *)(p->key);
1247         break;
1248       }
1249   }));
1250   /* *INDENT-ON* */
1251
1252   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1253            mp->shg, sw_if_name ? (char *) sw_if_name :
1254            "sw_if_index not found!");
1255 }
1256
1257 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1258   (vl_api_bridge_domain_sw_if_details_t * mp)
1259 {
1260   vat_main_t *vam = &vat_main;
1261   vat_json_node_t *node = NULL;
1262   uword last_index = 0;
1263
1264   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1265   ASSERT (vec_len (vam->json_tree.array) >= 1);
1266   last_index = vec_len (vam->json_tree.array) - 1;
1267   node = &vam->json_tree.array[last_index];
1268   node = vat_json_object_get_element (node, "sw_if");
1269   ASSERT (NULL != node);
1270   node = vat_json_array_add (node);
1271
1272   vat_json_init_object (node);
1273   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1274   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1275   vat_json_object_add_uint (node, "shg", mp->shg);
1276 }
1277
1278 static void vl_api_control_ping_reply_t_handler
1279   (vl_api_control_ping_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   i32 retval = ntohl (mp->retval);
1283   if (vam->async_mode)
1284     {
1285       vam->async_errors += (retval < 0);
1286     }
1287   else
1288     {
1289       vam->retval = retval;
1290       vam->result_ready = 1;
1291     }
1292 }
1293
1294 static void vl_api_control_ping_reply_t_handler_json
1295   (vl_api_control_ping_reply_t * mp)
1296 {
1297   vat_main_t *vam = &vat_main;
1298   i32 retval = ntohl (mp->retval);
1299
1300   if (VAT_JSON_NONE != vam->json_tree.type)
1301     {
1302       vat_json_print (vam->ofp, &vam->json_tree);
1303       vat_json_free (&vam->json_tree);
1304       vam->json_tree.type = VAT_JSON_NONE;
1305     }
1306   else
1307     {
1308       /* just print [] */
1309       vat_json_init_array (&vam->json_tree);
1310       vat_json_print (vam->ofp, &vam->json_tree);
1311       vam->json_tree.type = VAT_JSON_NONE;
1312     }
1313
1314   vam->retval = retval;
1315   vam->result_ready = 1;
1316 }
1317
1318 static void
1319 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1320 {
1321   vat_main_t *vam = &vat_main;
1322   i32 retval = ntohl (mp->retval);
1323   if (vam->async_mode)
1324     {
1325       vam->async_errors += (retval < 0);
1326     }
1327   else
1328     {
1329       vam->retval = retval;
1330       vam->result_ready = 1;
1331     }
1332 }
1333
1334 static void vl_api_l2_flags_reply_t_handler_json
1335   (vl_api_l2_flags_reply_t * mp)
1336 {
1337   vat_main_t *vam = &vat_main;
1338   vat_json_node_t node;
1339
1340   vat_json_init_object (&node);
1341   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1342   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1343                             ntohl (mp->resulting_feature_bitmap));
1344
1345   vat_json_print (vam->ofp, &node);
1346   vat_json_free (&node);
1347
1348   vam->retval = ntohl (mp->retval);
1349   vam->result_ready = 1;
1350 }
1351
1352 static void vl_api_bridge_flags_reply_t_handler
1353   (vl_api_bridge_flags_reply_t * mp)
1354 {
1355   vat_main_t *vam = &vat_main;
1356   i32 retval = ntohl (mp->retval);
1357   if (vam->async_mode)
1358     {
1359       vam->async_errors += (retval < 0);
1360     }
1361   else
1362     {
1363       vam->retval = retval;
1364       vam->result_ready = 1;
1365     }
1366 }
1367
1368 static void vl_api_bridge_flags_reply_t_handler_json
1369   (vl_api_bridge_flags_reply_t * mp)
1370 {
1371   vat_main_t *vam = &vat_main;
1372   vat_json_node_t node;
1373
1374   vat_json_init_object (&node);
1375   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1376   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1377                             ntohl (mp->resulting_feature_bitmap));
1378
1379   vat_json_print (vam->ofp, &node);
1380   vat_json_free (&node);
1381
1382   vam->retval = ntohl (mp->retval);
1383   vam->result_ready = 1;
1384 }
1385
1386 static void vl_api_tap_connect_reply_t_handler
1387   (vl_api_tap_connect_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   i32 retval = ntohl (mp->retval);
1391   if (vam->async_mode)
1392     {
1393       vam->async_errors += (retval < 0);
1394     }
1395   else
1396     {
1397       vam->retval = retval;
1398       vam->sw_if_index = ntohl (mp->sw_if_index);
1399       vam->result_ready = 1;
1400     }
1401
1402 }
1403
1404 static void vl_api_tap_connect_reply_t_handler_json
1405   (vl_api_tap_connect_reply_t * mp)
1406 {
1407   vat_main_t *vam = &vat_main;
1408   vat_json_node_t node;
1409
1410   vat_json_init_object (&node);
1411   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1412   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1413
1414   vat_json_print (vam->ofp, &node);
1415   vat_json_free (&node);
1416
1417   vam->retval = ntohl (mp->retval);
1418   vam->result_ready = 1;
1419
1420 }
1421
1422 static void
1423 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1424 {
1425   vat_main_t *vam = &vat_main;
1426   i32 retval = ntohl (mp->retval);
1427   if (vam->async_mode)
1428     {
1429       vam->async_errors += (retval < 0);
1430     }
1431   else
1432     {
1433       vam->retval = retval;
1434       vam->sw_if_index = ntohl (mp->sw_if_index);
1435       vam->result_ready = 1;
1436     }
1437 }
1438
1439 static void vl_api_tap_modify_reply_t_handler_json
1440   (vl_api_tap_modify_reply_t * mp)
1441 {
1442   vat_main_t *vam = &vat_main;
1443   vat_json_node_t node;
1444
1445   vat_json_init_object (&node);
1446   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1447   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1448
1449   vat_json_print (vam->ofp, &node);
1450   vat_json_free (&node);
1451
1452   vam->retval = ntohl (mp->retval);
1453   vam->result_ready = 1;
1454 }
1455
1456 static void
1457 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1458 {
1459   vat_main_t *vam = &vat_main;
1460   i32 retval = ntohl (mp->retval);
1461   if (vam->async_mode)
1462     {
1463       vam->async_errors += (retval < 0);
1464     }
1465   else
1466     {
1467       vam->retval = retval;
1468       vam->result_ready = 1;
1469     }
1470 }
1471
1472 static void vl_api_tap_delete_reply_t_handler_json
1473   (vl_api_tap_delete_reply_t * mp)
1474 {
1475   vat_main_t *vam = &vat_main;
1476   vat_json_node_t node;
1477
1478   vat_json_init_object (&node);
1479   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1480
1481   vat_json_print (vam->ofp, &node);
1482   vat_json_free (&node);
1483
1484   vam->retval = ntohl (mp->retval);
1485   vam->result_ready = 1;
1486 }
1487
1488 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1489   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1490 {
1491   vat_main_t *vam = &vat_main;
1492   i32 retval = ntohl (mp->retval);
1493   if (vam->async_mode)
1494     {
1495       vam->async_errors += (retval < 0);
1496     }
1497   else
1498     {
1499       vam->retval = retval;
1500       vam->result_ready = 1;
1501     }
1502 }
1503
1504 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1505   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1506 {
1507   vat_main_t *vam = &vat_main;
1508   vat_json_node_t node;
1509
1510   vat_json_init_object (&node);
1511   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1512   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1513                             ntohl (mp->tunnel_sw_if_index));
1514
1515   vat_json_print (vam->ofp, &node);
1516   vat_json_free (&node);
1517
1518   vam->retval = ntohl (mp->retval);
1519   vam->result_ready = 1;
1520 }
1521
1522 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1523   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1524 {
1525   vat_main_t *vam = &vat_main;
1526   i32 retval = ntohl (mp->retval);
1527   if (vam->async_mode)
1528     {
1529       vam->async_errors += (retval < 0);
1530     }
1531   else
1532     {
1533       vam->retval = retval;
1534       vam->sw_if_index = ntohl (mp->sw_if_index);
1535       vam->result_ready = 1;
1536     }
1537 }
1538
1539 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1540   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1541 {
1542   vat_main_t *vam = &vat_main;
1543   vat_json_node_t node;
1544
1545   vat_json_init_object (&node);
1546   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1547   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1548
1549   vat_json_print (vam->ofp, &node);
1550   vat_json_free (&node);
1551
1552   vam->retval = ntohl (mp->retval);
1553   vam->result_ready = 1;
1554 }
1555
1556
1557 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1558   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1559 {
1560   vat_main_t *vam = &vat_main;
1561   i32 retval = ntohl (mp->retval);
1562   if (vam->async_mode)
1563     {
1564       vam->async_errors += (retval < 0);
1565     }
1566   else
1567     {
1568       vam->retval = retval;
1569       vam->result_ready = 1;
1570     }
1571 }
1572
1573 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1574   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1575 {
1576   vat_main_t *vam = &vat_main;
1577   vat_json_node_t node;
1578
1579   vat_json_init_object (&node);
1580   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1581   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1582
1583   vat_json_print (vam->ofp, &node);
1584   vat_json_free (&node);
1585
1586   vam->retval = ntohl (mp->retval);
1587   vam->result_ready = 1;
1588 }
1589
1590 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1591   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1592 {
1593   vat_main_t *vam = &vat_main;
1594   i32 retval = ntohl (mp->retval);
1595   if (vam->async_mode)
1596     {
1597       vam->async_errors += (retval < 0);
1598     }
1599   else
1600     {
1601       vam->retval = retval;
1602       vam->sw_if_index = ntohl (mp->sw_if_index);
1603       vam->result_ready = 1;
1604     }
1605 }
1606
1607 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1608   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1609 {
1610   vat_main_t *vam = &vat_main;
1611   vat_json_node_t node;
1612
1613   vat_json_init_object (&node);
1614   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1615   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1616
1617   vat_json_print (vam->ofp, &node);
1618   vat_json_free (&node);
1619
1620   vam->retval = ntohl (mp->retval);
1621   vam->result_ready = 1;
1622 }
1623
1624 static void vl_api_gre_add_del_tunnel_reply_t_handler
1625   (vl_api_gre_add_del_tunnel_reply_t * mp)
1626 {
1627   vat_main_t *vam = &vat_main;
1628   i32 retval = ntohl (mp->retval);
1629   if (vam->async_mode)
1630     {
1631       vam->async_errors += (retval < 0);
1632     }
1633   else
1634     {
1635       vam->retval = retval;
1636       vam->sw_if_index = ntohl (mp->sw_if_index);
1637       vam->result_ready = 1;
1638     }
1639 }
1640
1641 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1642   (vl_api_gre_add_del_tunnel_reply_t * mp)
1643 {
1644   vat_main_t *vam = &vat_main;
1645   vat_json_node_t node;
1646
1647   vat_json_init_object (&node);
1648   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1649   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1650
1651   vat_json_print (vam->ofp, &node);
1652   vat_json_free (&node);
1653
1654   vam->retval = ntohl (mp->retval);
1655   vam->result_ready = 1;
1656 }
1657
1658 static void vl_api_create_vhost_user_if_reply_t_handler
1659   (vl_api_create_vhost_user_if_reply_t * mp)
1660 {
1661   vat_main_t *vam = &vat_main;
1662   i32 retval = ntohl (mp->retval);
1663   if (vam->async_mode)
1664     {
1665       vam->async_errors += (retval < 0);
1666     }
1667   else
1668     {
1669       vam->retval = retval;
1670       vam->sw_if_index = ntohl (mp->sw_if_index);
1671       vam->result_ready = 1;
1672     }
1673 }
1674
1675 static void vl_api_create_vhost_user_if_reply_t_handler_json
1676   (vl_api_create_vhost_user_if_reply_t * mp)
1677 {
1678   vat_main_t *vam = &vat_main;
1679   vat_json_node_t node;
1680
1681   vat_json_init_object (&node);
1682   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1683   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1684
1685   vat_json_print (vam->ofp, &node);
1686   vat_json_free (&node);
1687
1688   vam->retval = ntohl (mp->retval);
1689   vam->result_ready = 1;
1690 }
1691
1692 static void vl_api_ip_address_details_t_handler
1693   (vl_api_ip_address_details_t * mp)
1694 {
1695   vat_main_t *vam = &vat_main;
1696   static ip_address_details_t empty_ip_address_details = { {0} };
1697   ip_address_details_t *address = NULL;
1698   ip_details_t *current_ip_details = NULL;
1699   ip_details_t *details = NULL;
1700
1701   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1702
1703   if (!details || vam->current_sw_if_index >= vec_len (details)
1704       || !details[vam->current_sw_if_index].present)
1705     {
1706       errmsg ("ip address details arrived but not stored\n");
1707       errmsg ("ip_dump should be called first\n");
1708       return;
1709     }
1710
1711   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1712
1713 #define addresses (current_ip_details->addr)
1714
1715   vec_validate_init_empty (addresses, vec_len (addresses),
1716                            empty_ip_address_details);
1717
1718   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1719
1720   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1721   address->prefix_length = mp->prefix_length;
1722 #undef addresses
1723 }
1724
1725 static void vl_api_ip_address_details_t_handler_json
1726   (vl_api_ip_address_details_t * mp)
1727 {
1728   vat_main_t *vam = &vat_main;
1729   vat_json_node_t *node = NULL;
1730   struct in6_addr ip6;
1731   struct in_addr ip4;
1732
1733   if (VAT_JSON_ARRAY != vam->json_tree.type)
1734     {
1735       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1736       vat_json_init_array (&vam->json_tree);
1737     }
1738   node = vat_json_array_add (&vam->json_tree);
1739
1740   vat_json_init_object (node);
1741   if (vam->is_ipv6)
1742     {
1743       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1744       vat_json_object_add_ip6 (node, "ip", ip6);
1745     }
1746   else
1747     {
1748       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1749       vat_json_object_add_ip4 (node, "ip", ip4);
1750     }
1751   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1752 }
1753
1754 static void
1755 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1756 {
1757   vat_main_t *vam = &vat_main;
1758   static ip_details_t empty_ip_details = { 0 };
1759   ip_details_t *ip = NULL;
1760   u32 sw_if_index = ~0;
1761
1762   sw_if_index = ntohl (mp->sw_if_index);
1763
1764   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1765                            sw_if_index, empty_ip_details);
1766
1767   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1768                          sw_if_index);
1769
1770   ip->present = 1;
1771 }
1772
1773 static void
1774 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1775 {
1776   vat_main_t *vam = &vat_main;
1777
1778   if (VAT_JSON_ARRAY != vam->json_tree.type)
1779     {
1780       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1781       vat_json_init_array (&vam->json_tree);
1782     }
1783   vat_json_array_add_uint (&vam->json_tree,
1784                            clib_net_to_host_u32 (mp->sw_if_index));
1785 }
1786
1787 static void vl_api_map_domain_details_t_handler_json
1788   (vl_api_map_domain_details_t * mp)
1789 {
1790   vat_json_node_t *node = NULL;
1791   vat_main_t *vam = &vat_main;
1792   struct in6_addr ip6;
1793   struct in_addr ip4;
1794
1795   if (VAT_JSON_ARRAY != vam->json_tree.type)
1796     {
1797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1798       vat_json_init_array (&vam->json_tree);
1799     }
1800
1801   node = vat_json_array_add (&vam->json_tree);
1802   vat_json_init_object (node);
1803
1804   vat_json_object_add_uint (node, "domain_index",
1805                             clib_net_to_host_u32 (mp->domain_index));
1806   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1807   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1808   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1809   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1810   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1811   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1812   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1813   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1814   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1815   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1816   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1817   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1818   vat_json_object_add_uint (node, "flags", mp->flags);
1819   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1820   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1821 }
1822
1823 static void vl_api_map_domain_details_t_handler
1824   (vl_api_map_domain_details_t * mp)
1825 {
1826   vat_main_t *vam = &vat_main;
1827
1828   if (mp->is_translation)
1829     {
1830       fformat (vam->ofp,
1831                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1832                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1833                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1834                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1835                clib_net_to_host_u32 (mp->domain_index));
1836     }
1837   else
1838     {
1839       fformat (vam->ofp,
1840                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1841                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1842                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1843                format_ip6_address, mp->ip6_src,
1844                clib_net_to_host_u32 (mp->domain_index));
1845     }
1846   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1847            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1848            mp->is_translation ? "map-t" : "");
1849 }
1850
1851 static void vl_api_map_rule_details_t_handler_json
1852   (vl_api_map_rule_details_t * mp)
1853 {
1854   struct in6_addr ip6;
1855   vat_json_node_t *node = NULL;
1856   vat_main_t *vam = &vat_main;
1857
1858   if (VAT_JSON_ARRAY != vam->json_tree.type)
1859     {
1860       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1861       vat_json_init_array (&vam->json_tree);
1862     }
1863
1864   node = vat_json_array_add (&vam->json_tree);
1865   vat_json_init_object (node);
1866
1867   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1868   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1869   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1870 }
1871
1872 static void
1873 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1874 {
1875   vat_main_t *vam = &vat_main;
1876   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1877            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1878 }
1879
1880 static void
1881 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1882 {
1883   vat_main_t *vam = &vat_main;
1884   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1885           "router_addr %U host_mac %U\n",
1886           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1887           format_ip4_address, &mp->host_address,
1888           format_ip4_address, &mp->router_address,
1889           format_ethernet_address, mp->host_mac);
1890 }
1891
1892 static void vl_api_dhcp_compl_event_t_handler_json
1893   (vl_api_dhcp_compl_event_t * mp)
1894 {
1895   /* JSON output not supported */
1896 }
1897
1898 static void
1899 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1900                               u32 counter)
1901 {
1902   vat_main_t *vam = &vat_main;
1903   static u64 default_counter = 0;
1904
1905   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1906                            NULL);
1907   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1908                            sw_if_index, default_counter);
1909   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1910 }
1911
1912 static void
1913 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1914                                 interface_counter_t counter)
1915 {
1916   vat_main_t *vam = &vat_main;
1917   static interface_counter_t default_counter = { 0, };
1918
1919   vec_validate_init_empty (vam->combined_interface_counters,
1920                            vnet_counter_type, NULL);
1921   vec_validate_init_empty (vam->combined_interface_counters
1922                            [vnet_counter_type], sw_if_index, default_counter);
1923   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1924 }
1925
1926 static void vl_api_vnet_interface_counters_t_handler
1927   (vl_api_vnet_interface_counters_t * mp)
1928 {
1929   /* not supported */
1930 }
1931
1932 static void vl_api_vnet_interface_counters_t_handler_json
1933   (vl_api_vnet_interface_counters_t * mp)
1934 {
1935   interface_counter_t counter;
1936   vlib_counter_t *v;
1937   u64 *v_packets;
1938   u64 packets;
1939   u32 count;
1940   u32 first_sw_if_index;
1941   int i;
1942
1943   count = ntohl (mp->count);
1944   first_sw_if_index = ntohl (mp->first_sw_if_index);
1945
1946   if (!mp->is_combined)
1947     {
1948       v_packets = (u64 *) & mp->data;
1949       for (i = 0; i < count; i++)
1950         {
1951           packets =
1952             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1953           set_simple_interface_counter (mp->vnet_counter_type,
1954                                         first_sw_if_index + i, packets);
1955           v_packets++;
1956         }
1957     }
1958   else
1959     {
1960       v = (vlib_counter_t *) & mp->data;
1961       for (i = 0; i < count; i++)
1962         {
1963           counter.packets =
1964             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1965           counter.bytes =
1966             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1967           set_combined_interface_counter (mp->vnet_counter_type,
1968                                           first_sw_if_index + i, counter);
1969           v++;
1970         }
1971     }
1972 }
1973
1974 static u32
1975 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1976 {
1977   vat_main_t *vam = &vat_main;
1978   u32 i;
1979
1980   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1981     {
1982       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1983         {
1984           return i;
1985         }
1986     }
1987   return ~0;
1988 }
1989
1990 static u32
1991 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1992 {
1993   vat_main_t *vam = &vat_main;
1994   u32 i;
1995
1996   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1997     {
1998       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1999         {
2000           return i;
2001         }
2002     }
2003   return ~0;
2004 }
2005
2006 static void vl_api_vnet_ip4_fib_counters_t_handler
2007   (vl_api_vnet_ip4_fib_counters_t * mp)
2008 {
2009   /* not supported */
2010 }
2011
2012 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2013   (vl_api_vnet_ip4_fib_counters_t * mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016   vl_api_ip4_fib_counter_t *v;
2017   ip4_fib_counter_t *counter;
2018   struct in_addr ip4;
2019   u32 vrf_id;
2020   u32 vrf_index;
2021   u32 count;
2022   int i;
2023
2024   vrf_id = ntohl (mp->vrf_id);
2025   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2026   if (~0 == vrf_index)
2027     {
2028       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2029       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2030       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2031       vec_validate (vam->ip4_fib_counters, vrf_index);
2032       vam->ip4_fib_counters[vrf_index] = NULL;
2033     }
2034
2035   vec_free (vam->ip4_fib_counters[vrf_index]);
2036   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2037   count = ntohl (mp->count);
2038   for (i = 0; i < count; i++)
2039     {
2040       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2041       counter = &vam->ip4_fib_counters[vrf_index][i];
2042       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2043       counter->address = ip4;
2044       counter->address_length = v->address_length;
2045       counter->packets = clib_net_to_host_u64 (v->packets);
2046       counter->bytes = clib_net_to_host_u64 (v->bytes);
2047       v++;
2048     }
2049 }
2050
2051 static void vl_api_vnet_ip6_fib_counters_t_handler
2052   (vl_api_vnet_ip6_fib_counters_t * mp)
2053 {
2054   /* not supported */
2055 }
2056
2057 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2058   (vl_api_vnet_ip6_fib_counters_t * mp)
2059 {
2060   vat_main_t *vam = &vat_main;
2061   vl_api_ip6_fib_counter_t *v;
2062   ip6_fib_counter_t *counter;
2063   struct in6_addr ip6;
2064   u32 vrf_id;
2065   u32 vrf_index;
2066   u32 count;
2067   int i;
2068
2069   vrf_id = ntohl (mp->vrf_id);
2070   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2071   if (~0 == vrf_index)
2072     {
2073       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2074       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2075       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2076       vec_validate (vam->ip6_fib_counters, vrf_index);
2077       vam->ip6_fib_counters[vrf_index] = NULL;
2078     }
2079
2080   vec_free (vam->ip6_fib_counters[vrf_index]);
2081   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2082   count = ntohl (mp->count);
2083   for (i = 0; i < count; i++)
2084     {
2085       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2086       counter = &vam->ip6_fib_counters[vrf_index][i];
2087       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2088       counter->address = ip6;
2089       counter->address_length = v->address_length;
2090       counter->packets = clib_net_to_host_u64 (v->packets);
2091       counter->bytes = clib_net_to_host_u64 (v->bytes);
2092       v++;
2093     }
2094 }
2095
2096 static void vl_api_get_first_msg_id_reply_t_handler
2097   (vl_api_get_first_msg_id_reply_t * mp)
2098 {
2099   vat_main_t *vam = &vat_main;
2100   i32 retval = ntohl (mp->retval);
2101
2102   if (vam->async_mode)
2103     {
2104       vam->async_errors += (retval < 0);
2105     }
2106   else
2107     {
2108       vam->retval = retval;
2109       vam->result_ready = 1;
2110     }
2111   if (retval >= 0)
2112     {
2113       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2114     }
2115 }
2116
2117 static void vl_api_get_first_msg_id_reply_t_handler_json
2118   (vl_api_get_first_msg_id_reply_t * mp)
2119 {
2120   vat_main_t *vam = &vat_main;
2121   vat_json_node_t node;
2122
2123   vat_json_init_object (&node);
2124   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2125   vat_json_object_add_uint (&node, "first_msg_id",
2126                             (uint) ntohs (mp->first_msg_id));
2127
2128   vat_json_print (vam->ofp, &node);
2129   vat_json_free (&node);
2130
2131   vam->retval = ntohl (mp->retval);
2132   vam->result_ready = 1;
2133 }
2134
2135 static void vl_api_get_node_graph_reply_t_handler
2136   (vl_api_get_node_graph_reply_t * mp)
2137 {
2138   vat_main_t *vam = &vat_main;
2139   api_main_t *am = &api_main;
2140   i32 retval = ntohl (mp->retval);
2141   u8 *pvt_copy, *reply;
2142   void *oldheap;
2143   vlib_node_t *node;
2144   int i;
2145
2146   if (vam->async_mode)
2147     {
2148       vam->async_errors += (retval < 0);
2149     }
2150   else
2151     {
2152       vam->retval = retval;
2153       vam->result_ready = 1;
2154     }
2155
2156   /* "Should never happen..." */
2157   if (retval != 0)
2158     return;
2159
2160   reply = (u8 *) (mp->reply_in_shmem);
2161   pvt_copy = vec_dup (reply);
2162
2163   /* Toss the shared-memory original... */
2164   pthread_mutex_lock (&am->vlib_rp->mutex);
2165   oldheap = svm_push_data_heap (am->vlib_rp);
2166
2167   vec_free (reply);
2168
2169   svm_pop_heap (oldheap);
2170   pthread_mutex_unlock (&am->vlib_rp->mutex);
2171
2172   if (vam->graph_nodes)
2173     {
2174       hash_free (vam->graph_node_index_by_name);
2175
2176       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2177         {
2178           node = vam->graph_nodes[i];
2179           vec_free (node->name);
2180           vec_free (node->next_nodes);
2181           vec_free (node);
2182         }
2183       vec_free (vam->graph_nodes);
2184     }
2185
2186   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2187   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2188   vec_free (pvt_copy);
2189
2190   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2191     {
2192       node = vam->graph_nodes[i];
2193       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2194     }
2195 }
2196
2197 static void vl_api_get_node_graph_reply_t_handler_json
2198   (vl_api_get_node_graph_reply_t * mp)
2199 {
2200   vat_main_t *vam = &vat_main;
2201   api_main_t *am = &api_main;
2202   void *oldheap;
2203   vat_json_node_t node;
2204   u8 *reply;
2205
2206   /* $$$$ make this real? */
2207   vat_json_init_object (&node);
2208   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2209   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2210
2211   reply = (u8 *) (mp->reply_in_shmem);
2212
2213   /* Toss the shared-memory original... */
2214   pthread_mutex_lock (&am->vlib_rp->mutex);
2215   oldheap = svm_push_data_heap (am->vlib_rp);
2216
2217   vec_free (reply);
2218
2219   svm_pop_heap (oldheap);
2220   pthread_mutex_unlock (&am->vlib_rp->mutex);
2221
2222   vat_json_print (vam->ofp, &node);
2223   vat_json_free (&node);
2224
2225   vam->retval = ntohl (mp->retval);
2226   vam->result_ready = 1;
2227 }
2228
2229 static void
2230 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2231 {
2232   vat_main_t *vam = &vat_main;
2233   u8 *s = 0;
2234
2235   if (mp->local)
2236     {
2237       s = format (s, "%=16d%=16d%=16d\n",
2238                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2239     }
2240   else
2241     {
2242       s = format (s, "%=16U%=16d%=16d\n",
2243                   mp->is_ipv6 ? format_ip6_address :
2244                   format_ip4_address,
2245                   mp->ip_address, mp->priority, mp->weight);
2246     }
2247
2248   fformat (vam->ofp, "%v", s);
2249   vec_free (s);
2250 }
2251
2252 static void
2253 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2254                                             mp)
2255 {
2256   vat_main_t *vam = &vat_main;
2257   vat_json_node_t *node = NULL;
2258   struct in6_addr ip6;
2259   struct in_addr ip4;
2260
2261   if (VAT_JSON_ARRAY != vam->json_tree.type)
2262     {
2263       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2264       vat_json_init_array (&vam->json_tree);
2265     }
2266   node = vat_json_array_add (&vam->json_tree);
2267   vat_json_init_object (node);
2268
2269   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2270   vat_json_object_add_uint (node, "priority", mp->priority);
2271   vat_json_object_add_uint (node, "weight", mp->weight);
2272
2273   if (mp->local)
2274     vat_json_object_add_uint (node, "sw_if_index",
2275                               clib_net_to_host_u32 (mp->sw_if_index));
2276   else
2277     {
2278       if (mp->is_ipv6)
2279         {
2280           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2281           vat_json_object_add_ip6 (node, "address", ip6);
2282         }
2283       else
2284         {
2285           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2286           vat_json_object_add_ip4 (node, "address", ip4);
2287         }
2288     }
2289 }
2290
2291 static void
2292 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2293                                            mp)
2294 {
2295   vat_main_t *vam = &vat_main;
2296   u8 *ls_name = 0;
2297
2298   ls_name = format (0, "%s", mp->ls_name);
2299
2300   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2301            ls_name);
2302   vec_free (ls_name);
2303 }
2304
2305 static void
2306   vl_api_lisp_locator_set_details_t_handler_json
2307   (vl_api_lisp_locator_set_details_t * mp)
2308 {
2309   vat_main_t *vam = &vat_main;
2310   vat_json_node_t *node = 0;
2311   u8 *ls_name = 0;
2312
2313   ls_name = format (0, "%s", mp->ls_name);
2314   vec_add1 (ls_name, 0);
2315
2316   if (VAT_JSON_ARRAY != vam->json_tree.type)
2317     {
2318       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2319       vat_json_init_array (&vam->json_tree);
2320     }
2321   node = vat_json_array_add (&vam->json_tree);
2322
2323   vat_json_init_object (node);
2324   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2325   vat_json_object_add_uint (node, "ls_index",
2326                             clib_net_to_host_u32 (mp->ls_index));
2327   vec_free (ls_name);
2328 }
2329
2330 static u8 *
2331 format_lisp_flat_eid (u8 * s, va_list * args)
2332 {
2333   u32 type = va_arg (*args, u32);
2334   u8 *eid = va_arg (*args, u8 *);
2335   u32 eid_len = va_arg (*args, u32);
2336
2337   switch (type)
2338     {
2339     case 0:
2340       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2341     case 1:
2342       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2343     case 2:
2344       return format (s, "%U", format_ethernet_address, eid);
2345     }
2346   return 0;
2347 }
2348
2349 static u8 *
2350 format_lisp_eid_vat (u8 * s, va_list * args)
2351 {
2352   u32 type = va_arg (*args, u32);
2353   u8 *eid = va_arg (*args, u8 *);
2354   u32 eid_len = va_arg (*args, u32);
2355   u8 *seid = va_arg (*args, u8 *);
2356   u32 seid_len = va_arg (*args, u32);
2357   u32 is_src_dst = va_arg (*args, u32);
2358
2359   if (is_src_dst)
2360     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2361
2362   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2363
2364   return s;
2365 }
2366
2367 static void
2368 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2369 {
2370   vat_main_t *vam = &vat_main;
2371   u8 *s = 0, *eid = 0;
2372
2373   if (~0 == mp->locator_set_index)
2374     s = format (0, "action: %d", mp->action);
2375   else
2376     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2377
2378   eid = format (0, "%U", format_lisp_eid_vat,
2379                 mp->eid_type,
2380                 mp->eid,
2381                 mp->eid_prefix_len,
2382                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2383   vec_add1 (eid, 0);
2384
2385   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2386            clib_net_to_host_u32 (mp->vni),
2387            eid,
2388            mp->is_local ? "local" : "remote",
2389            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2390   vec_free (s);
2391   vec_free (eid);
2392 }
2393
2394 static void
2395 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2396                                               * mp)
2397 {
2398   vat_main_t *vam = &vat_main;
2399   vat_json_node_t *node = 0;
2400   u8 *eid = 0;
2401
2402   if (VAT_JSON_ARRAY != vam->json_tree.type)
2403     {
2404       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2405       vat_json_init_array (&vam->json_tree);
2406     }
2407   node = vat_json_array_add (&vam->json_tree);
2408
2409   vat_json_init_object (node);
2410   if (~0 == mp->locator_set_index)
2411     vat_json_object_add_uint (node, "action", mp->action);
2412   else
2413     vat_json_object_add_uint (node, "locator_set_index",
2414                               clib_net_to_host_u32 (mp->locator_set_index));
2415
2416   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2417   eid = format (0, "%U", format_lisp_eid_vat,
2418                 mp->eid_type,
2419                 mp->eid,
2420                 mp->eid_prefix_len,
2421                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2422   vec_add1 (eid, 0);
2423   vat_json_object_add_string_copy (node, "eid", eid);
2424   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2425   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2426   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2427   vec_free (eid);
2428 }
2429
2430 static void
2431   vl_api_lisp_eid_table_map_details_t_handler
2432   (vl_api_lisp_eid_table_map_details_t * mp)
2433 {
2434   vat_main_t *vam = &vat_main;
2435
2436   u8 *line = format (0, "%=10d%=10d",
2437                      clib_net_to_host_u32 (mp->vni),
2438                      clib_net_to_host_u32 (mp->dp_table));
2439   fformat (vam->ofp, "%v\n", line);
2440   vec_free (line);
2441 }
2442
2443 static void
2444   vl_api_lisp_eid_table_map_details_t_handler_json
2445   (vl_api_lisp_eid_table_map_details_t * mp)
2446 {
2447   vat_main_t *vam = &vat_main;
2448   vat_json_node_t *node = NULL;
2449
2450   if (VAT_JSON_ARRAY != vam->json_tree.type)
2451     {
2452       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2453       vat_json_init_array (&vam->json_tree);
2454     }
2455   node = vat_json_array_add (&vam->json_tree);
2456   vat_json_init_object (node);
2457   vat_json_object_add_uint (node, "dp_table",
2458                             clib_net_to_host_u32 (mp->dp_table));
2459   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2460 }
2461
2462 static void
2463   vl_api_lisp_eid_table_vni_details_t_handler
2464   (vl_api_lisp_eid_table_vni_details_t * mp)
2465 {
2466   vat_main_t *vam = &vat_main;
2467
2468   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2469   fformat (vam->ofp, "%v\n", line);
2470   vec_free (line);
2471 }
2472
2473 static void
2474   vl_api_lisp_eid_table_vni_details_t_handler_json
2475   (vl_api_lisp_eid_table_vni_details_t * mp)
2476 {
2477   vat_main_t *vam = &vat_main;
2478   vat_json_node_t *node = NULL;
2479
2480   if (VAT_JSON_ARRAY != vam->json_tree.type)
2481     {
2482       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2483       vat_json_init_array (&vam->json_tree);
2484     }
2485   node = vat_json_array_add (&vam->json_tree);
2486   vat_json_init_object (node);
2487   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2488 }
2489
2490 static u8 *
2491 format_decap_next (u8 * s, va_list * args)
2492 {
2493   u32 next_index = va_arg (*args, u32);
2494
2495   switch (next_index)
2496     {
2497     case LISP_GPE_INPUT_NEXT_DROP:
2498       return format (s, "drop");
2499     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2500       return format (s, "ip4");
2501     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2502       return format (s, "ip6");
2503     default:
2504       return format (s, "unknown %d", next_index);
2505     }
2506   return s;
2507 }
2508
2509 static void
2510 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2511                                           mp)
2512 {
2513   vat_main_t *vam = &vat_main;
2514   u8 *iid_str;
2515   u8 *flag_str = NULL;
2516
2517   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2518
2519 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2520   foreach_lisp_gpe_flag_bit;
2521 #undef _
2522
2523   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2524            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2525            mp->tunnels,
2526            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2527            mp->source_ip,
2528            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2529            mp->destination_ip,
2530            ntohl (mp->encap_fib_id),
2531            ntohl (mp->decap_fib_id),
2532            format_decap_next, ntohl (mp->dcap_next),
2533            mp->ver_res >> 6,
2534            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2535
2536   vec_free (iid_str);
2537 }
2538
2539 static void
2540   vl_api_lisp_gpe_tunnel_details_t_handler_json
2541   (vl_api_lisp_gpe_tunnel_details_t * mp)
2542 {
2543   vat_main_t *vam = &vat_main;
2544   vat_json_node_t *node = NULL;
2545   struct in6_addr ip6;
2546   struct in_addr ip4;
2547   u8 *next_decap_str;
2548
2549   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2550
2551   if (VAT_JSON_ARRAY != vam->json_tree.type)
2552     {
2553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2554       vat_json_init_array (&vam->json_tree);
2555     }
2556   node = vat_json_array_add (&vam->json_tree);
2557
2558   vat_json_init_object (node);
2559   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2560   if (mp->is_ipv6)
2561     {
2562       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2563       vat_json_object_add_ip6 (node, "source address", ip6);
2564       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2565       vat_json_object_add_ip6 (node, "destination address", ip6);
2566     }
2567   else
2568     {
2569       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2570       vat_json_object_add_ip4 (node, "source address", ip4);
2571       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2572       vat_json_object_add_ip4 (node, "destination address", ip4);
2573     }
2574   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2575   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2576   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2577   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2578   vat_json_object_add_uint (node, "flags", mp->flags);
2579   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2580   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2581   vat_json_object_add_uint (node, "res", mp->res);
2582   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2583
2584   vec_free (next_decap_str);
2585 }
2586
2587 static void
2588 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2589                                             * mp)
2590 {
2591   vat_main_t *vam = &vat_main;
2592
2593   fformat (vam->ofp, "%=20U\n",
2594            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2595            mp->ip_address);
2596 }
2597
2598 static void
2599   vl_api_lisp_map_resolver_details_t_handler_json
2600   (vl_api_lisp_map_resolver_details_t * mp)
2601 {
2602   vat_main_t *vam = &vat_main;
2603   vat_json_node_t *node = NULL;
2604   struct in6_addr ip6;
2605   struct in_addr ip4;
2606
2607   if (VAT_JSON_ARRAY != vam->json_tree.type)
2608     {
2609       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2610       vat_json_init_array (&vam->json_tree);
2611     }
2612   node = vat_json_array_add (&vam->json_tree);
2613
2614   vat_json_init_object (node);
2615   if (mp->is_ipv6)
2616     {
2617       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2618       vat_json_object_add_ip6 (node, "map resolver", ip6);
2619     }
2620   else
2621     {
2622       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2623       vat_json_object_add_ip4 (node, "map resolver", ip4);
2624     }
2625 }
2626
2627 static void
2628   vl_api_show_lisp_status_reply_t_handler
2629   (vl_api_show_lisp_status_reply_t * mp)
2630 {
2631   vat_main_t *vam = &vat_main;
2632   i32 retval = ntohl (mp->retval);
2633
2634   if (0 <= retval)
2635     {
2636       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2637                mp->feature_status ? "enabled" : "disabled",
2638                mp->gpe_status ? "enabled" : "disabled");
2639     }
2640
2641   vam->retval = retval;
2642   vam->result_ready = 1;
2643 }
2644
2645 static void
2646   vl_api_show_lisp_status_reply_t_handler_json
2647   (vl_api_show_lisp_status_reply_t * mp)
2648 {
2649   vat_main_t *vam = &vat_main;
2650   vat_json_node_t node;
2651   u8 *gpe_status = NULL;
2652   u8 *feature_status = NULL;
2653
2654   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2655   feature_status = format (0, "%s",
2656                            mp->feature_status ? "enabled" : "disabled");
2657   vec_add1 (gpe_status, 0);
2658   vec_add1 (feature_status, 0);
2659
2660   vat_json_init_object (&node);
2661   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2662   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2663
2664   vec_free (gpe_status);
2665   vec_free (feature_status);
2666
2667   vat_json_print (vam->ofp, &node);
2668   vat_json_free (&node);
2669
2670   vam->retval = ntohl (mp->retval);
2671   vam->result_ready = 1;
2672 }
2673
2674 static void
2675   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2676   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2677 {
2678   vat_main_t *vam = &vat_main;
2679   i32 retval = ntohl (mp->retval);
2680
2681   if (retval >= 0)
2682     {
2683       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2684     }
2685
2686   vam->retval = retval;
2687   vam->result_ready = 1;
2688 }
2689
2690 static void
2691   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2692   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2693 {
2694   vat_main_t *vam = &vat_main;
2695   vat_json_node_t *node = NULL;
2696
2697   if (VAT_JSON_ARRAY != vam->json_tree.type)
2698     {
2699       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2700       vat_json_init_array (&vam->json_tree);
2701     }
2702   node = vat_json_array_add (&vam->json_tree);
2703
2704   vat_json_init_object (node);
2705   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2706
2707   vat_json_print (vam->ofp, node);
2708   vat_json_free (node);
2709
2710   vam->retval = ntohl (mp->retval);
2711   vam->result_ready = 1;
2712 }
2713
2714 static void
2715 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2716 {
2717   vat_main_t *vam = &vat_main;
2718   i32 retval = ntohl (mp->retval);
2719
2720   if (0 <= retval)
2721     {
2722       fformat (vam->ofp, "%-20s%-16s\n",
2723                mp->status ? "enabled" : "disabled",
2724                mp->status ? (char *) mp->locator_set_name : "");
2725     }
2726
2727   vam->retval = retval;
2728   vam->result_ready = 1;
2729 }
2730
2731 static void
2732 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2733                                             mp)
2734 {
2735   vat_main_t *vam = &vat_main;
2736   vat_json_node_t node;
2737   u8 *status = 0;
2738
2739   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2740   vec_add1 (status, 0);
2741
2742   vat_json_init_object (&node);
2743   vat_json_object_add_string_copy (&node, "status", status);
2744   if (mp->status)
2745     {
2746       vat_json_object_add_string_copy (&node, "locator_set",
2747                                        mp->locator_set_name);
2748     }
2749
2750   vec_free (status);
2751
2752   vat_json_print (vam->ofp, &node);
2753   vat_json_free (&node);
2754
2755   vam->retval = ntohl (mp->retval);
2756   vam->result_ready = 1;
2757 }
2758
2759 static u8 *
2760 format_policer_type (u8 * s, va_list * va)
2761 {
2762   u32 i = va_arg (*va, u32);
2763
2764   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2765     s = format (s, "1r2c");
2766   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2767     s = format (s, "1r3c");
2768   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2769     s = format (s, "2r3c-2698");
2770   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2771     s = format (s, "2r3c-4115");
2772   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2773     s = format (s, "2r3c-mef5cf1");
2774   else
2775     s = format (s, "ILLEGAL");
2776   return s;
2777 }
2778
2779 static u8 *
2780 format_policer_rate_type (u8 * s, va_list * va)
2781 {
2782   u32 i = va_arg (*va, u32);
2783
2784   if (i == SSE2_QOS_RATE_KBPS)
2785     s = format (s, "kbps");
2786   else if (i == SSE2_QOS_RATE_PPS)
2787     s = format (s, "pps");
2788   else
2789     s = format (s, "ILLEGAL");
2790   return s;
2791 }
2792
2793 static u8 *
2794 format_policer_round_type (u8 * s, va_list * va)
2795 {
2796   u32 i = va_arg (*va, u32);
2797
2798   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2799     s = format (s, "closest");
2800   else if (i == SSE2_QOS_ROUND_TO_UP)
2801     s = format (s, "up");
2802   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2803     s = format (s, "down");
2804   else
2805     s = format (s, "ILLEGAL");
2806   return s;
2807 }
2808
2809 static u8 *
2810 format_policer_action_type (u8 * s, va_list * va)
2811 {
2812   u32 i = va_arg (*va, u32);
2813
2814   if (i == SSE2_QOS_ACTION_DROP)
2815     s = format (s, "drop");
2816   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2817     s = format (s, "transmit");
2818   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2819     s = format (s, "mark-and-transmit");
2820   else
2821     s = format (s, "ILLEGAL");
2822   return s;
2823 }
2824
2825 static u8 *
2826 format_dscp (u8 * s, va_list * va)
2827 {
2828   u32 i = va_arg (*va, u32);
2829   char *t = 0;
2830
2831   switch (i)
2832     {
2833 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2834       foreach_vnet_dscp
2835 #undef _
2836     default:
2837       return format (s, "ILLEGAL");
2838     }
2839   s = format (s, "%s", t);
2840   return s;
2841 }
2842
2843 static void
2844 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2845 {
2846   vat_main_t *vam = &vat_main;
2847   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2848
2849   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2850     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2851   else
2852     conform_dscp_str = format (0, "");
2853
2854   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2855     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2856   else
2857     exceed_dscp_str = format (0, "");
2858
2859   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2860     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2861   else
2862     violate_dscp_str = format (0, "");
2863
2864   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2865            "rate type %U, round type %U, %s rate, %s color-aware, "
2866            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2867            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2868            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2869            mp->name,
2870            format_policer_type, mp->type,
2871            ntohl (mp->cir),
2872            ntohl (mp->eir),
2873            clib_net_to_host_u64 (mp->cb),
2874            clib_net_to_host_u64 (mp->eb),
2875            format_policer_rate_type, mp->rate_type,
2876            format_policer_round_type, mp->round_type,
2877            mp->single_rate ? "single" : "dual",
2878            mp->color_aware ? "is" : "not",
2879            ntohl (mp->cir_tokens_per_period),
2880            ntohl (mp->pir_tokens_per_period),
2881            ntohl (mp->scale),
2882            ntohl (mp->current_limit),
2883            ntohl (mp->current_bucket),
2884            ntohl (mp->extended_limit),
2885            ntohl (mp->extended_bucket),
2886            clib_net_to_host_u64 (mp->last_update_time),
2887            format_policer_action_type, mp->conform_action_type,
2888            conform_dscp_str,
2889            format_policer_action_type, mp->exceed_action_type,
2890            exceed_dscp_str,
2891            format_policer_action_type, mp->violate_action_type,
2892            violate_dscp_str);
2893
2894   vec_free (conform_dscp_str);
2895   vec_free (exceed_dscp_str);
2896   vec_free (violate_dscp_str);
2897 }
2898
2899 static void vl_api_policer_details_t_handler_json
2900   (vl_api_policer_details_t * mp)
2901 {
2902   vat_main_t *vam = &vat_main;
2903   vat_json_node_t *node;
2904   u8 *rate_type_str, *round_type_str, *type_str;
2905   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2906
2907   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2908   round_type_str =
2909     format (0, "%U", format_policer_round_type, mp->round_type);
2910   type_str = format (0, "%U", format_policer_type, mp->type);
2911   conform_action_str = format (0, "%U", format_policer_action_type,
2912                                mp->conform_action_type);
2913   exceed_action_str = format (0, "%U", format_policer_action_type,
2914                               mp->exceed_action_type);
2915   violate_action_str = format (0, "%U", format_policer_action_type,
2916                                mp->violate_action_type);
2917
2918   if (VAT_JSON_ARRAY != vam->json_tree.type)
2919     {
2920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2921       vat_json_init_array (&vam->json_tree);
2922     }
2923   node = vat_json_array_add (&vam->json_tree);
2924
2925   vat_json_init_object (node);
2926   vat_json_object_add_string_copy (node, "name", mp->name);
2927   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2928   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2929   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
2930   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
2931   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2932   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2933   vat_json_object_add_string_copy (node, "type", type_str);
2934   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2935   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2936   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2937   vat_json_object_add_uint (node, "cir_tokens_per_period",
2938                             ntohl (mp->cir_tokens_per_period));
2939   vat_json_object_add_uint (node, "eir_tokens_per_period",
2940                             ntohl (mp->pir_tokens_per_period));
2941   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2942   vat_json_object_add_uint (node, "current_bucket",
2943                             ntohl (mp->current_bucket));
2944   vat_json_object_add_uint (node, "extended_limit",
2945                             ntohl (mp->extended_limit));
2946   vat_json_object_add_uint (node, "extended_bucket",
2947                             ntohl (mp->extended_bucket));
2948   vat_json_object_add_uint (node, "last_update_time",
2949                             ntohl (mp->last_update_time));
2950   vat_json_object_add_string_copy (node, "conform_action",
2951                                    conform_action_str);
2952   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2953     {
2954       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2955       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2956       vec_free (dscp_str);
2957     }
2958   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
2959   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2960     {
2961       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2962       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2963       vec_free (dscp_str);
2964     }
2965   vat_json_object_add_string_copy (node, "violate_action",
2966                                    violate_action_str);
2967   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2968     {
2969       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2970       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2971       vec_free (dscp_str);
2972     }
2973
2974   vec_free (rate_type_str);
2975   vec_free (round_type_str);
2976   vec_free (type_str);
2977   vec_free (conform_action_str);
2978   vec_free (exceed_action_str);
2979   vec_free (violate_action_str);
2980 }
2981
2982 static void
2983 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2984                                            mp)
2985 {
2986   vat_main_t *vam = &vat_main;
2987   int i, count = ntohl (mp->count);
2988
2989   if (count > 0)
2990     fformat (vam->ofp, "classify table ids (%d) : ", count);
2991   for (i = 0; i < count; i++)
2992     {
2993       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
2994       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
2995     }
2996   vam->retval = ntohl (mp->retval);
2997   vam->result_ready = 1;
2998 }
2999
3000 static void
3001   vl_api_classify_table_ids_reply_t_handler_json
3002   (vl_api_classify_table_ids_reply_t * mp)
3003 {
3004   vat_main_t *vam = &vat_main;
3005   int i, count = ntohl (mp->count);
3006
3007   if (count > 0)
3008     {
3009       vat_json_node_t node;
3010
3011       vat_json_init_object (&node);
3012       for (i = 0; i < count; i++)
3013         {
3014           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3015         }
3016       vat_json_print (vam->ofp, &node);
3017       vat_json_free (&node);
3018     }
3019   vam->retval = ntohl (mp->retval);
3020   vam->result_ready = 1;
3021 }
3022
3023 static void
3024   vl_api_classify_table_by_interface_reply_t_handler
3025   (vl_api_classify_table_by_interface_reply_t * mp)
3026 {
3027   vat_main_t *vam = &vat_main;
3028   u32 table_id;
3029
3030   table_id = ntohl (mp->l2_table_id);
3031   if (table_id != ~0)
3032     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3033   else
3034     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3035   table_id = ntohl (mp->ip4_table_id);
3036   if (table_id != ~0)
3037     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3038   else
3039     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3040   table_id = ntohl (mp->ip6_table_id);
3041   if (table_id != ~0)
3042     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3043   else
3044     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3045   vam->retval = ntohl (mp->retval);
3046   vam->result_ready = 1;
3047 }
3048
3049 static void
3050   vl_api_classify_table_by_interface_reply_t_handler_json
3051   (vl_api_classify_table_by_interface_reply_t * mp)
3052 {
3053   vat_main_t *vam = &vat_main;
3054   vat_json_node_t node;
3055
3056   vat_json_init_object (&node);
3057
3058   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3059   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3060   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3061
3062   vat_json_print (vam->ofp, &node);
3063   vat_json_free (&node);
3064
3065   vam->retval = ntohl (mp->retval);
3066   vam->result_ready = 1;
3067 }
3068
3069 static void vl_api_policer_add_del_reply_t_handler
3070   (vl_api_policer_add_del_reply_t * mp)
3071 {
3072   vat_main_t *vam = &vat_main;
3073   i32 retval = ntohl (mp->retval);
3074   if (vam->async_mode)
3075     {
3076       vam->async_errors += (retval < 0);
3077     }
3078   else
3079     {
3080       vam->retval = retval;
3081       vam->result_ready = 1;
3082       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3083         /*
3084          * Note: this is just barely thread-safe, depends on
3085          * the main thread spinning waiting for an answer...
3086          */
3087         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3088     }
3089 }
3090
3091 static void vl_api_policer_add_del_reply_t_handler_json
3092   (vl_api_policer_add_del_reply_t * mp)
3093 {
3094   vat_main_t *vam = &vat_main;
3095   vat_json_node_t node;
3096
3097   vat_json_init_object (&node);
3098   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3099   vat_json_object_add_uint (&node, "policer_index",
3100                             ntohl (mp->policer_index));
3101
3102   vat_json_print (vam->ofp, &node);
3103   vat_json_free (&node);
3104
3105   vam->retval = ntohl (mp->retval);
3106   vam->result_ready = 1;
3107 }
3108
3109 /* Format hex dump. */
3110 u8 *
3111 format_hex_bytes (u8 * s, va_list * va)
3112 {
3113   u8 *bytes = va_arg (*va, u8 *);
3114   int n_bytes = va_arg (*va, int);
3115   uword i;
3116
3117   /* Print short or long form depending on byte count. */
3118   uword short_form = n_bytes <= 32;
3119   uword indent = format_get_indent (s);
3120
3121   if (n_bytes == 0)
3122     return s;
3123
3124   for (i = 0; i < n_bytes; i++)
3125     {
3126       if (!short_form && (i % 32) == 0)
3127         s = format (s, "%08x: ", i);
3128       s = format (s, "%02x", bytes[i]);
3129       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3130         s = format (s, "\n%U", format_white_space, indent);
3131     }
3132
3133   return s;
3134 }
3135
3136 static void
3137 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3138                                             * mp)
3139 {
3140   vat_main_t *vam = &vat_main;
3141   i32 retval = ntohl (mp->retval);
3142   if (retval == 0)
3143     {
3144       fformat (vam->ofp, "classify table info :\n");
3145       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3146                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3147                ntohl (mp->miss_next_index));
3148       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3149                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3150                ntohl (mp->match_n_vectors));
3151       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3152                ntohl (mp->mask_length));
3153     }
3154   vam->retval = retval;
3155   vam->result_ready = 1;
3156 }
3157
3158 static void
3159   vl_api_classify_table_info_reply_t_handler_json
3160   (vl_api_classify_table_info_reply_t * mp)
3161 {
3162   vat_main_t *vam = &vat_main;
3163   vat_json_node_t node;
3164
3165   i32 retval = ntohl (mp->retval);
3166   if (retval == 0)
3167     {
3168       vat_json_init_object (&node);
3169
3170       vat_json_object_add_int (&node, "sessions",
3171                                ntohl (mp->active_sessions));
3172       vat_json_object_add_int (&node, "nexttbl",
3173                                ntohl (mp->next_table_index));
3174       vat_json_object_add_int (&node, "nextnode",
3175                                ntohl (mp->miss_next_index));
3176       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3177       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3178       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3179       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3180                       ntohl (mp->mask_length), 0);
3181       vat_json_object_add_string_copy (&node, "mask", s);
3182
3183       vat_json_print (vam->ofp, &node);
3184       vat_json_free (&node);
3185     }
3186   vam->retval = ntohl (mp->retval);
3187   vam->result_ready = 1;
3188 }
3189
3190 static void
3191 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3192                                            mp)
3193 {
3194   vat_main_t *vam = &vat_main;
3195
3196   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3197            ntohl (mp->hit_next_index), ntohl (mp->advance),
3198            ntohl (mp->opaque_index));
3199   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3200            ntohl (mp->match_length));
3201 }
3202
3203 static void
3204   vl_api_classify_session_details_t_handler_json
3205   (vl_api_classify_session_details_t * mp)
3206 {
3207   vat_main_t *vam = &vat_main;
3208   vat_json_node_t *node = NULL;
3209
3210   if (VAT_JSON_ARRAY != vam->json_tree.type)
3211     {
3212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3213       vat_json_init_array (&vam->json_tree);
3214     }
3215   node = vat_json_array_add (&vam->json_tree);
3216
3217   vat_json_init_object (node);
3218   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3219   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3220   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3221   u8 *s =
3222     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3223             0);
3224   vat_json_object_add_string_copy (node, "match", s);
3225 }
3226
3227 static void vl_api_pg_create_interface_reply_t_handler
3228   (vl_api_pg_create_interface_reply_t * mp)
3229 {
3230   vat_main_t *vam = &vat_main;
3231
3232   vam->retval = ntohl (mp->retval);
3233   vam->result_ready = 1;
3234 }
3235
3236 static void vl_api_pg_create_interface_reply_t_handler_json
3237   (vl_api_pg_create_interface_reply_t * mp)
3238 {
3239   vat_main_t *vam = &vat_main;
3240   vat_json_node_t node;
3241
3242   i32 retval = ntohl (mp->retval);
3243   if (retval == 0)
3244     {
3245       vat_json_init_object (&node);
3246
3247       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3248
3249       vat_json_print (vam->ofp, &node);
3250       vat_json_free (&node);
3251     }
3252   vam->retval = ntohl (mp->retval);
3253   vam->result_ready = 1;
3254 }
3255
3256 static void vl_api_policer_classify_details_t_handler
3257   (vl_api_policer_classify_details_t * mp)
3258 {
3259   vat_main_t *vam = &vat_main;
3260
3261   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3262            ntohl (mp->table_index));
3263 }
3264
3265 static void vl_api_policer_classify_details_t_handler_json
3266   (vl_api_policer_classify_details_t * mp)
3267 {
3268   vat_main_t *vam = &vat_main;
3269   vat_json_node_t *node;
3270
3271   if (VAT_JSON_ARRAY != vam->json_tree.type)
3272     {
3273       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3274       vat_json_init_array (&vam->json_tree);
3275     }
3276   node = vat_json_array_add (&vam->json_tree);
3277
3278   vat_json_init_object (node);
3279   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3280   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3281 }
3282
3283 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3284   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3285 {
3286   vat_main_t *vam = &vat_main;
3287   i32 retval = ntohl (mp->retval);
3288   if (vam->async_mode)
3289     {
3290       vam->async_errors += (retval < 0);
3291     }
3292   else
3293     {
3294       vam->retval = retval;
3295       vam->sw_if_index = ntohl (mp->sw_if_index);
3296       vam->result_ready = 1;
3297     }
3298 }
3299
3300 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3301   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3302 {
3303   vat_main_t *vam = &vat_main;
3304   vat_json_node_t node;
3305
3306   vat_json_init_object (&node);
3307   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3308   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3309
3310   vat_json_print (vam->ofp, &node);
3311   vat_json_free (&node);
3312
3313   vam->retval = ntohl (mp->retval);
3314   vam->result_ready = 1;
3315 }
3316
3317 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3318 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3319 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3320 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3321
3322 /*
3323  * Generate boilerplate reply handlers, which
3324  * dig the return value out of the xxx_reply_t API message,
3325  * stick it into vam->retval, and set vam->result_ready
3326  *
3327  * Could also do this by pointing N message decode slots at
3328  * a single function, but that could break in subtle ways.
3329  */
3330
3331 #define foreach_standard_reply_retval_handler           \
3332 _(sw_interface_set_flags_reply)                         \
3333 _(sw_interface_add_del_address_reply)                   \
3334 _(sw_interface_set_table_reply)                         \
3335 _(sw_interface_set_vpath_reply)                         \
3336 _(sw_interface_set_l2_bridge_reply)                     \
3337 _(bridge_domain_add_del_reply)                          \
3338 _(sw_interface_set_l2_xconnect_reply)                   \
3339 _(l2fib_add_del_reply)                                  \
3340 _(ip_add_del_route_reply)                               \
3341 _(proxy_arp_add_del_reply)                              \
3342 _(proxy_arp_intfc_enable_disable_reply)                 \
3343 _(mpls_add_del_encap_reply)                             \
3344 _(mpls_add_del_decap_reply)                             \
3345 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3346 _(sw_interface_set_unnumbered_reply)                    \
3347 _(ip_neighbor_add_del_reply)                            \
3348 _(reset_vrf_reply)                                      \
3349 _(oam_add_del_reply)                                    \
3350 _(reset_fib_reply)                                      \
3351 _(dhcp_proxy_config_reply)                              \
3352 _(dhcp_proxy_config_2_reply)                            \
3353 _(dhcp_proxy_set_vss_reply)                             \
3354 _(dhcp_client_config_reply)                             \
3355 _(set_ip_flow_hash_reply)                               \
3356 _(sw_interface_ip6_enable_disable_reply)                \
3357 _(sw_interface_ip6_set_link_local_address_reply)        \
3358 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3359 _(sw_interface_ip6nd_ra_config_reply)                   \
3360 _(set_arp_neighbor_limit_reply)                         \
3361 _(l2_patch_add_del_reply)                               \
3362 _(sr_tunnel_add_del_reply)                              \
3363 _(sr_policy_add_del_reply)                              \
3364 _(sr_multicast_map_add_del_reply)                       \
3365 _(classify_add_del_session_reply)                       \
3366 _(classify_set_interface_ip_table_reply)                \
3367 _(classify_set_interface_l2_tables_reply)               \
3368 _(l2tpv3_set_tunnel_cookies_reply)                      \
3369 _(l2tpv3_interface_enable_disable_reply)                \
3370 _(l2tpv3_set_lookup_key_reply)                          \
3371 _(l2_fib_clear_table_reply)                             \
3372 _(l2_interface_efp_filter_reply)                        \
3373 _(l2_interface_vlan_tag_rewrite_reply)                  \
3374 _(modify_vhost_user_if_reply)                           \
3375 _(delete_vhost_user_if_reply)                           \
3376 _(want_ip4_arp_events_reply)                            \
3377 _(want_ip6_nd_events_reply)                             \
3378 _(input_acl_set_interface_reply)                        \
3379 _(ipsec_spd_add_del_reply)                              \
3380 _(ipsec_interface_add_del_spd_reply)                    \
3381 _(ipsec_spd_add_del_entry_reply)                        \
3382 _(ipsec_sad_add_del_entry_reply)                        \
3383 _(ipsec_sa_set_key_reply)                               \
3384 _(ikev2_profile_add_del_reply)                          \
3385 _(ikev2_profile_set_auth_reply)                         \
3386 _(ikev2_profile_set_id_reply)                           \
3387 _(ikev2_profile_set_ts_reply)                           \
3388 _(ikev2_set_local_key_reply)                            \
3389 _(delete_loopback_reply)                                \
3390 _(bd_ip_mac_add_del_reply)                              \
3391 _(map_del_domain_reply)                                 \
3392 _(map_add_del_rule_reply)                               \
3393 _(want_interface_events_reply)                          \
3394 _(want_stats_reply)                                     \
3395 _(cop_interface_enable_disable_reply)                   \
3396 _(cop_whitelist_enable_disable_reply)                   \
3397 _(sw_interface_clear_stats_reply)                       \
3398 _(ioam_enable_reply)                              \
3399 _(ioam_disable_reply)                              \
3400 _(lisp_add_del_locator_reply)                           \
3401 _(lisp_add_del_local_eid_reply)                         \
3402 _(lisp_add_del_remote_mapping_reply)                    \
3403 _(lisp_add_del_adjacency_reply)                         \
3404 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3405 _(lisp_add_del_map_resolver_reply)                      \
3406 _(lisp_gpe_enable_disable_reply)                        \
3407 _(lisp_gpe_add_del_iface_reply)                         \
3408 _(lisp_enable_disable_reply)                            \
3409 _(lisp_pitr_set_locator_set_reply)                      \
3410 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3411 _(lisp_eid_table_add_del_map_reply)                     \
3412 _(vxlan_gpe_add_del_tunnel_reply)                       \
3413 _(af_packet_delete_reply)                               \
3414 _(policer_classify_set_interface_reply)                 \
3415 _(netmap_create_reply)                                  \
3416 _(netmap_delete_reply)                                  \
3417 _(set_ipfix_exporter_reply)                             \
3418 _(set_ipfix_classify_stream_reply)                      \
3419 _(ipfix_classify_table_add_del_reply)                   \
3420 _(pg_capture_reply)                                     \
3421 _(pg_enable_disable_reply)                              \
3422 _(ip_source_and_port_range_check_add_del_reply)         \
3423 _(ip_source_and_port_range_check_interface_add_del_reply)\
3424 _(delete_subif_reply)
3425
3426 #define _(n)                                    \
3427     static void vl_api_##n##_t_handler          \
3428     (vl_api_##n##_t * mp)                       \
3429     {                                           \
3430         vat_main_t * vam = &vat_main;           \
3431         i32 retval = ntohl(mp->retval);         \
3432         if (vam->async_mode) {                  \
3433             vam->async_errors += (retval < 0);  \
3434         } else {                                \
3435             vam->retval = retval;               \
3436             vam->result_ready = 1;              \
3437         }                                       \
3438     }
3439 foreach_standard_reply_retval_handler;
3440 #undef _
3441
3442 #define _(n)                                    \
3443     static void vl_api_##n##_t_handler_json     \
3444     (vl_api_##n##_t * mp)                       \
3445     {                                           \
3446         vat_main_t * vam = &vat_main;           \
3447         vat_json_node_t node;                   \
3448         vat_json_init_object(&node);            \
3449         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3450         vat_json_print(vam->ofp, &node);        \
3451         vam->retval = ntohl(mp->retval);        \
3452         vam->result_ready = 1;                  \
3453     }
3454 foreach_standard_reply_retval_handler;
3455 #undef _
3456
3457 /*
3458  * Table of message reply handlers, must include boilerplate handlers
3459  * we just generated
3460  */
3461
3462 #define foreach_vpe_api_reply_msg                                       \
3463 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3464 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3465 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3466 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3467 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3468 _(CLI_REPLY, cli_reply)                                                 \
3469 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3470 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3471   sw_interface_add_del_address_reply)                                   \
3472 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3473 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3474 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3475   sw_interface_set_l2_xconnect_reply)                                   \
3476 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3477   sw_interface_set_l2_bridge_reply)                                     \
3478 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3479 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3480 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3481 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3482 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3483 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3484 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3485 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3486 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3487 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3488 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3489 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3490 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3491   proxy_arp_intfc_enable_disable_reply)                                 \
3492 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3493 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3494 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3495 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3496   mpls_ethernet_add_del_tunnel_reply)                                   \
3497 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3498   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3499 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3500   sw_interface_set_unnumbered_reply)                                    \
3501 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3502 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3503 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3504 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3505 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3506 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3507 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3508 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3509 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3510 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3511 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3512 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3513   sw_interface_ip6_enable_disable_reply)                                \
3514 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3515   sw_interface_ip6_set_link_local_address_reply)                        \
3516 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3517   sw_interface_ip6nd_ra_prefix_reply)                                   \
3518 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3519   sw_interface_ip6nd_ra_config_reply)                                   \
3520 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3521 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3522 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3523 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3524 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3525 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3526 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3527 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3528 classify_set_interface_ip_table_reply)                                  \
3529 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3530   classify_set_interface_l2_tables_reply)                               \
3531 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3532 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3533 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3534 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3535 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3536   l2tpv3_interface_enable_disable_reply)                                \
3537 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3538 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3539 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3540 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3541 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3542 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3543 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3544 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3545 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3546 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3547 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3548 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3549 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3550 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3551 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3552 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3553 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3554 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3555 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3556 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3557 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3558 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3559 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3560 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3561 _(IP_DETAILS, ip_details)                                               \
3562 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3563 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3564 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3565 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3566 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3567 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3568 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3569 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3570 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3571 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3572 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3573 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3574 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3575 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3576 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3577 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3578 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3579 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3580 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3581 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3582 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3583 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3584 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3585 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3586 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3587 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3588 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3589 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3590 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3591 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3592 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3593 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3594 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3595 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3596 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3597 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3598 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3599 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3600 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3601 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3602 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3603 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3604 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3605 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3606 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3607 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3608 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3609 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3610 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3611 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3612 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3613   lisp_add_del_map_request_itr_rlocs_reply)                             \
3614 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3615   lisp_get_map_request_itr_rlocs_reply)                                 \
3616 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3617 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3618 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3619 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3620 _(POLICER_DETAILS, policer_details)                                     \
3621 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3622 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3623 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3624 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3625 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3626 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3627 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3628 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3629 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3630 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3631 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3632 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3633 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3634 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3635 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3636 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3637 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3638 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3639 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3640 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3641 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3642 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3643 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3644  ip_source_and_port_range_check_add_del_reply)                          \
3645 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3646  ip_source_and_port_range_check_interface_add_del_reply)                \
3647 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3648 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3649 _(DELETE_SUBIF_REPLY, delete_subif_reply)
3650
3651 /* M: construct, but don't yet send a message */
3652
3653 #define M(T,t)                                  \
3654 do {                                            \
3655     vam->result_ready = 0;                      \
3656     mp = vl_msg_api_alloc(sizeof(*mp));         \
3657     memset (mp, 0, sizeof (*mp));               \
3658     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3659     mp->client_index = vam->my_client_index;    \
3660 } while(0);
3661
3662 #define M2(T,t,n)                               \
3663 do {                                            \
3664     vam->result_ready = 0;                      \
3665     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3666     memset (mp, 0, sizeof (*mp));               \
3667     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3668     mp->client_index = vam->my_client_index;    \
3669 } while(0);
3670
3671
3672 /* S: send a message */
3673 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3674
3675 /* W: wait for results, with timeout */
3676 #define W                                       \
3677 do {                                            \
3678     timeout = vat_time_now (vam) + 1.0;         \
3679                                                 \
3680     while (vat_time_now (vam) < timeout) {      \
3681         if (vam->result_ready == 1) {           \
3682             return (vam->retval);               \
3683         }                                       \
3684     }                                           \
3685     return -99;                                 \
3686 } while(0);
3687
3688 /* W2: wait for results, with timeout */
3689 #define W2(body)                                \
3690 do {                                            \
3691     timeout = vat_time_now (vam) + 1.0;         \
3692                                                 \
3693     while (vat_time_now (vam) < timeout) {      \
3694         if (vam->result_ready == 1) {           \
3695           (body);                               \
3696           return (vam->retval);                 \
3697         }                                       \
3698     }                                           \
3699     return -99;                                 \
3700 } while(0);
3701
3702 typedef struct
3703 {
3704   u8 *name;
3705   u32 value;
3706 } name_sort_t;
3707
3708
3709 #define STR_VTR_OP_CASE(op)     \
3710     case L2_VTR_ ## op:         \
3711         return "" # op;
3712
3713 static const char *
3714 str_vtr_op (u32 vtr_op)
3715 {
3716   switch (vtr_op)
3717     {
3718       STR_VTR_OP_CASE (DISABLED);
3719       STR_VTR_OP_CASE (PUSH_1);
3720       STR_VTR_OP_CASE (PUSH_2);
3721       STR_VTR_OP_CASE (POP_1);
3722       STR_VTR_OP_CASE (POP_2);
3723       STR_VTR_OP_CASE (TRANSLATE_1_1);
3724       STR_VTR_OP_CASE (TRANSLATE_1_2);
3725       STR_VTR_OP_CASE (TRANSLATE_2_1);
3726       STR_VTR_OP_CASE (TRANSLATE_2_2);
3727     }
3728
3729   return "UNKNOWN";
3730 }
3731
3732 static int
3733 dump_sub_interface_table (vat_main_t * vam)
3734 {
3735   const sw_interface_subif_t *sub = NULL;
3736
3737   if (vam->json_output)
3738     {
3739       clib_warning
3740         ("JSON output supported only for VPE API calls and dump_stats_table");
3741       return -99;
3742     }
3743
3744   fformat (vam->ofp,
3745            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3746            "Interface", "sw_if_index",
3747            "sub id", "dot1ad", "tags", "outer id",
3748            "inner id", "exact", "default", "outer any", "inner any");
3749
3750   vec_foreach (sub, vam->sw_if_subif_table)
3751   {
3752     fformat (vam->ofp,
3753              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3754              sub->interface_name,
3755              sub->sw_if_index,
3756              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3757              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3758              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3759              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3760     if (sub->vtr_op != L2_VTR_DISABLED)
3761       {
3762         fformat (vam->ofp,
3763                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3764                  "tag1: %d tag2: %d ]\n",
3765                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3766                  sub->vtr_tag1, sub->vtr_tag2);
3767       }
3768   }
3769
3770   return 0;
3771 }
3772
3773 static int
3774 name_sort_cmp (void *a1, void *a2)
3775 {
3776   name_sort_t *n1 = a1;
3777   name_sort_t *n2 = a2;
3778
3779   return strcmp ((char *) n1->name, (char *) n2->name);
3780 }
3781
3782 static int
3783 dump_interface_table (vat_main_t * vam)
3784 {
3785   hash_pair_t *p;
3786   name_sort_t *nses = 0, *ns;
3787
3788   if (vam->json_output)
3789     {
3790       clib_warning
3791         ("JSON output supported only for VPE API calls and dump_stats_table");
3792       return -99;
3793     }
3794
3795   /* *INDENT-OFF* */
3796   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3797   ({
3798     vec_add2 (nses, ns, 1);
3799     ns->name = (u8 *)(p->key);
3800     ns->value = (u32) p->value[0];
3801   }));
3802   /* *INDENT-ON* */
3803
3804   vec_sort_with_function (nses, name_sort_cmp);
3805
3806   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3807   vec_foreach (ns, nses)
3808   {
3809     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3810   }
3811   vec_free (nses);
3812   return 0;
3813 }
3814
3815 static int
3816 dump_ip_table (vat_main_t * vam, int is_ipv6)
3817 {
3818   const ip_details_t *det = NULL;
3819   const ip_address_details_t *address = NULL;
3820   u32 i = ~0;
3821
3822   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3823
3824   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3825   {
3826     i++;
3827     if (!det->present)
3828       {
3829         continue;
3830       }
3831     fformat (vam->ofp, "%-12d\n", i);
3832     fformat (vam->ofp,
3833              "            %-30s%-13s\n", "Address", "Prefix length");
3834     if (!det->addr)
3835       {
3836         continue;
3837       }
3838     vec_foreach (address, det->addr)
3839     {
3840       fformat (vam->ofp,
3841                "            %-30U%-13d\n",
3842                is_ipv6 ? format_ip6_address : format_ip4_address,
3843                address->ip, address->prefix_length);
3844     }
3845   }
3846
3847   return 0;
3848 }
3849
3850 static int
3851 dump_ipv4_table (vat_main_t * vam)
3852 {
3853   if (vam->json_output)
3854     {
3855       clib_warning
3856         ("JSON output supported only for VPE API calls and dump_stats_table");
3857       return -99;
3858     }
3859
3860   return dump_ip_table (vam, 0);
3861 }
3862
3863 static int
3864 dump_ipv6_table (vat_main_t * vam)
3865 {
3866   if (vam->json_output)
3867     {
3868       clib_warning
3869         ("JSON output supported only for VPE API calls and dump_stats_table");
3870       return -99;
3871     }
3872
3873   return dump_ip_table (vam, 1);
3874 }
3875
3876 static char *
3877 counter_type_to_str (u8 counter_type, u8 is_combined)
3878 {
3879   if (!is_combined)
3880     {
3881       switch (counter_type)
3882         {
3883         case VNET_INTERFACE_COUNTER_DROP:
3884           return "drop";
3885         case VNET_INTERFACE_COUNTER_PUNT:
3886           return "punt";
3887         case VNET_INTERFACE_COUNTER_IP4:
3888           return "ip4";
3889         case VNET_INTERFACE_COUNTER_IP6:
3890           return "ip6";
3891         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3892           return "rx-no-buf";
3893         case VNET_INTERFACE_COUNTER_RX_MISS:
3894           return "rx-miss";
3895         case VNET_INTERFACE_COUNTER_RX_ERROR:
3896           return "rx-error";
3897         case VNET_INTERFACE_COUNTER_TX_ERROR:
3898           return "tx-error";
3899         default:
3900           return "INVALID-COUNTER-TYPE";
3901         }
3902     }
3903   else
3904     {
3905       switch (counter_type)
3906         {
3907         case VNET_INTERFACE_COUNTER_RX:
3908           return "rx";
3909         case VNET_INTERFACE_COUNTER_TX:
3910           return "tx";
3911         default:
3912           return "INVALID-COUNTER-TYPE";
3913         }
3914     }
3915 }
3916
3917 static int
3918 dump_stats_table (vat_main_t * vam)
3919 {
3920   vat_json_node_t node;
3921   vat_json_node_t *msg_array;
3922   vat_json_node_t *msg;
3923   vat_json_node_t *counter_array;
3924   vat_json_node_t *counter;
3925   interface_counter_t c;
3926   u64 packets;
3927   ip4_fib_counter_t *c4;
3928   ip6_fib_counter_t *c6;
3929   int i, j;
3930
3931   if (!vam->json_output)
3932     {
3933       clib_warning ("dump_stats_table supported only in JSON format");
3934       return -99;
3935     }
3936
3937   vat_json_init_object (&node);
3938
3939   /* interface counters */
3940   msg_array = vat_json_object_add (&node, "interface_counters");
3941   vat_json_init_array (msg_array);
3942   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
3943     {
3944       msg = vat_json_array_add (msg_array);
3945       vat_json_init_object (msg);
3946       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3947                                        (u8 *) counter_type_to_str (i, 0));
3948       vat_json_object_add_int (msg, "is_combined", 0);
3949       counter_array = vat_json_object_add (msg, "data");
3950       vat_json_init_array (counter_array);
3951       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
3952         {
3953           packets = vam->simple_interface_counters[i][j];
3954           vat_json_array_add_uint (counter_array, packets);
3955         }
3956     }
3957   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
3958     {
3959       msg = vat_json_array_add (msg_array);
3960       vat_json_init_object (msg);
3961       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3962                                        (u8 *) counter_type_to_str (i, 1));
3963       vat_json_object_add_int (msg, "is_combined", 1);
3964       counter_array = vat_json_object_add (msg, "data");
3965       vat_json_init_array (counter_array);
3966       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
3967         {
3968           c = vam->combined_interface_counters[i][j];
3969           counter = vat_json_array_add (counter_array);
3970           vat_json_init_object (counter);
3971           vat_json_object_add_uint (counter, "packets", c.packets);
3972           vat_json_object_add_uint (counter, "bytes", c.bytes);
3973         }
3974     }
3975
3976   /* ip4 fib counters */
3977   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
3978   vat_json_init_array (msg_array);
3979   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
3980     {
3981       msg = vat_json_array_add (msg_array);
3982       vat_json_init_object (msg);
3983       vat_json_object_add_uint (msg, "vrf_id",
3984                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
3985       counter_array = vat_json_object_add (msg, "c");
3986       vat_json_init_array (counter_array);
3987       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
3988         {
3989           counter = vat_json_array_add (counter_array);
3990           vat_json_init_object (counter);
3991           c4 = &vam->ip4_fib_counters[i][j];
3992           vat_json_object_add_ip4 (counter, "address", c4->address);
3993           vat_json_object_add_uint (counter, "address_length",
3994                                     c4->address_length);
3995           vat_json_object_add_uint (counter, "packets", c4->packets);
3996           vat_json_object_add_uint (counter, "bytes", c4->bytes);
3997         }
3998     }
3999
4000   /* ip6 fib counters */
4001   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4002   vat_json_init_array (msg_array);
4003   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4004     {
4005       msg = vat_json_array_add (msg_array);
4006       vat_json_init_object (msg);
4007       vat_json_object_add_uint (msg, "vrf_id",
4008                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4009       counter_array = vat_json_object_add (msg, "c");
4010       vat_json_init_array (counter_array);
4011       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4012         {
4013           counter = vat_json_array_add (counter_array);
4014           vat_json_init_object (counter);
4015           c6 = &vam->ip6_fib_counters[i][j];
4016           vat_json_object_add_ip6 (counter, "address", c6->address);
4017           vat_json_object_add_uint (counter, "address_length",
4018                                     c6->address_length);
4019           vat_json_object_add_uint (counter, "packets", c6->packets);
4020           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4021         }
4022     }
4023
4024   vat_json_print (vam->ofp, &node);
4025   vat_json_free (&node);
4026
4027   return 0;
4028 }
4029
4030 int
4031 exec (vat_main_t * vam)
4032 {
4033   api_main_t *am = &api_main;
4034   vl_api_cli_request_t *mp;
4035   f64 timeout;
4036   void *oldheap;
4037   u8 *cmd = 0;
4038   unformat_input_t *i = vam->input;
4039
4040   if (vec_len (i->buffer) == 0)
4041     return -1;
4042
4043   if (vam->exec_mode == 0 && unformat (i, "mode"))
4044     {
4045       vam->exec_mode = 1;
4046       return 0;
4047     }
4048   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4049     {
4050       vam->exec_mode = 0;
4051       return 0;
4052     }
4053
4054
4055   M (CLI_REQUEST, cli_request);
4056
4057   /*
4058    * Copy cmd into shared memory.
4059    * In order for the CLI command to work, it
4060    * must be a vector ending in \n, not a C-string ending
4061    * in \n\0.
4062    */
4063   pthread_mutex_lock (&am->vlib_rp->mutex);
4064   oldheap = svm_push_data_heap (am->vlib_rp);
4065
4066   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4067   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4068
4069   svm_pop_heap (oldheap);
4070   pthread_mutex_unlock (&am->vlib_rp->mutex);
4071
4072   mp->cmd_in_shmem = (u64) cmd;
4073   S;
4074   timeout = vat_time_now (vam) + 10.0;
4075
4076   while (vat_time_now (vam) < timeout)
4077     {
4078       if (vam->result_ready == 1)
4079         {
4080           u8 *free_me;
4081           if (vam->shmem_result != NULL)
4082             fformat (vam->ofp, "%s", vam->shmem_result);
4083           pthread_mutex_lock (&am->vlib_rp->mutex);
4084           oldheap = svm_push_data_heap (am->vlib_rp);
4085
4086           free_me = (u8 *) vam->shmem_result;
4087           vec_free (free_me);
4088
4089           svm_pop_heap (oldheap);
4090           pthread_mutex_unlock (&am->vlib_rp->mutex);
4091           return 0;
4092         }
4093     }
4094   return -99;
4095 }
4096
4097 /*
4098  * Future replacement of exec() that passes CLI buffers directly in
4099  * the API messages instead of an additional shared memory area.
4100  */
4101 static int
4102 exec_inband (vat_main_t * vam)
4103 {
4104   vl_api_cli_inband_t *mp;
4105   f64 timeout;
4106   unformat_input_t *i = vam->input;
4107
4108   if (vec_len (i->buffer) == 0)
4109     return -1;
4110
4111   if (vam->exec_mode == 0 && unformat (i, "mode"))
4112     {
4113       vam->exec_mode = 1;
4114       return 0;
4115     }
4116   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4117     {
4118       vam->exec_mode = 0;
4119       return 0;
4120     }
4121
4122   /*
4123    * In order for the CLI command to work, it
4124    * must be a vector ending in \n, not a C-string ending
4125    * in \n\0.
4126    */
4127   u32 len = vec_len (vam->input->buffer);
4128   M2 (CLI_INBAND, cli_inband, len);
4129   clib_memcpy (mp->cmd, vam->input->buffer, len);
4130   mp->length = htonl (len);
4131
4132   S;
4133   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4134 }
4135
4136 static int
4137 api_create_loopback (vat_main_t * vam)
4138 {
4139   unformat_input_t *i = vam->input;
4140   vl_api_create_loopback_t *mp;
4141   f64 timeout;
4142   u8 mac_address[6];
4143   u8 mac_set = 0;
4144
4145   memset (mac_address, 0, sizeof (mac_address));
4146
4147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4148     {
4149       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4150         mac_set = 1;
4151       else
4152         break;
4153     }
4154
4155   /* Construct the API message */
4156   M (CREATE_LOOPBACK, create_loopback);
4157   if (mac_set)
4158     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4159
4160   S;
4161   W;
4162 }
4163
4164 static int
4165 api_delete_loopback (vat_main_t * vam)
4166 {
4167   unformat_input_t *i = vam->input;
4168   vl_api_delete_loopback_t *mp;
4169   f64 timeout;
4170   u32 sw_if_index = ~0;
4171
4172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4173     {
4174       if (unformat (i, "sw_if_index %d", &sw_if_index))
4175         ;
4176       else
4177         break;
4178     }
4179
4180   if (sw_if_index == ~0)
4181     {
4182       errmsg ("missing sw_if_index\n");
4183       return -99;
4184     }
4185
4186   /* Construct the API message */
4187   M (DELETE_LOOPBACK, delete_loopback);
4188   mp->sw_if_index = ntohl (sw_if_index);
4189
4190   S;
4191   W;
4192 }
4193
4194 static int
4195 api_want_stats (vat_main_t * vam)
4196 {
4197   unformat_input_t *i = vam->input;
4198   vl_api_want_stats_t *mp;
4199   f64 timeout;
4200   int enable = -1;
4201
4202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4203     {
4204       if (unformat (i, "enable"))
4205         enable = 1;
4206       else if (unformat (i, "disable"))
4207         enable = 0;
4208       else
4209         break;
4210     }
4211
4212   if (enable == -1)
4213     {
4214       errmsg ("missing enable|disable\n");
4215       return -99;
4216     }
4217
4218   M (WANT_STATS, want_stats);
4219   mp->enable_disable = enable;
4220
4221   S;
4222   W;
4223 }
4224
4225 static int
4226 api_want_interface_events (vat_main_t * vam)
4227 {
4228   unformat_input_t *i = vam->input;
4229   vl_api_want_interface_events_t *mp;
4230   f64 timeout;
4231   int enable = -1;
4232
4233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4234     {
4235       if (unformat (i, "enable"))
4236         enable = 1;
4237       else if (unformat (i, "disable"))
4238         enable = 0;
4239       else
4240         break;
4241     }
4242
4243   if (enable == -1)
4244     {
4245       errmsg ("missing enable|disable\n");
4246       return -99;
4247     }
4248
4249   M (WANT_INTERFACE_EVENTS, want_interface_events);
4250   mp->enable_disable = enable;
4251
4252   vam->interface_event_display = enable;
4253
4254   S;
4255   W;
4256 }
4257
4258
4259 /* Note: non-static, called once to set up the initial intfc table */
4260 int
4261 api_sw_interface_dump (vat_main_t * vam)
4262 {
4263   vl_api_sw_interface_dump_t *mp;
4264   f64 timeout;
4265   hash_pair_t *p;
4266   name_sort_t *nses = 0, *ns;
4267   sw_interface_subif_t *sub = NULL;
4268
4269   /* Toss the old name table */
4270   /* *INDENT-OFF* */
4271   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4272   ({
4273     vec_add2 (nses, ns, 1);
4274     ns->name = (u8 *)(p->key);
4275     ns->value = (u32) p->value[0];
4276   }));
4277   /* *INDENT-ON* */
4278
4279   hash_free (vam->sw_if_index_by_interface_name);
4280
4281   vec_foreach (ns, nses) vec_free (ns->name);
4282
4283   vec_free (nses);
4284
4285   vec_foreach (sub, vam->sw_if_subif_table)
4286   {
4287     vec_free (sub->interface_name);
4288   }
4289   vec_free (vam->sw_if_subif_table);
4290
4291   /* recreate the interface name hash table */
4292   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4293
4294   /* Get list of ethernets */
4295   M (SW_INTERFACE_DUMP, sw_interface_dump);
4296   mp->name_filter_valid = 1;
4297   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4298   S;
4299
4300   /* and local / loopback interfaces */
4301   M (SW_INTERFACE_DUMP, sw_interface_dump);
4302   mp->name_filter_valid = 1;
4303   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4304   S;
4305
4306
4307   /* and vxlan-gpe tunnel interfaces */
4308   M (SW_INTERFACE_DUMP, sw_interface_dump);
4309   mp->name_filter_valid = 1;
4310   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4311            sizeof (mp->name_filter) - 1);
4312   S;
4313
4314   /* and vxlan tunnel interfaces */
4315   M (SW_INTERFACE_DUMP, sw_interface_dump);
4316   mp->name_filter_valid = 1;
4317   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4318   S;
4319
4320   /* and host (af_packet) interfaces */
4321   M (SW_INTERFACE_DUMP, sw_interface_dump);
4322   mp->name_filter_valid = 1;
4323   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4324   S;
4325
4326   /* and l2tpv3 tunnel interfaces */
4327   M (SW_INTERFACE_DUMP, sw_interface_dump);
4328   mp->name_filter_valid = 1;
4329   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4330            sizeof (mp->name_filter) - 1);
4331   S;
4332
4333   /* and GRE tunnel interfaces */
4334   M (SW_INTERFACE_DUMP, sw_interface_dump);
4335   mp->name_filter_valid = 1;
4336   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4337   S;
4338
4339   /* and LISP-GPE interfaces */
4340   M (SW_INTERFACE_DUMP, sw_interface_dump);
4341   mp->name_filter_valid = 1;
4342   strncpy ((char *) mp->name_filter, "lisp_gpe",
4343            sizeof (mp->name_filter) - 1);
4344   S;
4345
4346   /* and IPSEC tunnel interfaces */
4347   M (SW_INTERFACE_DUMP, sw_interface_dump);
4348   mp->name_filter_valid = 1;
4349   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4350   S;
4351
4352   /* Use a control ping for synchronization */
4353   {
4354     vl_api_control_ping_t *mp;
4355     M (CONTROL_PING, control_ping);
4356     S;
4357   }
4358   W;
4359 }
4360
4361 static int
4362 api_sw_interface_set_flags (vat_main_t * vam)
4363 {
4364   unformat_input_t *i = vam->input;
4365   vl_api_sw_interface_set_flags_t *mp;
4366   f64 timeout;
4367   u32 sw_if_index;
4368   u8 sw_if_index_set = 0;
4369   u8 admin_up = 0, link_up = 0;
4370
4371   /* Parse args required to build the message */
4372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4373     {
4374       if (unformat (i, "admin-up"))
4375         admin_up = 1;
4376       else if (unformat (i, "admin-down"))
4377         admin_up = 0;
4378       else if (unformat (i, "link-up"))
4379         link_up = 1;
4380       else if (unformat (i, "link-down"))
4381         link_up = 0;
4382       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4383         sw_if_index_set = 1;
4384       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4385         sw_if_index_set = 1;
4386       else
4387         break;
4388     }
4389
4390   if (sw_if_index_set == 0)
4391     {
4392       errmsg ("missing interface name or sw_if_index\n");
4393       return -99;
4394     }
4395
4396   /* Construct the API message */
4397   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4398   mp->sw_if_index = ntohl (sw_if_index);
4399   mp->admin_up_down = admin_up;
4400   mp->link_up_down = link_up;
4401
4402   /* send it... */
4403   S;
4404
4405   /* Wait for a reply, return the good/bad news... */
4406   W;
4407 }
4408
4409 static int
4410 api_sw_interface_clear_stats (vat_main_t * vam)
4411 {
4412   unformat_input_t *i = vam->input;
4413   vl_api_sw_interface_clear_stats_t *mp;
4414   f64 timeout;
4415   u32 sw_if_index;
4416   u8 sw_if_index_set = 0;
4417
4418   /* Parse args required to build the message */
4419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4420     {
4421       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4422         sw_if_index_set = 1;
4423       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4424         sw_if_index_set = 1;
4425       else
4426         break;
4427     }
4428
4429   /* Construct the API message */
4430   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4431
4432   if (sw_if_index_set == 1)
4433     mp->sw_if_index = ntohl (sw_if_index);
4434   else
4435     mp->sw_if_index = ~0;
4436
4437   /* send it... */
4438   S;
4439
4440   /* Wait for a reply, return the good/bad news... */
4441   W;
4442 }
4443
4444 static int
4445 api_sw_interface_add_del_address (vat_main_t * vam)
4446 {
4447   unformat_input_t *i = vam->input;
4448   vl_api_sw_interface_add_del_address_t *mp;
4449   f64 timeout;
4450   u32 sw_if_index;
4451   u8 sw_if_index_set = 0;
4452   u8 is_add = 1, del_all = 0;
4453   u32 address_length = 0;
4454   u8 v4_address_set = 0;
4455   u8 v6_address_set = 0;
4456   ip4_address_t v4address;
4457   ip6_address_t v6address;
4458
4459   /* Parse args required to build the message */
4460   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4461     {
4462       if (unformat (i, "del-all"))
4463         del_all = 1;
4464       else if (unformat (i, "del"))
4465         is_add = 0;
4466       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4467         sw_if_index_set = 1;
4468       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4469         sw_if_index_set = 1;
4470       else if (unformat (i, "%U/%d",
4471                          unformat_ip4_address, &v4address, &address_length))
4472         v4_address_set = 1;
4473       else if (unformat (i, "%U/%d",
4474                          unformat_ip6_address, &v6address, &address_length))
4475         v6_address_set = 1;
4476       else
4477         break;
4478     }
4479
4480   if (sw_if_index_set == 0)
4481     {
4482       errmsg ("missing interface name or sw_if_index\n");
4483       return -99;
4484     }
4485   if (v4_address_set && v6_address_set)
4486     {
4487       errmsg ("both v4 and v6 addresses set\n");
4488       return -99;
4489     }
4490   if (!v4_address_set && !v6_address_set && !del_all)
4491     {
4492       errmsg ("no addresses set\n");
4493       return -99;
4494     }
4495
4496   /* Construct the API message */
4497   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4498
4499   mp->sw_if_index = ntohl (sw_if_index);
4500   mp->is_add = is_add;
4501   mp->del_all = del_all;
4502   if (v6_address_set)
4503     {
4504       mp->is_ipv6 = 1;
4505       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4506     }
4507   else
4508     {
4509       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4510     }
4511   mp->address_length = address_length;
4512
4513   /* send it... */
4514   S;
4515
4516   /* Wait for a reply, return good/bad news  */
4517   W;
4518 }
4519
4520 static int
4521 api_sw_interface_set_table (vat_main_t * vam)
4522 {
4523   unformat_input_t *i = vam->input;
4524   vl_api_sw_interface_set_table_t *mp;
4525   f64 timeout;
4526   u32 sw_if_index, vrf_id = 0;
4527   u8 sw_if_index_set = 0;
4528   u8 is_ipv6 = 0;
4529
4530   /* Parse args required to build the message */
4531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4532     {
4533       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4534         sw_if_index_set = 1;
4535       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4536         sw_if_index_set = 1;
4537       else if (unformat (i, "vrf %d", &vrf_id))
4538         ;
4539       else if (unformat (i, "ipv6"))
4540         is_ipv6 = 1;
4541       else
4542         break;
4543     }
4544
4545   if (sw_if_index_set == 0)
4546     {
4547       errmsg ("missing interface name or sw_if_index\n");
4548       return -99;
4549     }
4550
4551   /* Construct the API message */
4552   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4553
4554   mp->sw_if_index = ntohl (sw_if_index);
4555   mp->is_ipv6 = is_ipv6;
4556   mp->vrf_id = ntohl (vrf_id);
4557
4558   /* send it... */
4559   S;
4560
4561   /* Wait for a reply... */
4562   W;
4563 }
4564
4565 static int
4566 api_sw_interface_set_vpath (vat_main_t * vam)
4567 {
4568   unformat_input_t *i = vam->input;
4569   vl_api_sw_interface_set_vpath_t *mp;
4570   f64 timeout;
4571   u32 sw_if_index = 0;
4572   u8 sw_if_index_set = 0;
4573   u8 is_enable = 0;
4574
4575   /* Parse args required to build the message */
4576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4577     {
4578       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4579         sw_if_index_set = 1;
4580       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4581         sw_if_index_set = 1;
4582       else if (unformat (i, "enable"))
4583         is_enable = 1;
4584       else if (unformat (i, "disable"))
4585         is_enable = 0;
4586       else
4587         break;
4588     }
4589
4590   if (sw_if_index_set == 0)
4591     {
4592       errmsg ("missing interface name or sw_if_index\n");
4593       return -99;
4594     }
4595
4596   /* Construct the API message */
4597   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4598
4599   mp->sw_if_index = ntohl (sw_if_index);
4600   mp->enable = is_enable;
4601
4602   /* send it... */
4603   S;
4604
4605   /* Wait for a reply... */
4606   W;
4607 }
4608
4609 static int
4610 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4611 {
4612   unformat_input_t *i = vam->input;
4613   vl_api_sw_interface_set_l2_xconnect_t *mp;
4614   f64 timeout;
4615   u32 rx_sw_if_index;
4616   u8 rx_sw_if_index_set = 0;
4617   u32 tx_sw_if_index;
4618   u8 tx_sw_if_index_set = 0;
4619   u8 enable = 1;
4620
4621   /* Parse args required to build the message */
4622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4623     {
4624       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4625         rx_sw_if_index_set = 1;
4626       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4627         tx_sw_if_index_set = 1;
4628       else if (unformat (i, "rx"))
4629         {
4630           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4631             {
4632               if (unformat (i, "%U", unformat_sw_if_index, vam,
4633                             &rx_sw_if_index))
4634                 rx_sw_if_index_set = 1;
4635             }
4636           else
4637             break;
4638         }
4639       else if (unformat (i, "tx"))
4640         {
4641           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4642             {
4643               if (unformat (i, "%U", unformat_sw_if_index, vam,
4644                             &tx_sw_if_index))
4645                 tx_sw_if_index_set = 1;
4646             }
4647           else
4648             break;
4649         }
4650       else if (unformat (i, "enable"))
4651         enable = 1;
4652       else if (unformat (i, "disable"))
4653         enable = 0;
4654       else
4655         break;
4656     }
4657
4658   if (rx_sw_if_index_set == 0)
4659     {
4660       errmsg ("missing rx interface name or rx_sw_if_index\n");
4661       return -99;
4662     }
4663
4664   if (enable && (tx_sw_if_index_set == 0))
4665     {
4666       errmsg ("missing tx interface name or tx_sw_if_index\n");
4667       return -99;
4668     }
4669
4670   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4671
4672   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4673   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4674   mp->enable = enable;
4675
4676   S;
4677   W;
4678   /* NOTREACHED */
4679   return 0;
4680 }
4681
4682 static int
4683 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4684 {
4685   unformat_input_t *i = vam->input;
4686   vl_api_sw_interface_set_l2_bridge_t *mp;
4687   f64 timeout;
4688   u32 rx_sw_if_index;
4689   u8 rx_sw_if_index_set = 0;
4690   u32 bd_id;
4691   u8 bd_id_set = 0;
4692   u8 bvi = 0;
4693   u32 shg = 0;
4694   u8 enable = 1;
4695
4696   /* Parse args required to build the message */
4697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4698     {
4699       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4700         rx_sw_if_index_set = 1;
4701       else if (unformat (i, "bd_id %d", &bd_id))
4702         bd_id_set = 1;
4703       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
4704         rx_sw_if_index_set = 1;
4705       else if (unformat (i, "shg %d", &shg))
4706         ;
4707       else if (unformat (i, "bvi"))
4708         bvi = 1;
4709       else if (unformat (i, "enable"))
4710         enable = 1;
4711       else if (unformat (i, "disable"))
4712         enable = 0;
4713       else
4714         break;
4715     }
4716
4717   if (rx_sw_if_index_set == 0)
4718     {
4719       errmsg ("missing rx interface name or sw_if_index\n");
4720       return -99;
4721     }
4722
4723   if (enable && (bd_id_set == 0))
4724     {
4725       errmsg ("missing bridge domain\n");
4726       return -99;
4727     }
4728
4729   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
4730
4731   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4732   mp->bd_id = ntohl (bd_id);
4733   mp->shg = (u8) shg;
4734   mp->bvi = bvi;
4735   mp->enable = enable;
4736
4737   S;
4738   W;
4739   /* NOTREACHED */
4740   return 0;
4741 }
4742
4743 static int
4744 api_bridge_domain_dump (vat_main_t * vam)
4745 {
4746   unformat_input_t *i = vam->input;
4747   vl_api_bridge_domain_dump_t *mp;
4748   f64 timeout;
4749   u32 bd_id = ~0;
4750
4751   /* Parse args required to build the message */
4752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4753     {
4754       if (unformat (i, "bd_id %d", &bd_id))
4755         ;
4756       else
4757         break;
4758     }
4759
4760   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
4761   mp->bd_id = ntohl (bd_id);
4762   S;
4763
4764   /* Use a control ping for synchronization */
4765   {
4766     vl_api_control_ping_t *mp;
4767     M (CONTROL_PING, control_ping);
4768     S;
4769   }
4770
4771   W;
4772   /* NOTREACHED */
4773   return 0;
4774 }
4775
4776 static int
4777 api_bridge_domain_add_del (vat_main_t * vam)
4778 {
4779   unformat_input_t *i = vam->input;
4780   vl_api_bridge_domain_add_del_t *mp;
4781   f64 timeout;
4782   u32 bd_id = ~0;
4783   u8 is_add = 1;
4784   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4785
4786   /* Parse args required to build the message */
4787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4788     {
4789       if (unformat (i, "bd_id %d", &bd_id))
4790         ;
4791       else if (unformat (i, "flood %d", &flood))
4792         ;
4793       else if (unformat (i, "uu-flood %d", &uu_flood))
4794         ;
4795       else if (unformat (i, "forward %d", &forward))
4796         ;
4797       else if (unformat (i, "learn %d", &learn))
4798         ;
4799       else if (unformat (i, "arp-term %d", &arp_term))
4800         ;
4801       else if (unformat (i, "del"))
4802         {
4803           is_add = 0;
4804           flood = uu_flood = forward = learn = 0;
4805         }
4806       else
4807         break;
4808     }
4809
4810   if (bd_id == ~0)
4811     {
4812       errmsg ("missing bridge domain\n");
4813       return -99;
4814     }
4815
4816   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
4817
4818   mp->bd_id = ntohl (bd_id);
4819   mp->flood = flood;
4820   mp->uu_flood = uu_flood;
4821   mp->forward = forward;
4822   mp->learn = learn;
4823   mp->arp_term = arp_term;
4824   mp->is_add = is_add;
4825
4826   S;
4827   W;
4828   /* NOTREACHED */
4829   return 0;
4830 }
4831
4832 static int
4833 api_l2fib_add_del (vat_main_t * vam)
4834 {
4835   unformat_input_t *i = vam->input;
4836   vl_api_l2fib_add_del_t *mp;
4837   f64 timeout;
4838   u64 mac = 0;
4839   u8 mac_set = 0;
4840   u32 bd_id;
4841   u8 bd_id_set = 0;
4842   u32 sw_if_index;
4843   u8 sw_if_index_set = 0;
4844   u8 is_add = 1;
4845   u8 static_mac = 0;
4846   u8 filter_mac = 0;
4847   u8 bvi_mac = 0;
4848   int count = 1;
4849   f64 before = 0;
4850   int j;
4851
4852   /* Parse args required to build the message */
4853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4854     {
4855       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
4856         mac_set = 1;
4857       else if (unformat (i, "bd_id %d", &bd_id))
4858         bd_id_set = 1;
4859       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4860         sw_if_index_set = 1;
4861       else if (unformat (i, "sw_if"))
4862         {
4863           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4864             {
4865               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4866                 sw_if_index_set = 1;
4867             }
4868           else
4869             break;
4870         }
4871       else if (unformat (i, "static"))
4872         static_mac = 1;
4873       else if (unformat (i, "filter"))
4874         {
4875           filter_mac = 1;
4876           static_mac = 1;
4877         }
4878       else if (unformat (i, "bvi"))
4879         {
4880           bvi_mac = 1;
4881           static_mac = 1;
4882         }
4883       else if (unformat (i, "del"))
4884         is_add = 0;
4885       else if (unformat (i, "count %d", &count))
4886         ;
4887       else
4888         break;
4889     }
4890
4891   if (mac_set == 0)
4892     {
4893       errmsg ("missing mac address\n");
4894       return -99;
4895     }
4896
4897   if (bd_id_set == 0)
4898     {
4899       errmsg ("missing bridge domain\n");
4900       return -99;
4901     }
4902
4903   if (is_add && (sw_if_index_set == 0))
4904     {
4905       errmsg ("missing interface name or sw_if_index\n");
4906       return -99;
4907     }
4908
4909   if (count > 1)
4910     {
4911       /* Turn on async mode */
4912       vam->async_mode = 1;
4913       vam->async_errors = 0;
4914       before = vat_time_now (vam);
4915     }
4916
4917   for (j = 0; j < count; j++)
4918     {
4919       M (L2FIB_ADD_DEL, l2fib_add_del);
4920
4921       mp->mac = mac;
4922       mp->bd_id = ntohl (bd_id);
4923       mp->is_add = is_add;
4924
4925       if (is_add)
4926         {
4927           mp->sw_if_index = ntohl (sw_if_index);
4928           mp->static_mac = static_mac;
4929           mp->filter_mac = filter_mac;
4930           mp->bvi_mac = bvi_mac;
4931         }
4932       increment_mac_address (&mac);
4933       /* send it... */
4934       S;
4935     }
4936
4937   if (count > 1)
4938     {
4939       vl_api_control_ping_t *mp;
4940       f64 after;
4941
4942       /* Shut off async mode */
4943       vam->async_mode = 0;
4944
4945       M (CONTROL_PING, control_ping);
4946       S;
4947
4948       timeout = vat_time_now (vam) + 1.0;
4949       while (vat_time_now (vam) < timeout)
4950         if (vam->result_ready == 1)
4951           goto out;
4952       vam->retval = -99;
4953
4954     out:
4955       if (vam->retval == -99)
4956         errmsg ("timeout\n");
4957
4958       if (vam->async_errors > 0)
4959         {
4960           errmsg ("%d asynchronous errors\n", vam->async_errors);
4961           vam->retval = -98;
4962         }
4963       vam->async_errors = 0;
4964       after = vat_time_now (vam);
4965
4966       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4967                count, after - before, count / (after - before));
4968     }
4969   else
4970     {
4971       /* Wait for a reply... */
4972       W;
4973     }
4974   /* Return the good/bad news */
4975   return (vam->retval);
4976 }
4977
4978 static int
4979 api_l2_flags (vat_main_t * vam)
4980 {
4981   unformat_input_t *i = vam->input;
4982   vl_api_l2_flags_t *mp;
4983   f64 timeout;
4984   u32 sw_if_index;
4985   u32 feature_bitmap = 0;
4986   u8 sw_if_index_set = 0;
4987
4988   /* Parse args required to build the message */
4989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4990     {
4991       if (unformat (i, "sw_if_index %d", &sw_if_index))
4992         sw_if_index_set = 1;
4993       else if (unformat (i, "sw_if"))
4994         {
4995           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4996             {
4997               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4998                 sw_if_index_set = 1;
4999             }
5000           else
5001             break;
5002         }
5003       else if (unformat (i, "learn"))
5004         feature_bitmap |= L2INPUT_FEAT_LEARN;
5005       else if (unformat (i, "forward"))
5006         feature_bitmap |= L2INPUT_FEAT_FWD;
5007       else if (unformat (i, "flood"))
5008         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5009       else if (unformat (i, "uu-flood"))
5010         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5011       else
5012         break;
5013     }
5014
5015   if (sw_if_index_set == 0)
5016     {
5017       errmsg ("missing interface name or sw_if_index\n");
5018       return -99;
5019     }
5020
5021   M (L2_FLAGS, l2_flags);
5022
5023   mp->sw_if_index = ntohl (sw_if_index);
5024   mp->feature_bitmap = ntohl (feature_bitmap);
5025
5026   S;
5027   W;
5028   /* NOTREACHED */
5029   return 0;
5030 }
5031
5032 static int
5033 api_bridge_flags (vat_main_t * vam)
5034 {
5035   unformat_input_t *i = vam->input;
5036   vl_api_bridge_flags_t *mp;
5037   f64 timeout;
5038   u32 bd_id;
5039   u8 bd_id_set = 0;
5040   u8 is_set = 1;
5041   u32 flags = 0;
5042
5043   /* Parse args required to build the message */
5044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5045     {
5046       if (unformat (i, "bd_id %d", &bd_id))
5047         bd_id_set = 1;
5048       else if (unformat (i, "learn"))
5049         flags |= L2_LEARN;
5050       else if (unformat (i, "forward"))
5051         flags |= L2_FWD;
5052       else if (unformat (i, "flood"))
5053         flags |= L2_FLOOD;
5054       else if (unformat (i, "uu-flood"))
5055         flags |= L2_UU_FLOOD;
5056       else if (unformat (i, "arp-term"))
5057         flags |= L2_ARP_TERM;
5058       else if (unformat (i, "off"))
5059         is_set = 0;
5060       else if (unformat (i, "disable"))
5061         is_set = 0;
5062       else
5063         break;
5064     }
5065
5066   if (bd_id_set == 0)
5067     {
5068       errmsg ("missing bridge domain\n");
5069       return -99;
5070     }
5071
5072   M (BRIDGE_FLAGS, bridge_flags);
5073
5074   mp->bd_id = ntohl (bd_id);
5075   mp->feature_bitmap = ntohl (flags);
5076   mp->is_set = is_set;
5077
5078   S;
5079   W;
5080   /* NOTREACHED */
5081   return 0;
5082 }
5083
5084 static int
5085 api_bd_ip_mac_add_del (vat_main_t * vam)
5086 {
5087   unformat_input_t *i = vam->input;
5088   vl_api_bd_ip_mac_add_del_t *mp;
5089   f64 timeout;
5090   u32 bd_id;
5091   u8 is_ipv6 = 0;
5092   u8 is_add = 1;
5093   u8 bd_id_set = 0;
5094   u8 ip_set = 0;
5095   u8 mac_set = 0;
5096   ip4_address_t v4addr;
5097   ip6_address_t v6addr;
5098   u8 macaddr[6];
5099
5100
5101   /* Parse args required to build the message */
5102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5103     {
5104       if (unformat (i, "bd_id %d", &bd_id))
5105         {
5106           bd_id_set++;
5107         }
5108       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5109         {
5110           ip_set++;
5111         }
5112       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5113         {
5114           ip_set++;
5115           is_ipv6++;
5116         }
5117       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5118         {
5119           mac_set++;
5120         }
5121       else if (unformat (i, "del"))
5122         is_add = 0;
5123       else
5124         break;
5125     }
5126
5127   if (bd_id_set == 0)
5128     {
5129       errmsg ("missing bridge domain\n");
5130       return -99;
5131     }
5132   else if (ip_set == 0)
5133     {
5134       errmsg ("missing IP address\n");
5135       return -99;
5136     }
5137   else if (mac_set == 0)
5138     {
5139       errmsg ("missing MAC address\n");
5140       return -99;
5141     }
5142
5143   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5144
5145   mp->bd_id = ntohl (bd_id);
5146   mp->is_ipv6 = is_ipv6;
5147   mp->is_add = is_add;
5148   if (is_ipv6)
5149     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5150   else
5151     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5152   clib_memcpy (mp->mac_address, macaddr, 6);
5153   S;
5154   W;
5155   /* NOTREACHED */
5156   return 0;
5157 }
5158
5159 static int
5160 api_tap_connect (vat_main_t * vam)
5161 {
5162   unformat_input_t *i = vam->input;
5163   vl_api_tap_connect_t *mp;
5164   f64 timeout;
5165   u8 mac_address[6];
5166   u8 random_mac = 1;
5167   u8 name_set = 0;
5168   u8 *tap_name;
5169
5170   memset (mac_address, 0, sizeof (mac_address));
5171
5172   /* Parse args required to build the message */
5173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5174     {
5175       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5176         {
5177           random_mac = 0;
5178         }
5179       else if (unformat (i, "random-mac"))
5180         random_mac = 1;
5181       else if (unformat (i, "tapname %s", &tap_name))
5182         name_set = 1;
5183       else
5184         break;
5185     }
5186
5187   if (name_set == 0)
5188     {
5189       errmsg ("missing tap name\n");
5190       return -99;
5191     }
5192   if (vec_len (tap_name) > 63)
5193     {
5194       errmsg ("tap name too long\n");
5195     }
5196   vec_add1 (tap_name, 0);
5197
5198   /* Construct the API message */
5199   M (TAP_CONNECT, tap_connect);
5200
5201   mp->use_random_mac = random_mac;
5202   clib_memcpy (mp->mac_address, mac_address, 6);
5203   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5204   vec_free (tap_name);
5205
5206   /* send it... */
5207   S;
5208
5209   /* Wait for a reply... */
5210   W;
5211 }
5212
5213 static int
5214 api_tap_modify (vat_main_t * vam)
5215 {
5216   unformat_input_t *i = vam->input;
5217   vl_api_tap_modify_t *mp;
5218   f64 timeout;
5219   u8 mac_address[6];
5220   u8 random_mac = 1;
5221   u8 name_set = 0;
5222   u8 *tap_name;
5223   u32 sw_if_index = ~0;
5224   u8 sw_if_index_set = 0;
5225
5226   memset (mac_address, 0, sizeof (mac_address));
5227
5228   /* Parse args required to build the message */
5229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5230     {
5231       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5232         sw_if_index_set = 1;
5233       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5234         sw_if_index_set = 1;
5235       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5236         {
5237           random_mac = 0;
5238         }
5239       else if (unformat (i, "random-mac"))
5240         random_mac = 1;
5241       else if (unformat (i, "tapname %s", &tap_name))
5242         name_set = 1;
5243       else
5244         break;
5245     }
5246
5247   if (sw_if_index_set == 0)
5248     {
5249       errmsg ("missing vpp interface name");
5250       return -99;
5251     }
5252   if (name_set == 0)
5253     {
5254       errmsg ("missing tap name\n");
5255       return -99;
5256     }
5257   if (vec_len (tap_name) > 63)
5258     {
5259       errmsg ("tap name too long\n");
5260     }
5261   vec_add1 (tap_name, 0);
5262
5263   /* Construct the API message */
5264   M (TAP_MODIFY, tap_modify);
5265
5266   mp->use_random_mac = random_mac;
5267   mp->sw_if_index = ntohl (sw_if_index);
5268   clib_memcpy (mp->mac_address, mac_address, 6);
5269   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5270   vec_free (tap_name);
5271
5272   /* send it... */
5273   S;
5274
5275   /* Wait for a reply... */
5276   W;
5277 }
5278
5279 static int
5280 api_tap_delete (vat_main_t * vam)
5281 {
5282   unformat_input_t *i = vam->input;
5283   vl_api_tap_delete_t *mp;
5284   f64 timeout;
5285   u32 sw_if_index = ~0;
5286   u8 sw_if_index_set = 0;
5287
5288   /* Parse args required to build the message */
5289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5290     {
5291       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5292         sw_if_index_set = 1;
5293       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5294         sw_if_index_set = 1;
5295       else
5296         break;
5297     }
5298
5299   if (sw_if_index_set == 0)
5300     {
5301       errmsg ("missing vpp interface name");
5302       return -99;
5303     }
5304
5305   /* Construct the API message */
5306   M (TAP_DELETE, tap_delete);
5307
5308   mp->sw_if_index = ntohl (sw_if_index);
5309
5310   /* send it... */
5311   S;
5312
5313   /* Wait for a reply... */
5314   W;
5315 }
5316
5317 static int
5318 api_ip_add_del_route (vat_main_t * vam)
5319 {
5320   unformat_input_t *i = vam->input;
5321   vl_api_ip_add_del_route_t *mp;
5322   f64 timeout;
5323   u32 sw_if_index = ~0, vrf_id = 0;
5324   u8 sw_if_index_set = 0;
5325   u8 is_ipv6 = 0;
5326   u8 is_local = 0, is_drop = 0;
5327   u8 create_vrf_if_needed = 0;
5328   u8 is_add = 1;
5329   u8 next_hop_weight = 1;
5330   u8 not_last = 0;
5331   u8 is_multipath = 0;
5332   u8 address_set = 0;
5333   u8 address_length_set = 0;
5334   u32 lookup_in_vrf = 0;
5335   u32 resolve_attempts = 0;
5336   u32 dst_address_length = 0;
5337   u8 next_hop_set = 0;
5338   ip4_address_t v4_dst_address, v4_next_hop_address;
5339   ip6_address_t v6_dst_address, v6_next_hop_address;
5340   int count = 1;
5341   int j;
5342   f64 before = 0;
5343   u32 random_add_del = 0;
5344   u32 *random_vector = 0;
5345   uword *random_hash;
5346   u32 random_seed = 0xdeaddabe;
5347   u32 classify_table_index = ~0;
5348   u8 is_classify = 0;
5349   u8 resolve_host, resolve_attached;
5350
5351   /* Parse args required to build the message */
5352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5353     {
5354       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5355         sw_if_index_set = 1;
5356       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5357         sw_if_index_set = 1;
5358       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5359         {
5360           address_set = 1;
5361           is_ipv6 = 0;
5362         }
5363       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5364         {
5365           address_set = 1;
5366           is_ipv6 = 1;
5367         }
5368       else if (unformat (i, "/%d", &dst_address_length))
5369         {
5370           address_length_set = 1;
5371         }
5372
5373       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5374                                          &v4_next_hop_address))
5375         {
5376           next_hop_set = 1;
5377         }
5378       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5379                                          &v6_next_hop_address))
5380         {
5381           next_hop_set = 1;
5382         }
5383       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5384         ;
5385       else if (unformat (i, "weight %d", &next_hop_weight))
5386         ;
5387       else if (unformat (i, "drop"))
5388         {
5389           is_drop = 1;
5390         }
5391       else if (unformat (i, "local"))
5392         {
5393           is_local = 1;
5394         }
5395       else if (unformat (i, "classify %d", &classify_table_index))
5396         {
5397           is_classify = 1;
5398         }
5399       else if (unformat (i, "del"))
5400         is_add = 0;
5401       else if (unformat (i, "add"))
5402         is_add = 1;
5403       else if (unformat (i, "not-last"))
5404         not_last = 1;
5405       else if (unformat (i, "resolve-via-host"))
5406         resolve_host = 1;
5407       else if (unformat (i, "resolve-via-attached"))
5408         resolve_attached = 1;
5409       else if (unformat (i, "multipath"))
5410         is_multipath = 1;
5411       else if (unformat (i, "vrf %d", &vrf_id))
5412         ;
5413       else if (unformat (i, "create-vrf"))
5414         create_vrf_if_needed = 1;
5415       else if (unformat (i, "count %d", &count))
5416         ;
5417       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5418         ;
5419       else if (unformat (i, "random"))
5420         random_add_del = 1;
5421       else if (unformat (i, "seed %d", &random_seed))
5422         ;
5423       else
5424         {
5425           clib_warning ("parse error '%U'", format_unformat_error, i);
5426           return -99;
5427         }
5428     }
5429
5430   if (resolve_attempts > 0 && sw_if_index_set == 0)
5431     {
5432       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5433       return -99;
5434     }
5435
5436   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5437     {
5438       errmsg ("next hop / local / drop / classify not set\n");
5439       return -99;
5440     }
5441
5442   if (address_set == 0)
5443     {
5444       errmsg ("missing addresses\n");
5445       return -99;
5446     }
5447
5448   if (address_length_set == 0)
5449     {
5450       errmsg ("missing address length\n");
5451       return -99;
5452     }
5453
5454   /* Generate a pile of unique, random routes */
5455   if (random_add_del)
5456     {
5457       u32 this_random_address;
5458       random_hash = hash_create (count, sizeof (uword));
5459
5460       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5461       for (j = 0; j <= count; j++)
5462         {
5463           do
5464             {
5465               this_random_address = random_u32 (&random_seed);
5466               this_random_address =
5467                 clib_host_to_net_u32 (this_random_address);
5468             }
5469           while (hash_get (random_hash, this_random_address));
5470           vec_add1 (random_vector, this_random_address);
5471           hash_set (random_hash, this_random_address, 1);
5472         }
5473       hash_free (random_hash);
5474       v4_dst_address.as_u32 = random_vector[0];
5475     }
5476
5477   if (count > 1)
5478     {
5479       /* Turn on async mode */
5480       vam->async_mode = 1;
5481       vam->async_errors = 0;
5482       before = vat_time_now (vam);
5483     }
5484
5485   for (j = 0; j < count; j++)
5486     {
5487       /* Construct the API message */
5488       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5489
5490       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5491       mp->vrf_id = ntohl (vrf_id);
5492       if (resolve_attempts > 0)
5493         {
5494           mp->resolve_attempts = ntohl (resolve_attempts);
5495           mp->resolve_if_needed = 1;
5496         }
5497       mp->create_vrf_if_needed = create_vrf_if_needed;
5498
5499       mp->is_add = is_add;
5500       mp->is_drop = is_drop;
5501       mp->is_ipv6 = is_ipv6;
5502       mp->is_local = is_local;
5503       mp->is_classify = is_classify;
5504       mp->is_multipath = is_multipath;
5505       mp->is_resolve_host = resolve_host;
5506       mp->is_resolve_attached = resolve_attached;
5507       mp->not_last = not_last;
5508       mp->next_hop_weight = next_hop_weight;
5509       mp->dst_address_length = dst_address_length;
5510       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5511       mp->classify_table_index = ntohl (classify_table_index);
5512
5513       if (is_ipv6)
5514         {
5515           clib_memcpy (mp->dst_address, &v6_dst_address,
5516                        sizeof (v6_dst_address));
5517           if (next_hop_set)
5518             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5519                          sizeof (v6_next_hop_address));
5520           increment_v6_address (&v6_dst_address);
5521         }
5522       else
5523         {
5524           clib_memcpy (mp->dst_address, &v4_dst_address,
5525                        sizeof (v4_dst_address));
5526           if (next_hop_set)
5527             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5528                          sizeof (v4_next_hop_address));
5529           if (random_add_del)
5530             v4_dst_address.as_u32 = random_vector[j + 1];
5531           else
5532             increment_v4_address (&v4_dst_address);
5533         }
5534       /* send it... */
5535       S;
5536     }
5537
5538   /* When testing multiple add/del ops, use a control-ping to sync */
5539   if (count > 1)
5540     {
5541       vl_api_control_ping_t *mp;
5542       f64 after;
5543
5544       /* Shut off async mode */
5545       vam->async_mode = 0;
5546
5547       M (CONTROL_PING, control_ping);
5548       S;
5549
5550       timeout = vat_time_now (vam) + 1.0;
5551       while (vat_time_now (vam) < timeout)
5552         if (vam->result_ready == 1)
5553           goto out;
5554       vam->retval = -99;
5555
5556     out:
5557       if (vam->retval == -99)
5558         errmsg ("timeout\n");
5559
5560       if (vam->async_errors > 0)
5561         {
5562           errmsg ("%d asynchronous errors\n", vam->async_errors);
5563           vam->retval = -98;
5564         }
5565       vam->async_errors = 0;
5566       after = vat_time_now (vam);
5567
5568       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5569                count, after - before, count / (after - before));
5570     }
5571   else
5572     {
5573       /* Wait for a reply... */
5574       W;
5575     }
5576
5577   /* Return the good/bad news */
5578   return (vam->retval);
5579 }
5580
5581 static int
5582 api_proxy_arp_add_del (vat_main_t * vam)
5583 {
5584   unformat_input_t *i = vam->input;
5585   vl_api_proxy_arp_add_del_t *mp;
5586   f64 timeout;
5587   u32 vrf_id = 0;
5588   u8 is_add = 1;
5589   ip4_address_t lo, hi;
5590   u8 range_set = 0;
5591
5592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5593     {
5594       if (unformat (i, "vrf %d", &vrf_id))
5595         ;
5596       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5597                          unformat_ip4_address, &hi))
5598         range_set = 1;
5599       else if (unformat (i, "del"))
5600         is_add = 0;
5601       else
5602         {
5603           clib_warning ("parse error '%U'", format_unformat_error, i);
5604           return -99;
5605         }
5606     }
5607
5608   if (range_set == 0)
5609     {
5610       errmsg ("address range not set\n");
5611       return -99;
5612     }
5613
5614   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5615
5616   mp->vrf_id = ntohl (vrf_id);
5617   mp->is_add = is_add;
5618   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5619   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5620
5621   S;
5622   W;
5623   /* NOTREACHED */
5624   return 0;
5625 }
5626
5627 static int
5628 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5629 {
5630   unformat_input_t *i = vam->input;
5631   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5632   f64 timeout;
5633   u32 sw_if_index;
5634   u8 enable = 1;
5635   u8 sw_if_index_set = 0;
5636
5637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5638     {
5639       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5640         sw_if_index_set = 1;
5641       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5642         sw_if_index_set = 1;
5643       else if (unformat (i, "enable"))
5644         enable = 1;
5645       else if (unformat (i, "disable"))
5646         enable = 0;
5647       else
5648         {
5649           clib_warning ("parse error '%U'", format_unformat_error, i);
5650           return -99;
5651         }
5652     }
5653
5654   if (sw_if_index_set == 0)
5655     {
5656       errmsg ("missing interface name or sw_if_index\n");
5657       return -99;
5658     }
5659
5660   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5661
5662   mp->sw_if_index = ntohl (sw_if_index);
5663   mp->enable_disable = enable;
5664
5665   S;
5666   W;
5667   /* NOTREACHED */
5668   return 0;
5669 }
5670
5671 static int
5672 api_mpls_add_del_decap (vat_main_t * vam)
5673 {
5674   unformat_input_t *i = vam->input;
5675   vl_api_mpls_add_del_decap_t *mp;
5676   f64 timeout;
5677   u32 rx_vrf_id = 0;
5678   u32 tx_vrf_id = 0;
5679   u32 label = 0;
5680   u8 is_add = 1;
5681   u8 s_bit = 1;
5682   u32 next_index = 1;
5683
5684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5685     {
5686       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5687         ;
5688       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5689         ;
5690       else if (unformat (i, "label %d", &label))
5691         ;
5692       else if (unformat (i, "next-index %d", &next_index))
5693         ;
5694       else if (unformat (i, "del"))
5695         is_add = 0;
5696       else if (unformat (i, "s-bit-clear"))
5697         s_bit = 0;
5698       else
5699         {
5700           clib_warning ("parse error '%U'", format_unformat_error, i);
5701           return -99;
5702         }
5703     }
5704
5705   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5706
5707   mp->rx_vrf_id = ntohl (rx_vrf_id);
5708   mp->tx_vrf_id = ntohl (tx_vrf_id);
5709   mp->label = ntohl (label);
5710   mp->next_index = ntohl (next_index);
5711   mp->s_bit = s_bit;
5712   mp->is_add = is_add;
5713
5714   S;
5715   W;
5716   /* NOTREACHED */
5717   return 0;
5718 }
5719
5720 static int
5721 api_mpls_add_del_encap (vat_main_t * vam)
5722 {
5723   unformat_input_t *i = vam->input;
5724   vl_api_mpls_add_del_encap_t *mp;
5725   f64 timeout;
5726   u32 vrf_id = 0;
5727   u32 *labels = 0;
5728   u32 label;
5729   ip4_address_t dst_address;
5730   u8 is_add = 1;
5731
5732   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5733     {
5734       if (unformat (i, "vrf %d", &vrf_id))
5735         ;
5736       else if (unformat (i, "label %d", &label))
5737         vec_add1 (labels, ntohl (label));
5738       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5739         ;
5740       else if (unformat (i, "del"))
5741         is_add = 0;
5742       else
5743         {
5744           clib_warning ("parse error '%U'", format_unformat_error, i);
5745           return -99;
5746         }
5747     }
5748
5749   if (vec_len (labels) == 0)
5750     {
5751       errmsg ("missing encap label stack\n");
5752       return -99;
5753     }
5754
5755   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
5756       sizeof (u32) * vec_len (labels));
5757
5758   mp->vrf_id = ntohl (vrf_id);
5759   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5760   mp->is_add = is_add;
5761   mp->nlabels = vec_len (labels);
5762   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
5763
5764   vec_free (labels);
5765
5766   S;
5767   W;
5768   /* NOTREACHED */
5769   return 0;
5770 }
5771
5772 static int
5773 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
5774 {
5775   unformat_input_t *i = vam->input;
5776   vl_api_mpls_gre_add_del_tunnel_t *mp;
5777   f64 timeout;
5778   u32 inner_vrf_id = 0;
5779   u32 outer_vrf_id = 0;
5780   ip4_address_t src_address;
5781   ip4_address_t dst_address;
5782   ip4_address_t intfc_address;
5783   u32 tmp;
5784   u8 intfc_address_length = 0;
5785   u8 is_add = 1;
5786   u8 l2_only = 0;
5787
5788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5789     {
5790       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5791         ;
5792       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5793         ;
5794       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
5795         ;
5796       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5797         ;
5798       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5799                          &intfc_address, &tmp))
5800         intfc_address_length = tmp;
5801       else if (unformat (i, "l2-only"))
5802         l2_only = 1;
5803       else if (unformat (i, "del"))
5804         is_add = 0;
5805       else
5806         {
5807           clib_warning ("parse error '%U'", format_unformat_error, i);
5808           return -99;
5809         }
5810     }
5811
5812   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
5813
5814   mp->inner_vrf_id = ntohl (inner_vrf_id);
5815   mp->outer_vrf_id = ntohl (outer_vrf_id);
5816   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
5817   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5818   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
5819   mp->intfc_address_length = intfc_address_length;
5820   mp->l2_only = l2_only;
5821   mp->is_add = is_add;
5822
5823   S;
5824   W;
5825   /* NOTREACHED */
5826   return 0;
5827 }
5828
5829 static int
5830 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
5831 {
5832   unformat_input_t *i = vam->input;
5833   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
5834   f64 timeout;
5835   u32 inner_vrf_id = 0;
5836   ip4_address_t intfc_address;
5837   u8 dst_mac_address[6];
5838   int dst_set = 1;
5839   u32 tmp;
5840   u8 intfc_address_length = 0;
5841   u8 is_add = 1;
5842   u8 l2_only = 0;
5843   u32 tx_sw_if_index;
5844   int tx_sw_if_index_set = 0;
5845
5846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5847     {
5848       if (unformat (i, "vrf %d", &inner_vrf_id))
5849         ;
5850       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5851                          &intfc_address, &tmp))
5852         intfc_address_length = tmp;
5853       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
5854         tx_sw_if_index_set = 1;
5855       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5856         tx_sw_if_index_set = 1;
5857       else if (unformat (i, "dst %U", unformat_ethernet_address,
5858                          dst_mac_address))
5859         dst_set = 1;
5860       else if (unformat (i, "l2-only"))
5861         l2_only = 1;
5862       else if (unformat (i, "del"))
5863         is_add = 0;
5864       else
5865         {
5866           clib_warning ("parse error '%U'", format_unformat_error, i);
5867           return -99;
5868         }
5869     }
5870
5871   if (!dst_set)
5872     {
5873       errmsg ("dst (mac address) not set\n");
5874       return -99;
5875     }
5876   if (!tx_sw_if_index_set)
5877     {
5878       errmsg ("tx-intfc not set\n");
5879       return -99;
5880     }
5881
5882   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
5883
5884   mp->vrf_id = ntohl (inner_vrf_id);
5885   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
5886   mp->adj_address_length = intfc_address_length;
5887   clib_memcpy (mp->dst_mac_address, dst_mac_address,
5888                sizeof (dst_mac_address));
5889   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5890   mp->l2_only = l2_only;
5891   mp->is_add = is_add;
5892
5893   S;
5894   W;
5895   /* NOTREACHED */
5896   return 0;
5897 }
5898
5899 static int
5900 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
5901 {
5902   unformat_input_t *i = vam->input;
5903   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
5904   f64 timeout;
5905   u32 inner_vrf_id = 0;
5906   u32 outer_vrf_id = 0;
5907   ip4_address_t adj_address;
5908   int adj_address_set = 0;
5909   ip4_address_t next_hop_address;
5910   int next_hop_address_set = 0;
5911   u32 tmp;
5912   u8 adj_address_length = 0;
5913   u8 l2_only = 0;
5914   u8 is_add = 1;
5915   u32 resolve_attempts = 5;
5916   u8 resolve_if_needed = 1;
5917
5918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5919     {
5920       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5921         ;
5922       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5923         ;
5924       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5925                          &adj_address, &tmp))
5926         {
5927           adj_address_length = tmp;
5928           adj_address_set = 1;
5929         }
5930       else if (unformat (i, "next-hop %U", unformat_ip4_address,
5931                          &next_hop_address))
5932         next_hop_address_set = 1;
5933       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5934         ;
5935       else if (unformat (i, "resolve-if-needed %d", &tmp))
5936         resolve_if_needed = tmp;
5937       else if (unformat (i, "l2-only"))
5938         l2_only = 1;
5939       else if (unformat (i, "del"))
5940         is_add = 0;
5941       else
5942         {
5943           clib_warning ("parse error '%U'", format_unformat_error, i);
5944           return -99;
5945         }
5946     }
5947
5948   if (!adj_address_set)
5949     {
5950       errmsg ("adjacency address/mask not set\n");
5951       return -99;
5952     }
5953   if (!next_hop_address_set)
5954     {
5955       errmsg ("ip4 next hop address (in outer fib) not set\n");
5956       return -99;
5957     }
5958
5959   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
5960
5961   mp->inner_vrf_id = ntohl (inner_vrf_id);
5962   mp->outer_vrf_id = ntohl (outer_vrf_id);
5963   mp->resolve_attempts = ntohl (resolve_attempts);
5964   mp->resolve_if_needed = resolve_if_needed;
5965   mp->is_add = is_add;
5966   mp->l2_only = l2_only;
5967   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
5968   mp->adj_address_length = adj_address_length;
5969   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
5970                sizeof (next_hop_address));
5971
5972   S;
5973   W;
5974   /* NOTREACHED */
5975   return 0;
5976 }
5977
5978 static int
5979 api_sw_interface_set_unnumbered (vat_main_t * vam)
5980 {
5981   unformat_input_t *i = vam->input;
5982   vl_api_sw_interface_set_unnumbered_t *mp;
5983   f64 timeout;
5984   u32 sw_if_index;
5985   u32 unnum_sw_index = ~0;
5986   u8 is_add = 1;
5987   u8 sw_if_index_set = 0;
5988
5989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5990     {
5991       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5992         sw_if_index_set = 1;
5993       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5994         sw_if_index_set = 1;
5995       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
5996         ;
5997       else if (unformat (i, "del"))
5998         is_add = 0;
5999       else
6000         {
6001           clib_warning ("parse error '%U'", format_unformat_error, i);
6002           return -99;
6003         }
6004     }
6005
6006   if (sw_if_index_set == 0)
6007     {
6008       errmsg ("missing interface name or sw_if_index\n");
6009       return -99;
6010     }
6011
6012   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6013
6014   mp->sw_if_index = ntohl (sw_if_index);
6015   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6016   mp->is_add = is_add;
6017
6018   S;
6019   W;
6020   /* NOTREACHED */
6021   return 0;
6022 }
6023
6024 static int
6025 api_ip_neighbor_add_del (vat_main_t * vam)
6026 {
6027   unformat_input_t *i = vam->input;
6028   vl_api_ip_neighbor_add_del_t *mp;
6029   f64 timeout;
6030   u32 sw_if_index;
6031   u8 sw_if_index_set = 0;
6032   u32 vrf_id = 0;
6033   u8 is_add = 1;
6034   u8 is_static = 0;
6035   u8 mac_address[6];
6036   u8 mac_set = 0;
6037   u8 v4_address_set = 0;
6038   u8 v6_address_set = 0;
6039   ip4_address_t v4address;
6040   ip6_address_t v6address;
6041
6042   memset (mac_address, 0, sizeof (mac_address));
6043
6044   /* Parse args required to build the message */
6045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6046     {
6047       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6048         {
6049           mac_set = 1;
6050         }
6051       else if (unformat (i, "del"))
6052         is_add = 0;
6053       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6054         sw_if_index_set = 1;
6055       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6056         sw_if_index_set = 1;
6057       else if (unformat (i, "is_static"))
6058         is_static = 1;
6059       else if (unformat (i, "vrf %d", &vrf_id))
6060         ;
6061       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6062         v4_address_set = 1;
6063       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6064         v6_address_set = 1;
6065       else
6066         {
6067           clib_warning ("parse error '%U'", format_unformat_error, i);
6068           return -99;
6069         }
6070     }
6071
6072   if (sw_if_index_set == 0)
6073     {
6074       errmsg ("missing interface name or sw_if_index\n");
6075       return -99;
6076     }
6077   if (v4_address_set && v6_address_set)
6078     {
6079       errmsg ("both v4 and v6 addresses set\n");
6080       return -99;
6081     }
6082   if (!v4_address_set && !v6_address_set)
6083     {
6084       errmsg ("no address set\n");
6085       return -99;
6086     }
6087
6088   /* Construct the API message */
6089   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6090
6091   mp->sw_if_index = ntohl (sw_if_index);
6092   mp->is_add = is_add;
6093   mp->vrf_id = ntohl (vrf_id);
6094   mp->is_static = is_static;
6095   if (mac_set)
6096     clib_memcpy (mp->mac_address, mac_address, 6);
6097   if (v6_address_set)
6098     {
6099       mp->is_ipv6 = 1;
6100       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6101     }
6102   else
6103     {
6104       /* mp->is_ipv6 = 0; via memset in M macro above */
6105       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6106     }
6107
6108   /* send it... */
6109   S;
6110
6111   /* Wait for a reply, return good/bad news  */
6112   W;
6113
6114   /* NOTREACHED */
6115   return 0;
6116 }
6117
6118 static int
6119 api_reset_vrf (vat_main_t * vam)
6120 {
6121   unformat_input_t *i = vam->input;
6122   vl_api_reset_vrf_t *mp;
6123   f64 timeout;
6124   u32 vrf_id = 0;
6125   u8 is_ipv6 = 0;
6126   u8 vrf_id_set = 0;
6127
6128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6129     {
6130       if (unformat (i, "vrf %d", &vrf_id))
6131         vrf_id_set = 1;
6132       else if (unformat (i, "ipv6"))
6133         is_ipv6 = 1;
6134       else
6135         {
6136           clib_warning ("parse error '%U'", format_unformat_error, i);
6137           return -99;
6138         }
6139     }
6140
6141   if (vrf_id_set == 0)
6142     {
6143       errmsg ("missing vrf id\n");
6144       return -99;
6145     }
6146
6147   M (RESET_VRF, reset_vrf);
6148
6149   mp->vrf_id = ntohl (vrf_id);
6150   mp->is_ipv6 = is_ipv6;
6151
6152   S;
6153   W;
6154   /* NOTREACHED */
6155   return 0;
6156 }
6157
6158 static int
6159 api_create_vlan_subif (vat_main_t * vam)
6160 {
6161   unformat_input_t *i = vam->input;
6162   vl_api_create_vlan_subif_t *mp;
6163   f64 timeout;
6164   u32 sw_if_index;
6165   u8 sw_if_index_set = 0;
6166   u32 vlan_id;
6167   u8 vlan_id_set = 0;
6168
6169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6170     {
6171       if (unformat (i, "sw_if_index %d", &sw_if_index))
6172         sw_if_index_set = 1;
6173       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6174         sw_if_index_set = 1;
6175       else if (unformat (i, "vlan %d", &vlan_id))
6176         vlan_id_set = 1;
6177       else
6178         {
6179           clib_warning ("parse error '%U'", format_unformat_error, i);
6180           return -99;
6181         }
6182     }
6183
6184   if (sw_if_index_set == 0)
6185     {
6186       errmsg ("missing interface name or sw_if_index\n");
6187       return -99;
6188     }
6189
6190   if (vlan_id_set == 0)
6191     {
6192       errmsg ("missing vlan_id\n");
6193       return -99;
6194     }
6195   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6196
6197   mp->sw_if_index = ntohl (sw_if_index);
6198   mp->vlan_id = ntohl (vlan_id);
6199
6200   S;
6201   W;
6202   /* NOTREACHED */
6203   return 0;
6204 }
6205
6206 #define foreach_create_subif_bit                \
6207 _(no_tags)                                      \
6208 _(one_tag)                                      \
6209 _(two_tags)                                     \
6210 _(dot1ad)                                       \
6211 _(exact_match)                                  \
6212 _(default_sub)                                  \
6213 _(outer_vlan_id_any)                            \
6214 _(inner_vlan_id_any)
6215
6216 static int
6217 api_create_subif (vat_main_t * vam)
6218 {
6219   unformat_input_t *i = vam->input;
6220   vl_api_create_subif_t *mp;
6221   f64 timeout;
6222   u32 sw_if_index;
6223   u8 sw_if_index_set = 0;
6224   u32 sub_id;
6225   u8 sub_id_set = 0;
6226   u32 no_tags = 0;
6227   u32 one_tag = 0;
6228   u32 two_tags = 0;
6229   u32 dot1ad = 0;
6230   u32 exact_match = 0;
6231   u32 default_sub = 0;
6232   u32 outer_vlan_id_any = 0;
6233   u32 inner_vlan_id_any = 0;
6234   u32 tmp;
6235   u16 outer_vlan_id = 0;
6236   u16 inner_vlan_id = 0;
6237
6238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6239     {
6240       if (unformat (i, "sw_if_index %d", &sw_if_index))
6241         sw_if_index_set = 1;
6242       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6243         sw_if_index_set = 1;
6244       else if (unformat (i, "sub_id %d", &sub_id))
6245         sub_id_set = 1;
6246       else if (unformat (i, "outer_vlan_id %d", &tmp))
6247         outer_vlan_id = tmp;
6248       else if (unformat (i, "inner_vlan_id %d", &tmp))
6249         inner_vlan_id = tmp;
6250
6251 #define _(a) else if (unformat (i, #a)) a = 1 ;
6252       foreach_create_subif_bit
6253 #undef _
6254         else
6255         {
6256           clib_warning ("parse error '%U'", format_unformat_error, i);
6257           return -99;
6258         }
6259     }
6260
6261   if (sw_if_index_set == 0)
6262     {
6263       errmsg ("missing interface name or sw_if_index\n");
6264       return -99;
6265     }
6266
6267   if (sub_id_set == 0)
6268     {
6269       errmsg ("missing sub_id\n");
6270       return -99;
6271     }
6272   M (CREATE_SUBIF, create_subif);
6273
6274   mp->sw_if_index = ntohl (sw_if_index);
6275   mp->sub_id = ntohl (sub_id);
6276
6277 #define _(a) mp->a = a;
6278   foreach_create_subif_bit;
6279 #undef _
6280
6281   mp->outer_vlan_id = ntohs (outer_vlan_id);
6282   mp->inner_vlan_id = ntohs (inner_vlan_id);
6283
6284   S;
6285   W;
6286   /* NOTREACHED */
6287   return 0;
6288 }
6289
6290 static int
6291 api_oam_add_del (vat_main_t * vam)
6292 {
6293   unformat_input_t *i = vam->input;
6294   vl_api_oam_add_del_t *mp;
6295   f64 timeout;
6296   u32 vrf_id = 0;
6297   u8 is_add = 1;
6298   ip4_address_t src, dst;
6299   u8 src_set = 0;
6300   u8 dst_set = 0;
6301
6302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6303     {
6304       if (unformat (i, "vrf %d", &vrf_id))
6305         ;
6306       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6307         src_set = 1;
6308       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6309         dst_set = 1;
6310       else if (unformat (i, "del"))
6311         is_add = 0;
6312       else
6313         {
6314           clib_warning ("parse error '%U'", format_unformat_error, i);
6315           return -99;
6316         }
6317     }
6318
6319   if (src_set == 0)
6320     {
6321       errmsg ("missing src addr\n");
6322       return -99;
6323     }
6324
6325   if (dst_set == 0)
6326     {
6327       errmsg ("missing dst addr\n");
6328       return -99;
6329     }
6330
6331   M (OAM_ADD_DEL, oam_add_del);
6332
6333   mp->vrf_id = ntohl (vrf_id);
6334   mp->is_add = is_add;
6335   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6336   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6337
6338   S;
6339   W;
6340   /* NOTREACHED */
6341   return 0;
6342 }
6343
6344 static int
6345 api_reset_fib (vat_main_t * vam)
6346 {
6347   unformat_input_t *i = vam->input;
6348   vl_api_reset_fib_t *mp;
6349   f64 timeout;
6350   u32 vrf_id = 0;
6351   u8 is_ipv6 = 0;
6352   u8 vrf_id_set = 0;
6353
6354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6355     {
6356       if (unformat (i, "vrf %d", &vrf_id))
6357         vrf_id_set = 1;
6358       else if (unformat (i, "ipv6"))
6359         is_ipv6 = 1;
6360       else
6361         {
6362           clib_warning ("parse error '%U'", format_unformat_error, i);
6363           return -99;
6364         }
6365     }
6366
6367   if (vrf_id_set == 0)
6368     {
6369       errmsg ("missing vrf id\n");
6370       return -99;
6371     }
6372
6373   M (RESET_FIB, reset_fib);
6374
6375   mp->vrf_id = ntohl (vrf_id);
6376   mp->is_ipv6 = is_ipv6;
6377
6378   S;
6379   W;
6380   /* NOTREACHED */
6381   return 0;
6382 }
6383
6384 static int
6385 api_dhcp_proxy_config (vat_main_t * vam)
6386 {
6387   unformat_input_t *i = vam->input;
6388   vl_api_dhcp_proxy_config_t *mp;
6389   f64 timeout;
6390   u32 vrf_id = 0;
6391   u8 is_add = 1;
6392   u8 insert_cid = 1;
6393   u8 v4_address_set = 0;
6394   u8 v6_address_set = 0;
6395   ip4_address_t v4address;
6396   ip6_address_t v6address;
6397   u8 v4_src_address_set = 0;
6398   u8 v6_src_address_set = 0;
6399   ip4_address_t v4srcaddress;
6400   ip6_address_t v6srcaddress;
6401
6402   /* Parse args required to build the message */
6403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6404     {
6405       if (unformat (i, "del"))
6406         is_add = 0;
6407       else if (unformat (i, "vrf %d", &vrf_id))
6408         ;
6409       else if (unformat (i, "insert-cid %d", &insert_cid))
6410         ;
6411       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6412         v4_address_set = 1;
6413       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6414         v6_address_set = 1;
6415       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6416         v4_src_address_set = 1;
6417       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6418         v6_src_address_set = 1;
6419       else
6420         break;
6421     }
6422
6423   if (v4_address_set && v6_address_set)
6424     {
6425       errmsg ("both v4 and v6 server addresses set\n");
6426       return -99;
6427     }
6428   if (!v4_address_set && !v6_address_set)
6429     {
6430       errmsg ("no server addresses set\n");
6431       return -99;
6432     }
6433
6434   if (v4_src_address_set && v6_src_address_set)
6435     {
6436       errmsg ("both v4 and v6  src addresses set\n");
6437       return -99;
6438     }
6439   if (!v4_src_address_set && !v6_src_address_set)
6440     {
6441       errmsg ("no src addresses set\n");
6442       return -99;
6443     }
6444
6445   if (!(v4_src_address_set && v4_address_set) &&
6446       !(v6_src_address_set && v6_address_set))
6447     {
6448       errmsg ("no matching server and src addresses set\n");
6449       return -99;
6450     }
6451
6452   /* Construct the API message */
6453   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6454
6455   mp->insert_circuit_id = insert_cid;
6456   mp->is_add = is_add;
6457   mp->vrf_id = ntohl (vrf_id);
6458   if (v6_address_set)
6459     {
6460       mp->is_ipv6 = 1;
6461       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6462       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6463     }
6464   else
6465     {
6466       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6467       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6468     }
6469
6470   /* send it... */
6471   S;
6472
6473   /* Wait for a reply, return good/bad news  */
6474   W;
6475   /* NOTREACHED */
6476   return 0;
6477 }
6478
6479 static int
6480 api_dhcp_proxy_config_2 (vat_main_t * vam)
6481 {
6482   unformat_input_t *i = vam->input;
6483   vl_api_dhcp_proxy_config_2_t *mp;
6484   f64 timeout;
6485   u32 rx_vrf_id = 0;
6486   u32 server_vrf_id = 0;
6487   u8 is_add = 1;
6488   u8 insert_cid = 1;
6489   u8 v4_address_set = 0;
6490   u8 v6_address_set = 0;
6491   ip4_address_t v4address;
6492   ip6_address_t v6address;
6493   u8 v4_src_address_set = 0;
6494   u8 v6_src_address_set = 0;
6495   ip4_address_t v4srcaddress;
6496   ip6_address_t v6srcaddress;
6497
6498   /* Parse args required to build the message */
6499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6500     {
6501       if (unformat (i, "del"))
6502         is_add = 0;
6503       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6504         ;
6505       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6506         ;
6507       else if (unformat (i, "insert-cid %d", &insert_cid))
6508         ;
6509       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6510         v4_address_set = 1;
6511       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6512         v6_address_set = 1;
6513       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6514         v4_src_address_set = 1;
6515       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6516         v6_src_address_set = 1;
6517       else
6518         break;
6519     }
6520
6521   if (v4_address_set && v6_address_set)
6522     {
6523       errmsg ("both v4 and v6 server addresses set\n");
6524       return -99;
6525     }
6526   if (!v4_address_set && !v6_address_set)
6527     {
6528       errmsg ("no server addresses set\n");
6529       return -99;
6530     }
6531
6532   if (v4_src_address_set && v6_src_address_set)
6533     {
6534       errmsg ("both v4 and v6  src addresses set\n");
6535       return -99;
6536     }
6537   if (!v4_src_address_set && !v6_src_address_set)
6538     {
6539       errmsg ("no src addresses set\n");
6540       return -99;
6541     }
6542
6543   if (!(v4_src_address_set && v4_address_set) &&
6544       !(v6_src_address_set && v6_address_set))
6545     {
6546       errmsg ("no matching server and src addresses set\n");
6547       return -99;
6548     }
6549
6550   /* Construct the API message */
6551   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6552
6553   mp->insert_circuit_id = insert_cid;
6554   mp->is_add = is_add;
6555   mp->rx_vrf_id = ntohl (rx_vrf_id);
6556   mp->server_vrf_id = ntohl (server_vrf_id);
6557   if (v6_address_set)
6558     {
6559       mp->is_ipv6 = 1;
6560       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6561       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6562     }
6563   else
6564     {
6565       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6566       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6567     }
6568
6569   /* send it... */
6570   S;
6571
6572   /* Wait for a reply, return good/bad news  */
6573   W;
6574   /* NOTREACHED */
6575   return 0;
6576 }
6577
6578 static int
6579 api_dhcp_proxy_set_vss (vat_main_t * vam)
6580 {
6581   unformat_input_t *i = vam->input;
6582   vl_api_dhcp_proxy_set_vss_t *mp;
6583   f64 timeout;
6584   u8 is_ipv6 = 0;
6585   u8 is_add = 1;
6586   u32 tbl_id;
6587   u8 tbl_id_set = 0;
6588   u32 oui;
6589   u8 oui_set = 0;
6590   u32 fib_id;
6591   u8 fib_id_set = 0;
6592
6593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6594     {
6595       if (unformat (i, "tbl_id %d", &tbl_id))
6596         tbl_id_set = 1;
6597       if (unformat (i, "fib_id %d", &fib_id))
6598         fib_id_set = 1;
6599       if (unformat (i, "oui %d", &oui))
6600         oui_set = 1;
6601       else if (unformat (i, "ipv6"))
6602         is_ipv6 = 1;
6603       else if (unformat (i, "del"))
6604         is_add = 0;
6605       else
6606         {
6607           clib_warning ("parse error '%U'", format_unformat_error, i);
6608           return -99;
6609         }
6610     }
6611
6612   if (tbl_id_set == 0)
6613     {
6614       errmsg ("missing tbl id\n");
6615       return -99;
6616     }
6617
6618   if (fib_id_set == 0)
6619     {
6620       errmsg ("missing fib id\n");
6621       return -99;
6622     }
6623   if (oui_set == 0)
6624     {
6625       errmsg ("missing oui\n");
6626       return -99;
6627     }
6628
6629   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6630   mp->tbl_id = ntohl (tbl_id);
6631   mp->fib_id = ntohl (fib_id);
6632   mp->oui = ntohl (oui);
6633   mp->is_ipv6 = is_ipv6;
6634   mp->is_add = is_add;
6635
6636   S;
6637   W;
6638   /* NOTREACHED */
6639   return 0;
6640 }
6641
6642 static int
6643 api_dhcp_client_config (vat_main_t * vam)
6644 {
6645   unformat_input_t *i = vam->input;
6646   vl_api_dhcp_client_config_t *mp;
6647   f64 timeout;
6648   u32 sw_if_index;
6649   u8 sw_if_index_set = 0;
6650   u8 is_add = 1;
6651   u8 *hostname = 0;
6652   u8 disable_event = 0;
6653
6654   /* Parse args required to build the message */
6655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6656     {
6657       if (unformat (i, "del"))
6658         is_add = 0;
6659       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6660         sw_if_index_set = 1;
6661       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6662         sw_if_index_set = 1;
6663       else if (unformat (i, "hostname %s", &hostname))
6664         ;
6665       else if (unformat (i, "disable_event"))
6666         disable_event = 1;
6667       else
6668         break;
6669     }
6670
6671   if (sw_if_index_set == 0)
6672     {
6673       errmsg ("missing interface name or sw_if_index\n");
6674       return -99;
6675     }
6676
6677   if (vec_len (hostname) > 63)
6678     {
6679       errmsg ("hostname too long\n");
6680     }
6681   vec_add1 (hostname, 0);
6682
6683   /* Construct the API message */
6684   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6685
6686   mp->sw_if_index = ntohl (sw_if_index);
6687   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6688   vec_free (hostname);
6689   mp->is_add = is_add;
6690   mp->want_dhcp_event = disable_event ? 0 : 1;
6691   mp->pid = getpid ();
6692
6693   /* send it... */
6694   S;
6695
6696   /* Wait for a reply, return good/bad news  */
6697   W;
6698   /* NOTREACHED */
6699   return 0;
6700 }
6701
6702 static int
6703 api_set_ip_flow_hash (vat_main_t * vam)
6704 {
6705   unformat_input_t *i = vam->input;
6706   vl_api_set_ip_flow_hash_t *mp;
6707   f64 timeout;
6708   u32 vrf_id = 0;
6709   u8 is_ipv6 = 0;
6710   u8 vrf_id_set = 0;
6711   u8 src = 0;
6712   u8 dst = 0;
6713   u8 sport = 0;
6714   u8 dport = 0;
6715   u8 proto = 0;
6716   u8 reverse = 0;
6717
6718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6719     {
6720       if (unformat (i, "vrf %d", &vrf_id))
6721         vrf_id_set = 1;
6722       else if (unformat (i, "ipv6"))
6723         is_ipv6 = 1;
6724       else if (unformat (i, "src"))
6725         src = 1;
6726       else if (unformat (i, "dst"))
6727         dst = 1;
6728       else if (unformat (i, "sport"))
6729         sport = 1;
6730       else if (unformat (i, "dport"))
6731         dport = 1;
6732       else if (unformat (i, "proto"))
6733         proto = 1;
6734       else if (unformat (i, "reverse"))
6735         reverse = 1;
6736
6737       else
6738         {
6739           clib_warning ("parse error '%U'", format_unformat_error, i);
6740           return -99;
6741         }
6742     }
6743
6744   if (vrf_id_set == 0)
6745     {
6746       errmsg ("missing vrf id\n");
6747       return -99;
6748     }
6749
6750   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
6751   mp->src = src;
6752   mp->dst = dst;
6753   mp->sport = sport;
6754   mp->dport = dport;
6755   mp->proto = proto;
6756   mp->reverse = reverse;
6757   mp->vrf_id = ntohl (vrf_id);
6758   mp->is_ipv6 = is_ipv6;
6759
6760   S;
6761   W;
6762   /* NOTREACHED */
6763   return 0;
6764 }
6765
6766 static int
6767 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
6768 {
6769   unformat_input_t *i = vam->input;
6770   vl_api_sw_interface_ip6_enable_disable_t *mp;
6771   f64 timeout;
6772   u32 sw_if_index;
6773   u8 sw_if_index_set = 0;
6774   u8 enable = 0;
6775
6776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6777     {
6778       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6779         sw_if_index_set = 1;
6780       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6781         sw_if_index_set = 1;
6782       else if (unformat (i, "enable"))
6783         enable = 1;
6784       else if (unformat (i, "disable"))
6785         enable = 0;
6786       else
6787         {
6788           clib_warning ("parse error '%U'", format_unformat_error, i);
6789           return -99;
6790         }
6791     }
6792
6793   if (sw_if_index_set == 0)
6794     {
6795       errmsg ("missing interface name or sw_if_index\n");
6796       return -99;
6797     }
6798
6799   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
6800
6801   mp->sw_if_index = ntohl (sw_if_index);
6802   mp->enable = enable;
6803
6804   S;
6805   W;
6806   /* NOTREACHED */
6807   return 0;
6808 }
6809
6810 static int
6811 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
6812 {
6813   unformat_input_t *i = vam->input;
6814   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
6815   f64 timeout;
6816   u32 sw_if_index;
6817   u8 sw_if_index_set = 0;
6818   u32 address_length = 0;
6819   u8 v6_address_set = 0;
6820   ip6_address_t v6address;
6821
6822   /* Parse args required to build the message */
6823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6824     {
6825       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6826         sw_if_index_set = 1;
6827       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6828         sw_if_index_set = 1;
6829       else if (unformat (i, "%U/%d",
6830                          unformat_ip6_address, &v6address, &address_length))
6831         v6_address_set = 1;
6832       else
6833         break;
6834     }
6835
6836   if (sw_if_index_set == 0)
6837     {
6838       errmsg ("missing interface name or sw_if_index\n");
6839       return -99;
6840     }
6841   if (!v6_address_set)
6842     {
6843       errmsg ("no address set\n");
6844       return -99;
6845     }
6846
6847   /* Construct the API message */
6848   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
6849      sw_interface_ip6_set_link_local_address);
6850
6851   mp->sw_if_index = ntohl (sw_if_index);
6852   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6853   mp->address_length = address_length;
6854
6855   /* send it... */
6856   S;
6857
6858   /* Wait for a reply, return good/bad news  */
6859   W;
6860
6861   /* NOTREACHED */
6862   return 0;
6863 }
6864
6865
6866 static int
6867 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
6868 {
6869   unformat_input_t *i = vam->input;
6870   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
6871   f64 timeout;
6872   u32 sw_if_index;
6873   u8 sw_if_index_set = 0;
6874   u32 address_length = 0;
6875   u8 v6_address_set = 0;
6876   ip6_address_t v6address;
6877   u8 use_default = 0;
6878   u8 no_advertise = 0;
6879   u8 off_link = 0;
6880   u8 no_autoconfig = 0;
6881   u8 no_onlink = 0;
6882   u8 is_no = 0;
6883   u32 val_lifetime = 0;
6884   u32 pref_lifetime = 0;
6885
6886   /* Parse args required to build the message */
6887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6888     {
6889       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6890         sw_if_index_set = 1;
6891       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6892         sw_if_index_set = 1;
6893       else if (unformat (i, "%U/%d",
6894                          unformat_ip6_address, &v6address, &address_length))
6895         v6_address_set = 1;
6896       else if (unformat (i, "val_life %d", &val_lifetime))
6897         ;
6898       else if (unformat (i, "pref_life %d", &pref_lifetime))
6899         ;
6900       else if (unformat (i, "def"))
6901         use_default = 1;
6902       else if (unformat (i, "noadv"))
6903         no_advertise = 1;
6904       else if (unformat (i, "offl"))
6905         off_link = 1;
6906       else if (unformat (i, "noauto"))
6907         no_autoconfig = 1;
6908       else if (unformat (i, "nolink"))
6909         no_onlink = 1;
6910       else if (unformat (i, "isno"))
6911         is_no = 1;
6912       else
6913         {
6914           clib_warning ("parse error '%U'", format_unformat_error, i);
6915           return -99;
6916         }
6917     }
6918
6919   if (sw_if_index_set == 0)
6920     {
6921       errmsg ("missing interface name or sw_if_index\n");
6922       return -99;
6923     }
6924   if (!v6_address_set)
6925     {
6926       errmsg ("no address set\n");
6927       return -99;
6928     }
6929
6930   /* Construct the API message */
6931   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
6932
6933   mp->sw_if_index = ntohl (sw_if_index);
6934   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6935   mp->address_length = address_length;
6936   mp->use_default = use_default;
6937   mp->no_advertise = no_advertise;
6938   mp->off_link = off_link;
6939   mp->no_autoconfig = no_autoconfig;
6940   mp->no_onlink = no_onlink;
6941   mp->is_no = is_no;
6942   mp->val_lifetime = ntohl (val_lifetime);
6943   mp->pref_lifetime = ntohl (pref_lifetime);
6944
6945   /* send it... */
6946   S;
6947
6948   /* Wait for a reply, return good/bad news  */
6949   W;
6950
6951   /* NOTREACHED */
6952   return 0;
6953 }
6954
6955 static int
6956 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
6957 {
6958   unformat_input_t *i = vam->input;
6959   vl_api_sw_interface_ip6nd_ra_config_t *mp;
6960   f64 timeout;
6961   u32 sw_if_index;
6962   u8 sw_if_index_set = 0;
6963   u8 suppress = 0;
6964   u8 managed = 0;
6965   u8 other = 0;
6966   u8 ll_option = 0;
6967   u8 send_unicast = 0;
6968   u8 cease = 0;
6969   u8 is_no = 0;
6970   u8 default_router = 0;
6971   u32 max_interval = 0;
6972   u32 min_interval = 0;
6973   u32 lifetime = 0;
6974   u32 initial_count = 0;
6975   u32 initial_interval = 0;
6976
6977
6978   /* Parse args required to build the message */
6979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6980     {
6981       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6982         sw_if_index_set = 1;
6983       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6984         sw_if_index_set = 1;
6985       else if (unformat (i, "maxint %d", &max_interval))
6986         ;
6987       else if (unformat (i, "minint %d", &min_interval))
6988         ;
6989       else if (unformat (i, "life %d", &lifetime))
6990         ;
6991       else if (unformat (i, "count %d", &initial_count))
6992         ;
6993       else if (unformat (i, "interval %d", &initial_interval))
6994         ;
6995       else if (unformat (i, "suppress") || unformat (i, "surpress"))
6996         suppress = 1;
6997       else if (unformat (i, "managed"))
6998         managed = 1;
6999       else if (unformat (i, "other"))
7000         other = 1;
7001       else if (unformat (i, "ll"))
7002         ll_option = 1;
7003       else if (unformat (i, "send"))
7004         send_unicast = 1;
7005       else if (unformat (i, "cease"))
7006         cease = 1;
7007       else if (unformat (i, "isno"))
7008         is_no = 1;
7009       else if (unformat (i, "def"))
7010         default_router = 1;
7011       else
7012         {
7013           clib_warning ("parse error '%U'", format_unformat_error, i);
7014           return -99;
7015         }
7016     }
7017
7018   if (sw_if_index_set == 0)
7019     {
7020       errmsg ("missing interface name or sw_if_index\n");
7021       return -99;
7022     }
7023
7024   /* Construct the API message */
7025   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7026
7027   mp->sw_if_index = ntohl (sw_if_index);
7028   mp->max_interval = ntohl (max_interval);
7029   mp->min_interval = ntohl (min_interval);
7030   mp->lifetime = ntohl (lifetime);
7031   mp->initial_count = ntohl (initial_count);
7032   mp->initial_interval = ntohl (initial_interval);
7033   mp->suppress = suppress;
7034   mp->managed = managed;
7035   mp->other = other;
7036   mp->ll_option = ll_option;
7037   mp->send_unicast = send_unicast;
7038   mp->cease = cease;
7039   mp->is_no = is_no;
7040   mp->default_router = default_router;
7041
7042   /* send it... */
7043   S;
7044
7045   /* Wait for a reply, return good/bad news  */
7046   W;
7047
7048   /* NOTREACHED */
7049   return 0;
7050 }
7051
7052 static int
7053 api_set_arp_neighbor_limit (vat_main_t * vam)
7054 {
7055   unformat_input_t *i = vam->input;
7056   vl_api_set_arp_neighbor_limit_t *mp;
7057   f64 timeout;
7058   u32 arp_nbr_limit;
7059   u8 limit_set = 0;
7060   u8 is_ipv6 = 0;
7061
7062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7063     {
7064       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7065         limit_set = 1;
7066       else if (unformat (i, "ipv6"))
7067         is_ipv6 = 1;
7068       else
7069         {
7070           clib_warning ("parse error '%U'", format_unformat_error, i);
7071           return -99;
7072         }
7073     }
7074
7075   if (limit_set == 0)
7076     {
7077       errmsg ("missing limit value\n");
7078       return -99;
7079     }
7080
7081   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7082
7083   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7084   mp->is_ipv6 = is_ipv6;
7085
7086   S;
7087   W;
7088   /* NOTREACHED */
7089   return 0;
7090 }
7091
7092 static int
7093 api_l2_patch_add_del (vat_main_t * vam)
7094 {
7095   unformat_input_t *i = vam->input;
7096   vl_api_l2_patch_add_del_t *mp;
7097   f64 timeout;
7098   u32 rx_sw_if_index;
7099   u8 rx_sw_if_index_set = 0;
7100   u32 tx_sw_if_index;
7101   u8 tx_sw_if_index_set = 0;
7102   u8 is_add = 1;
7103
7104   /* Parse args required to build the message */
7105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7106     {
7107       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7108         rx_sw_if_index_set = 1;
7109       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7110         tx_sw_if_index_set = 1;
7111       else if (unformat (i, "rx"))
7112         {
7113           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7114             {
7115               if (unformat (i, "%U", unformat_sw_if_index, vam,
7116                             &rx_sw_if_index))
7117                 rx_sw_if_index_set = 1;
7118             }
7119           else
7120             break;
7121         }
7122       else if (unformat (i, "tx"))
7123         {
7124           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7125             {
7126               if (unformat (i, "%U", unformat_sw_if_index, vam,
7127                             &tx_sw_if_index))
7128                 tx_sw_if_index_set = 1;
7129             }
7130           else
7131             break;
7132         }
7133       else if (unformat (i, "del"))
7134         is_add = 0;
7135       else
7136         break;
7137     }
7138
7139   if (rx_sw_if_index_set == 0)
7140     {
7141       errmsg ("missing rx interface name or rx_sw_if_index\n");
7142       return -99;
7143     }
7144
7145   if (tx_sw_if_index_set == 0)
7146     {
7147       errmsg ("missing tx interface name or tx_sw_if_index\n");
7148       return -99;
7149     }
7150
7151   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7152
7153   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7154   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7155   mp->is_add = is_add;
7156
7157   S;
7158   W;
7159   /* NOTREACHED */
7160   return 0;
7161 }
7162
7163 static int
7164 api_ioam_enable (vat_main_t * vam)
7165 {
7166   unformat_input_t *input = vam->input;
7167   vl_api_ioam_enable_t *mp;
7168   f64 timeout;
7169   u32 id = 0;
7170   int has_trace_option = 0;
7171   int has_pow_option = 0;
7172   int has_ppc_option = 0;
7173
7174   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7175     {
7176       if (unformat (input, "trace"))
7177         has_trace_option = 1;
7178       else if (unformat (input, "pow"))
7179         has_pow_option = 1;
7180       else if (unformat (input, "ppc encap"))
7181         has_ppc_option = PPC_ENCAP;
7182       else if (unformat (input, "ppc decap"))
7183         has_ppc_option = PPC_DECAP;
7184       else if (unformat (input, "ppc none"))
7185         has_ppc_option = PPC_NONE;
7186       else
7187         break;
7188     }
7189   M (IOAM_ENABLE, ioam_enable);
7190   mp->id = htons (id);
7191   mp->trace_ppc = has_ppc_option;
7192   mp->pow_enable = has_pow_option;
7193   mp->trace_enable = has_trace_option;
7194
7195   S;
7196   W;
7197
7198   return (0);
7199
7200 }
7201
7202
7203 static int
7204 api_ioam_disable (vat_main_t * vam)
7205 {
7206   vl_api_ioam_disable_t *mp;
7207   f64 timeout;
7208
7209   M (IOAM_DISABLE, ioam_disable);
7210   S;
7211   W;
7212   return 0;
7213 }
7214
7215 static int
7216 api_sr_tunnel_add_del (vat_main_t * vam)
7217 {
7218   unformat_input_t *i = vam->input;
7219   vl_api_sr_tunnel_add_del_t *mp;
7220   f64 timeout;
7221   int is_del = 0;
7222   int pl_index;
7223   ip6_address_t src_address;
7224   int src_address_set = 0;
7225   ip6_address_t dst_address;
7226   u32 dst_mask_width;
7227   int dst_address_set = 0;
7228   u16 flags = 0;
7229   u32 rx_table_id = 0;
7230   u32 tx_table_id = 0;
7231   ip6_address_t *segments = 0;
7232   ip6_address_t *this_seg;
7233   ip6_address_t *tags = 0;
7234   ip6_address_t *this_tag;
7235   ip6_address_t next_address, tag;
7236   u8 *name = 0;
7237   u8 *policy_name = 0;
7238
7239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7240     {
7241       if (unformat (i, "del"))
7242         is_del = 1;
7243       else if (unformat (i, "name %s", &name))
7244         ;
7245       else if (unformat (i, "policy %s", &policy_name))
7246         ;
7247       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7248         ;
7249       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7250         ;
7251       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7252         src_address_set = 1;
7253       else if (unformat (i, "dst %U/%d",
7254                          unformat_ip6_address, &dst_address, &dst_mask_width))
7255         dst_address_set = 1;
7256       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7257         {
7258           vec_add2 (segments, this_seg, 1);
7259           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7260                        sizeof (*this_seg));
7261         }
7262       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7263         {
7264           vec_add2 (tags, this_tag, 1);
7265           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7266         }
7267       else if (unformat (i, "clean"))
7268         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7269       else if (unformat (i, "protected"))
7270         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7271       else if (unformat (i, "InPE %d", &pl_index))
7272         {
7273           if (pl_index <= 0 || pl_index > 4)
7274             {
7275             pl_index_range_error:
7276               errmsg ("pl index %d out of range\n", pl_index);
7277               return -99;
7278             }
7279           flags |=
7280             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7281         }
7282       else if (unformat (i, "EgPE %d", &pl_index))
7283         {
7284           if (pl_index <= 0 || pl_index > 4)
7285             goto pl_index_range_error;
7286           flags |=
7287             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7288         }
7289       else if (unformat (i, "OrgSrc %d", &pl_index))
7290         {
7291           if (pl_index <= 0 || pl_index > 4)
7292             goto pl_index_range_error;
7293           flags |=
7294             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7295         }
7296       else
7297         break;
7298     }
7299
7300   if (!src_address_set)
7301     {
7302       errmsg ("src address required\n");
7303       return -99;
7304     }
7305
7306   if (!dst_address_set)
7307     {
7308       errmsg ("dst address required\n");
7309       return -99;
7310     }
7311
7312   if (!segments)
7313     {
7314       errmsg ("at least one sr segment required\n");
7315       return -99;
7316     }
7317
7318   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7319       vec_len (segments) * sizeof (ip6_address_t)
7320       + vec_len (tags) * sizeof (ip6_address_t));
7321
7322   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7323   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7324   mp->dst_mask_width = dst_mask_width;
7325   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7326   mp->n_segments = vec_len (segments);
7327   mp->n_tags = vec_len (tags);
7328   mp->is_add = is_del == 0;
7329   clib_memcpy (mp->segs_and_tags, segments,
7330                vec_len (segments) * sizeof (ip6_address_t));
7331   clib_memcpy (mp->segs_and_tags +
7332                vec_len (segments) * sizeof (ip6_address_t), tags,
7333                vec_len (tags) * sizeof (ip6_address_t));
7334
7335   mp->outer_vrf_id = ntohl (rx_table_id);
7336   mp->inner_vrf_id = ntohl (tx_table_id);
7337   memcpy (mp->name, name, vec_len (name));
7338   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7339
7340   vec_free (segments);
7341   vec_free (tags);
7342
7343   S;
7344   W;
7345   /* NOTREACHED */
7346 }
7347
7348 static int
7349 api_sr_policy_add_del (vat_main_t * vam)
7350 {
7351   unformat_input_t *input = vam->input;
7352   vl_api_sr_policy_add_del_t *mp;
7353   f64 timeout;
7354   int is_del = 0;
7355   u8 *name = 0;
7356   u8 *tunnel_name = 0;
7357   u8 **tunnel_names = 0;
7358
7359   int name_set = 0;
7360   int tunnel_set = 0;
7361   int j = 0;
7362   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7363   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7364
7365   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7366     {
7367       if (unformat (input, "del"))
7368         is_del = 1;
7369       else if (unformat (input, "name %s", &name))
7370         name_set = 1;
7371       else if (unformat (input, "tunnel %s", &tunnel_name))
7372         {
7373           if (tunnel_name)
7374             {
7375               vec_add1 (tunnel_names, tunnel_name);
7376               /* For serializer:
7377                  - length = #bytes to store in serial vector
7378                  - +1 = byte to store that length
7379                */
7380               tunnel_names_length += (vec_len (tunnel_name) + 1);
7381               tunnel_set = 1;
7382               tunnel_name = 0;
7383             }
7384         }
7385       else
7386         break;
7387     }
7388
7389   if (!name_set)
7390     {
7391       errmsg ("policy name required\n");
7392       return -99;
7393     }
7394
7395   if ((!tunnel_set) && (!is_del))
7396     {
7397       errmsg ("tunnel name required\n");
7398       return -99;
7399     }
7400
7401   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7402
7403
7404
7405   mp->is_add = !is_del;
7406
7407   memcpy (mp->name, name, vec_len (name));
7408   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7409   u8 *serial_orig = 0;
7410   vec_validate (serial_orig, tunnel_names_length);
7411   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7412   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7413
7414   for (j = 0; j < vec_len (tunnel_names); j++)
7415     {
7416       tun_name_len = vec_len (tunnel_names[j]);
7417       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7418       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7419       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7420       serial_orig += tun_name_len;      // Advance past the copy
7421     }
7422   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7423
7424   vec_free (tunnel_names);
7425   vec_free (tunnel_name);
7426
7427   S;
7428   W;
7429   /* NOTREACHED */
7430 }
7431
7432 static int
7433 api_sr_multicast_map_add_del (vat_main_t * vam)
7434 {
7435   unformat_input_t *input = vam->input;
7436   vl_api_sr_multicast_map_add_del_t *mp;
7437   f64 timeout;
7438   int is_del = 0;
7439   ip6_address_t multicast_address;
7440   u8 *policy_name = 0;
7441   int multicast_address_set = 0;
7442
7443   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7444     {
7445       if (unformat (input, "del"))
7446         is_del = 1;
7447       else
7448         if (unformat
7449             (input, "address %U", unformat_ip6_address, &multicast_address))
7450         multicast_address_set = 1;
7451       else if (unformat (input, "sr-policy %s", &policy_name))
7452         ;
7453       else
7454         break;
7455     }
7456
7457   if (!is_del && !policy_name)
7458     {
7459       errmsg ("sr-policy name required\n");
7460       return -99;
7461     }
7462
7463
7464   if (!multicast_address_set)
7465     {
7466       errmsg ("address required\n");
7467       return -99;
7468     }
7469
7470   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7471
7472   mp->is_add = !is_del;
7473   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7474   clib_memcpy (mp->multicast_address, &multicast_address,
7475                sizeof (mp->multicast_address));
7476
7477
7478   vec_free (policy_name);
7479
7480   S;
7481   W;
7482   /* NOTREACHED */
7483 }
7484
7485
7486 #define foreach_ip4_proto_field                 \
7487 _(src_address)                                  \
7488 _(dst_address)                                  \
7489 _(tos)                                          \
7490 _(length)                                       \
7491 _(fragment_id)                                  \
7492 _(ttl)                                          \
7493 _(protocol)                                     \
7494 _(checksum)
7495
7496 uword
7497 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7498 {
7499   u8 **maskp = va_arg (*args, u8 **);
7500   u8 *mask = 0;
7501   u8 found_something = 0;
7502   ip4_header_t *ip;
7503
7504 #define _(a) u8 a=0;
7505   foreach_ip4_proto_field;
7506 #undef _
7507   u8 version = 0;
7508   u8 hdr_length = 0;
7509
7510
7511   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7512     {
7513       if (unformat (input, "version"))
7514         version = 1;
7515       else if (unformat (input, "hdr_length"))
7516         hdr_length = 1;
7517       else if (unformat (input, "src"))
7518         src_address = 1;
7519       else if (unformat (input, "dst"))
7520         dst_address = 1;
7521       else if (unformat (input, "proto"))
7522         protocol = 1;
7523
7524 #define _(a) else if (unformat (input, #a)) a=1;
7525       foreach_ip4_proto_field
7526 #undef _
7527         else
7528         break;
7529     }
7530
7531 #define _(a) found_something += a;
7532   foreach_ip4_proto_field;
7533 #undef _
7534
7535   if (found_something == 0)
7536     return 0;
7537
7538   vec_validate (mask, sizeof (*ip) - 1);
7539
7540   ip = (ip4_header_t *) mask;
7541
7542 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7543   foreach_ip4_proto_field;
7544 #undef _
7545
7546   ip->ip_version_and_header_length = 0;
7547
7548   if (version)
7549     ip->ip_version_and_header_length |= 0xF0;
7550
7551   if (hdr_length)
7552     ip->ip_version_and_header_length |= 0x0F;
7553
7554   *maskp = mask;
7555   return 1;
7556 }
7557
7558 #define foreach_ip6_proto_field                 \
7559 _(src_address)                                  \
7560 _(dst_address)                                  \
7561 _(payload_length)                               \
7562 _(hop_limit)                                    \
7563 _(protocol)
7564
7565 uword
7566 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7567 {
7568   u8 **maskp = va_arg (*args, u8 **);
7569   u8 *mask = 0;
7570   u8 found_something = 0;
7571   ip6_header_t *ip;
7572   u32 ip_version_traffic_class_and_flow_label;
7573
7574 #define _(a) u8 a=0;
7575   foreach_ip6_proto_field;
7576 #undef _
7577   u8 version = 0;
7578   u8 traffic_class = 0;
7579   u8 flow_label = 0;
7580
7581   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7582     {
7583       if (unformat (input, "version"))
7584         version = 1;
7585       else if (unformat (input, "traffic-class"))
7586         traffic_class = 1;
7587       else if (unformat (input, "flow-label"))
7588         flow_label = 1;
7589       else if (unformat (input, "src"))
7590         src_address = 1;
7591       else if (unformat (input, "dst"))
7592         dst_address = 1;
7593       else if (unformat (input, "proto"))
7594         protocol = 1;
7595
7596 #define _(a) else if (unformat (input, #a)) a=1;
7597       foreach_ip6_proto_field
7598 #undef _
7599         else
7600         break;
7601     }
7602
7603 #define _(a) found_something += a;
7604   foreach_ip6_proto_field;
7605 #undef _
7606
7607   if (found_something == 0)
7608     return 0;
7609
7610   vec_validate (mask, sizeof (*ip) - 1);
7611
7612   ip = (ip6_header_t *) mask;
7613
7614 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7615   foreach_ip6_proto_field;
7616 #undef _
7617
7618   ip_version_traffic_class_and_flow_label = 0;
7619
7620   if (version)
7621     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7622
7623   if (traffic_class)
7624     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7625
7626   if (flow_label)
7627     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7628
7629   ip->ip_version_traffic_class_and_flow_label =
7630     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7631
7632   *maskp = mask;
7633   return 1;
7634 }
7635
7636 uword
7637 unformat_l3_mask (unformat_input_t * input, va_list * args)
7638 {
7639   u8 **maskp = va_arg (*args, u8 **);
7640
7641   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7642     {
7643       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7644         return 1;
7645       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7646         return 1;
7647       else
7648         break;
7649     }
7650   return 0;
7651 }
7652
7653 uword
7654 unformat_l2_mask (unformat_input_t * input, va_list * args)
7655 {
7656   u8 **maskp = va_arg (*args, u8 **);
7657   u8 *mask = 0;
7658   u8 src = 0;
7659   u8 dst = 0;
7660   u8 proto = 0;
7661   u8 tag1 = 0;
7662   u8 tag2 = 0;
7663   u8 ignore_tag1 = 0;
7664   u8 ignore_tag2 = 0;
7665   u8 cos1 = 0;
7666   u8 cos2 = 0;
7667   u8 dot1q = 0;
7668   u8 dot1ad = 0;
7669   int len = 14;
7670
7671   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7672     {
7673       if (unformat (input, "src"))
7674         src = 1;
7675       else if (unformat (input, "dst"))
7676         dst = 1;
7677       else if (unformat (input, "proto"))
7678         proto = 1;
7679       else if (unformat (input, "tag1"))
7680         tag1 = 1;
7681       else if (unformat (input, "tag2"))
7682         tag2 = 1;
7683       else if (unformat (input, "ignore-tag1"))
7684         ignore_tag1 = 1;
7685       else if (unformat (input, "ignore-tag2"))
7686         ignore_tag2 = 1;
7687       else if (unformat (input, "cos1"))
7688         cos1 = 1;
7689       else if (unformat (input, "cos2"))
7690         cos2 = 1;
7691       else if (unformat (input, "dot1q"))
7692         dot1q = 1;
7693       else if (unformat (input, "dot1ad"))
7694         dot1ad = 1;
7695       else
7696         break;
7697     }
7698   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7699        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7700     return 0;
7701
7702   if (tag1 || ignore_tag1 || cos1 || dot1q)
7703     len = 18;
7704   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7705     len = 22;
7706
7707   vec_validate (mask, len - 1);
7708
7709   if (dst)
7710     memset (mask, 0xff, 6);
7711
7712   if (src)
7713     memset (mask + 6, 0xff, 6);
7714
7715   if (tag2 || dot1ad)
7716     {
7717       /* inner vlan tag */
7718       if (tag2)
7719         {
7720           mask[19] = 0xff;
7721           mask[18] = 0x0f;
7722         }
7723       if (cos2)
7724         mask[18] |= 0xe0;
7725       if (proto)
7726         mask[21] = mask[20] = 0xff;
7727       if (tag1)
7728         {
7729           mask[15] = 0xff;
7730           mask[14] = 0x0f;
7731         }
7732       if (cos1)
7733         mask[14] |= 0xe0;
7734       *maskp = mask;
7735       return 1;
7736     }
7737   if (tag1 | dot1q)
7738     {
7739       if (tag1)
7740         {
7741           mask[15] = 0xff;
7742           mask[14] = 0x0f;
7743         }
7744       if (cos1)
7745         mask[14] |= 0xe0;
7746       if (proto)
7747         mask[16] = mask[17] = 0xff;
7748
7749       *maskp = mask;
7750       return 1;
7751     }
7752   if (cos2)
7753     mask[18] |= 0xe0;
7754   if (cos1)
7755     mask[14] |= 0xe0;
7756   if (proto)
7757     mask[12] = mask[13] = 0xff;
7758
7759   *maskp = mask;
7760   return 1;
7761 }
7762
7763 uword
7764 unformat_classify_mask (unformat_input_t * input, va_list * args)
7765 {
7766   u8 **maskp = va_arg (*args, u8 **);
7767   u32 *skipp = va_arg (*args, u32 *);
7768   u32 *matchp = va_arg (*args, u32 *);
7769   u32 match;
7770   u8 *mask = 0;
7771   u8 *l2 = 0;
7772   u8 *l3 = 0;
7773   int i;
7774
7775   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7776     {
7777       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7778         ;
7779       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7780         ;
7781       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7782         ;
7783       else
7784         break;
7785     }
7786
7787   if (mask || l2 || l3)
7788     {
7789       if (l2 || l3)
7790         {
7791           /* "With a free Ethernet header in every package" */
7792           if (l2 == 0)
7793             vec_validate (l2, 13);
7794           mask = l2;
7795           if (vec_len (l3))
7796             {
7797               vec_append (mask, l3);
7798               vec_free (l3);
7799             }
7800         }
7801
7802       /* Scan forward looking for the first significant mask octet */
7803       for (i = 0; i < vec_len (mask); i++)
7804         if (mask[i])
7805           break;
7806
7807       /* compute (skip, match) params */
7808       *skipp = i / sizeof (u32x4);
7809       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7810
7811       /* Pad mask to an even multiple of the vector size */
7812       while (vec_len (mask) % sizeof (u32x4))
7813         vec_add1 (mask, 0);
7814
7815       match = vec_len (mask) / sizeof (u32x4);
7816
7817       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7818         {
7819           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7820           if (*tmp || *(tmp + 1))
7821             break;
7822           match--;
7823         }
7824       if (match == 0)
7825         clib_warning ("BUG: match 0");
7826
7827       _vec_len (mask) = match * sizeof (u32x4);
7828
7829       *matchp = match;
7830       *maskp = mask;
7831
7832       return 1;
7833     }
7834
7835   return 0;
7836 }
7837
7838 #define foreach_l2_next                         \
7839 _(drop, DROP)                                   \
7840 _(ethernet, ETHERNET_INPUT)                     \
7841 _(ip4, IP4_INPUT)                               \
7842 _(ip6, IP6_INPUT)
7843
7844 uword
7845 unformat_l2_next_index (unformat_input_t * input, va_list * args)
7846 {
7847   u32 *miss_next_indexp = va_arg (*args, u32 *);
7848   u32 next_index = 0;
7849   u32 tmp;
7850
7851 #define _(n,N) \
7852   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
7853   foreach_l2_next;
7854 #undef _
7855
7856   if (unformat (input, "%d", &tmp))
7857     {
7858       next_index = tmp;
7859       goto out;
7860     }
7861
7862   return 0;
7863
7864 out:
7865   *miss_next_indexp = next_index;
7866   return 1;
7867 }
7868
7869 #define foreach_ip_next                         \
7870 _(drop, DROP)                                   \
7871 _(local, LOCAL)                                 \
7872 _(rewrite, REWRITE)
7873
7874 uword
7875 unformat_ip_next_index (unformat_input_t * input, va_list * args)
7876 {
7877   u32 *miss_next_indexp = va_arg (*args, u32 *);
7878   u32 next_index = 0;
7879   u32 tmp;
7880
7881 #define _(n,N) \
7882   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7883   foreach_ip_next;
7884 #undef _
7885
7886   if (unformat (input, "%d", &tmp))
7887     {
7888       next_index = tmp;
7889       goto out;
7890     }
7891
7892   return 0;
7893
7894 out:
7895   *miss_next_indexp = next_index;
7896   return 1;
7897 }
7898
7899 #define foreach_acl_next                        \
7900 _(deny, DENY)
7901
7902 uword
7903 unformat_acl_next_index (unformat_input_t * input, va_list * args)
7904 {
7905   u32 *miss_next_indexp = va_arg (*args, u32 *);
7906   u32 next_index = 0;
7907   u32 tmp;
7908
7909 #define _(n,N) \
7910   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7911   foreach_acl_next;
7912 #undef _
7913
7914   if (unformat (input, "permit"))
7915     {
7916       next_index = ~0;
7917       goto out;
7918     }
7919   else if (unformat (input, "%d", &tmp))
7920     {
7921       next_index = tmp;
7922       goto out;
7923     }
7924
7925   return 0;
7926
7927 out:
7928   *miss_next_indexp = next_index;
7929   return 1;
7930 }
7931
7932 uword
7933 unformat_policer_precolor (unformat_input_t * input, va_list * args)
7934 {
7935   u32 *r = va_arg (*args, u32 *);
7936
7937   if (unformat (input, "conform-color"))
7938     *r = POLICE_CONFORM;
7939   else if (unformat (input, "exceed-color"))
7940     *r = POLICE_EXCEED;
7941   else
7942     return 0;
7943
7944   return 1;
7945 }
7946
7947 static int
7948 api_classify_add_del_table (vat_main_t * vam)
7949 {
7950   unformat_input_t *i = vam->input;
7951   vl_api_classify_add_del_table_t *mp;
7952
7953   u32 nbuckets = 2;
7954   u32 skip = ~0;
7955   u32 match = ~0;
7956   int is_add = 1;
7957   u32 table_index = ~0;
7958   u32 next_table_index = ~0;
7959   u32 miss_next_index = ~0;
7960   u32 memory_size = 32 << 20;
7961   u8 *mask = 0;
7962   f64 timeout;
7963
7964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7965     {
7966       if (unformat (i, "del"))
7967         is_add = 0;
7968       else if (unformat (i, "buckets %d", &nbuckets))
7969         ;
7970       else if (unformat (i, "memory_size %d", &memory_size))
7971         ;
7972       else if (unformat (i, "skip %d", &skip))
7973         ;
7974       else if (unformat (i, "match %d", &match))
7975         ;
7976       else if (unformat (i, "table %d", &table_index))
7977         ;
7978       else if (unformat (i, "mask %U", unformat_classify_mask,
7979                          &mask, &skip, &match))
7980         ;
7981       else if (unformat (i, "next-table %d", &next_table_index))
7982         ;
7983       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
7984                          &miss_next_index))
7985         ;
7986       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
7987                          &miss_next_index))
7988         ;
7989       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
7990                          &miss_next_index))
7991         ;
7992       else
7993         break;
7994     }
7995
7996   if (is_add && mask == 0)
7997     {
7998       errmsg ("Mask required\n");
7999       return -99;
8000     }
8001
8002   if (is_add && skip == ~0)
8003     {
8004       errmsg ("skip count required\n");
8005       return -99;
8006     }
8007
8008   if (is_add && match == ~0)
8009     {
8010       errmsg ("match count required\n");
8011       return -99;
8012     }
8013
8014   if (!is_add && table_index == ~0)
8015     {
8016       errmsg ("table index required for delete\n");
8017       return -99;
8018     }
8019
8020   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8021
8022   mp->is_add = is_add;
8023   mp->table_index = ntohl (table_index);
8024   mp->nbuckets = ntohl (nbuckets);
8025   mp->memory_size = ntohl (memory_size);
8026   mp->skip_n_vectors = ntohl (skip);
8027   mp->match_n_vectors = ntohl (match);
8028   mp->next_table_index = ntohl (next_table_index);
8029   mp->miss_next_index = ntohl (miss_next_index);
8030   clib_memcpy (mp->mask, mask, vec_len (mask));
8031
8032   vec_free (mask);
8033
8034   S;
8035   W;
8036   /* NOTREACHED */
8037 }
8038
8039 uword
8040 unformat_ip4_match (unformat_input_t * input, va_list * args)
8041 {
8042   u8 **matchp = va_arg (*args, u8 **);
8043   u8 *match = 0;
8044   ip4_header_t *ip;
8045   int version = 0;
8046   u32 version_val;
8047   int hdr_length = 0;
8048   u32 hdr_length_val;
8049   int src = 0, dst = 0;
8050   ip4_address_t src_val, dst_val;
8051   int proto = 0;
8052   u32 proto_val;
8053   int tos = 0;
8054   u32 tos_val;
8055   int length = 0;
8056   u32 length_val;
8057   int fragment_id = 0;
8058   u32 fragment_id_val;
8059   int ttl = 0;
8060   int ttl_val;
8061   int checksum = 0;
8062   u32 checksum_val;
8063
8064   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8065     {
8066       if (unformat (input, "version %d", &version_val))
8067         version = 1;
8068       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8069         hdr_length = 1;
8070       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8071         src = 1;
8072       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8073         dst = 1;
8074       else if (unformat (input, "proto %d", &proto_val))
8075         proto = 1;
8076       else if (unformat (input, "tos %d", &tos_val))
8077         tos = 1;
8078       else if (unformat (input, "length %d", &length_val))
8079         length = 1;
8080       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8081         fragment_id = 1;
8082       else if (unformat (input, "ttl %d", &ttl_val))
8083         ttl = 1;
8084       else if (unformat (input, "checksum %d", &checksum_val))
8085         checksum = 1;
8086       else
8087         break;
8088     }
8089
8090   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8091       + ttl + checksum == 0)
8092     return 0;
8093
8094   /*
8095    * Aligned because we use the real comparison functions
8096    */
8097   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8098
8099   ip = (ip4_header_t *) match;
8100
8101   /* These are realistically matched in practice */
8102   if (src)
8103     ip->src_address.as_u32 = src_val.as_u32;
8104
8105   if (dst)
8106     ip->dst_address.as_u32 = dst_val.as_u32;
8107
8108   if (proto)
8109     ip->protocol = proto_val;
8110
8111
8112   /* These are not, but they're included for completeness */
8113   if (version)
8114     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8115
8116   if (hdr_length)
8117     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8118
8119   if (tos)
8120     ip->tos = tos_val;
8121
8122   if (length)
8123     ip->length = length_val;
8124
8125   if (ttl)
8126     ip->ttl = ttl_val;
8127
8128   if (checksum)
8129     ip->checksum = checksum_val;
8130
8131   *matchp = match;
8132   return 1;
8133 }
8134
8135 uword
8136 unformat_ip6_match (unformat_input_t * input, va_list * args)
8137 {
8138   u8 **matchp = va_arg (*args, u8 **);
8139   u8 *match = 0;
8140   ip6_header_t *ip;
8141   int version = 0;
8142   u32 version_val;
8143   u8 traffic_class = 0;
8144   u32 traffic_class_val = 0;
8145   u8 flow_label = 0;
8146   u8 flow_label_val;
8147   int src = 0, dst = 0;
8148   ip6_address_t src_val, dst_val;
8149   int proto = 0;
8150   u32 proto_val;
8151   int payload_length = 0;
8152   u32 payload_length_val;
8153   int hop_limit = 0;
8154   int hop_limit_val;
8155   u32 ip_version_traffic_class_and_flow_label;
8156
8157   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8158     {
8159       if (unformat (input, "version %d", &version_val))
8160         version = 1;
8161       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8162         traffic_class = 1;
8163       else if (unformat (input, "flow_label %d", &flow_label_val))
8164         flow_label = 1;
8165       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8166         src = 1;
8167       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8168         dst = 1;
8169       else if (unformat (input, "proto %d", &proto_val))
8170         proto = 1;
8171       else if (unformat (input, "payload_length %d", &payload_length_val))
8172         payload_length = 1;
8173       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8174         hop_limit = 1;
8175       else
8176         break;
8177     }
8178
8179   if (version + traffic_class + flow_label + src + dst + proto +
8180       payload_length + hop_limit == 0)
8181     return 0;
8182
8183   /*
8184    * Aligned because we use the real comparison functions
8185    */
8186   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8187
8188   ip = (ip6_header_t *) match;
8189
8190   if (src)
8191     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8192
8193   if (dst)
8194     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8195
8196   if (proto)
8197     ip->protocol = proto_val;
8198
8199   ip_version_traffic_class_and_flow_label = 0;
8200
8201   if (version)
8202     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8203
8204   if (traffic_class)
8205     ip_version_traffic_class_and_flow_label |=
8206       (traffic_class_val & 0xFF) << 20;
8207
8208   if (flow_label)
8209     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8210
8211   ip->ip_version_traffic_class_and_flow_label =
8212     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8213
8214   if (payload_length)
8215     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8216
8217   if (hop_limit)
8218     ip->hop_limit = hop_limit_val;
8219
8220   *matchp = match;
8221   return 1;
8222 }
8223
8224 uword
8225 unformat_l3_match (unformat_input_t * input, va_list * args)
8226 {
8227   u8 **matchp = va_arg (*args, u8 **);
8228
8229   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8230     {
8231       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8232         return 1;
8233       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8234         return 1;
8235       else
8236         break;
8237     }
8238   return 0;
8239 }
8240
8241 uword
8242 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8243 {
8244   u8 *tagp = va_arg (*args, u8 *);
8245   u32 tag;
8246
8247   if (unformat (input, "%d", &tag))
8248     {
8249       tagp[0] = (tag >> 8) & 0x0F;
8250       tagp[1] = tag & 0xFF;
8251       return 1;
8252     }
8253
8254   return 0;
8255 }
8256
8257 uword
8258 unformat_l2_match (unformat_input_t * input, va_list * args)
8259 {
8260   u8 **matchp = va_arg (*args, u8 **);
8261   u8 *match = 0;
8262   u8 src = 0;
8263   u8 src_val[6];
8264   u8 dst = 0;
8265   u8 dst_val[6];
8266   u8 proto = 0;
8267   u16 proto_val;
8268   u8 tag1 = 0;
8269   u8 tag1_val[2];
8270   u8 tag2 = 0;
8271   u8 tag2_val[2];
8272   int len = 14;
8273   u8 ignore_tag1 = 0;
8274   u8 ignore_tag2 = 0;
8275   u8 cos1 = 0;
8276   u8 cos2 = 0;
8277   u32 cos1_val = 0;
8278   u32 cos2_val = 0;
8279
8280   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8281     {
8282       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8283         src = 1;
8284       else
8285         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8286         dst = 1;
8287       else if (unformat (input, "proto %U",
8288                          unformat_ethernet_type_host_byte_order, &proto_val))
8289         proto = 1;
8290       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8291         tag1 = 1;
8292       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8293         tag2 = 1;
8294       else if (unformat (input, "ignore-tag1"))
8295         ignore_tag1 = 1;
8296       else if (unformat (input, "ignore-tag2"))
8297         ignore_tag2 = 1;
8298       else if (unformat (input, "cos1 %d", &cos1_val))
8299         cos1 = 1;
8300       else if (unformat (input, "cos2 %d", &cos2_val))
8301         cos2 = 1;
8302       else
8303         break;
8304     }
8305   if ((src + dst + proto + tag1 + tag2 +
8306        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8307     return 0;
8308
8309   if (tag1 || ignore_tag1 || cos1)
8310     len = 18;
8311   if (tag2 || ignore_tag2 || cos2)
8312     len = 22;
8313
8314   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8315
8316   if (dst)
8317     clib_memcpy (match, dst_val, 6);
8318
8319   if (src)
8320     clib_memcpy (match + 6, src_val, 6);
8321
8322   if (tag2)
8323     {
8324       /* inner vlan tag */
8325       match[19] = tag2_val[1];
8326       match[18] = tag2_val[0];
8327       if (cos2)
8328         match[18] |= (cos2_val & 0x7) << 5;
8329       if (proto)
8330         {
8331           match[21] = proto_val & 0xff;
8332           match[20] = proto_val >> 8;
8333         }
8334       if (tag1)
8335         {
8336           match[15] = tag1_val[1];
8337           match[14] = tag1_val[0];
8338         }
8339       if (cos1)
8340         match[14] |= (cos1_val & 0x7) << 5;
8341       *matchp = match;
8342       return 1;
8343     }
8344   if (tag1)
8345     {
8346       match[15] = tag1_val[1];
8347       match[14] = tag1_val[0];
8348       if (proto)
8349         {
8350           match[17] = proto_val & 0xff;
8351           match[16] = proto_val >> 8;
8352         }
8353       if (cos1)
8354         match[14] |= (cos1_val & 0x7) << 5;
8355
8356       *matchp = match;
8357       return 1;
8358     }
8359   if (cos2)
8360     match[18] |= (cos2_val & 0x7) << 5;
8361   if (cos1)
8362     match[14] |= (cos1_val & 0x7) << 5;
8363   if (proto)
8364     {
8365       match[13] = proto_val & 0xff;
8366       match[12] = proto_val >> 8;
8367     }
8368
8369   *matchp = match;
8370   return 1;
8371 }
8372
8373
8374 uword
8375 unformat_classify_match (unformat_input_t * input, va_list * args)
8376 {
8377   u8 **matchp = va_arg (*args, u8 **);
8378   u32 skip_n_vectors = va_arg (*args, u32);
8379   u32 match_n_vectors = va_arg (*args, u32);
8380
8381   u8 *match = 0;
8382   u8 *l2 = 0;
8383   u8 *l3 = 0;
8384
8385   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8386     {
8387       if (unformat (input, "hex %U", unformat_hex_string, &match))
8388         ;
8389       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8390         ;
8391       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8392         ;
8393       else
8394         break;
8395     }
8396
8397   if (match || l2 || l3)
8398     {
8399       if (l2 || l3)
8400         {
8401           /* "Win a free Ethernet header in every packet" */
8402           if (l2 == 0)
8403             vec_validate_aligned (l2, 13, sizeof (u32x4));
8404           match = l2;
8405           if (vec_len (l3))
8406             {
8407               vec_append_aligned (match, l3, sizeof (u32x4));
8408               vec_free (l3);
8409             }
8410         }
8411
8412       /* Make sure the vector is big enough even if key is all 0's */
8413       vec_validate_aligned
8414         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8415          sizeof (u32x4));
8416
8417       /* Set size, include skipped vectors */
8418       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8419
8420       *matchp = match;
8421
8422       return 1;
8423     }
8424
8425   return 0;
8426 }
8427
8428 static int
8429 api_classify_add_del_session (vat_main_t * vam)
8430 {
8431   unformat_input_t *i = vam->input;
8432   vl_api_classify_add_del_session_t *mp;
8433   int is_add = 1;
8434   u32 table_index = ~0;
8435   u32 hit_next_index = ~0;
8436   u32 opaque_index = ~0;
8437   u8 *match = 0;
8438   i32 advance = 0;
8439   f64 timeout;
8440   u32 skip_n_vectors = 0;
8441   u32 match_n_vectors = 0;
8442
8443   /*
8444    * Warning: you have to supply skip_n and match_n
8445    * because the API client cant simply look at the classify
8446    * table object.
8447    */
8448
8449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8450     {
8451       if (unformat (i, "del"))
8452         is_add = 0;
8453       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8454                          &hit_next_index))
8455         ;
8456       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8457                          &hit_next_index))
8458         ;
8459       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8460                          &hit_next_index))
8461         ;
8462       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8463         ;
8464       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8465         ;
8466       else if (unformat (i, "opaque-index %d", &opaque_index))
8467         ;
8468       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8469         ;
8470       else if (unformat (i, "match_n %d", &match_n_vectors))
8471         ;
8472       else if (unformat (i, "match %U", unformat_classify_match,
8473                          &match, skip_n_vectors, match_n_vectors))
8474         ;
8475       else if (unformat (i, "advance %d", &advance))
8476         ;
8477       else if (unformat (i, "table-index %d", &table_index))
8478         ;
8479       else
8480         break;
8481     }
8482
8483   if (table_index == ~0)
8484     {
8485       errmsg ("Table index required\n");
8486       return -99;
8487     }
8488
8489   if (is_add && match == 0)
8490     {
8491       errmsg ("Match value required\n");
8492       return -99;
8493     }
8494
8495   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8496
8497   mp->is_add = is_add;
8498   mp->table_index = ntohl (table_index);
8499   mp->hit_next_index = ntohl (hit_next_index);
8500   mp->opaque_index = ntohl (opaque_index);
8501   mp->advance = ntohl (advance);
8502   clib_memcpy (mp->match, match, vec_len (match));
8503   vec_free (match);
8504
8505   S;
8506   W;
8507   /* NOTREACHED */
8508 }
8509
8510 static int
8511 api_classify_set_interface_ip_table (vat_main_t * vam)
8512 {
8513   unformat_input_t *i = vam->input;
8514   vl_api_classify_set_interface_ip_table_t *mp;
8515   f64 timeout;
8516   u32 sw_if_index;
8517   int sw_if_index_set;
8518   u32 table_index = ~0;
8519   u8 is_ipv6 = 0;
8520
8521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8522     {
8523       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8524         sw_if_index_set = 1;
8525       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8526         sw_if_index_set = 1;
8527       else if (unformat (i, "table %d", &table_index))
8528         ;
8529       else
8530         {
8531           clib_warning ("parse error '%U'", format_unformat_error, i);
8532           return -99;
8533         }
8534     }
8535
8536   if (sw_if_index_set == 0)
8537     {
8538       errmsg ("missing interface name or sw_if_index\n");
8539       return -99;
8540     }
8541
8542
8543   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8544
8545   mp->sw_if_index = ntohl (sw_if_index);
8546   mp->table_index = ntohl (table_index);
8547   mp->is_ipv6 = is_ipv6;
8548
8549   S;
8550   W;
8551   /* NOTREACHED */
8552   return 0;
8553 }
8554
8555 static int
8556 api_classify_set_interface_l2_tables (vat_main_t * vam)
8557 {
8558   unformat_input_t *i = vam->input;
8559   vl_api_classify_set_interface_l2_tables_t *mp;
8560   f64 timeout;
8561   u32 sw_if_index;
8562   int sw_if_index_set;
8563   u32 ip4_table_index = ~0;
8564   u32 ip6_table_index = ~0;
8565   u32 other_table_index = ~0;
8566   u32 is_input = 1;
8567
8568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8569     {
8570       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8571         sw_if_index_set = 1;
8572       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8573         sw_if_index_set = 1;
8574       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8575         ;
8576       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8577         ;
8578       else if (unformat (i, "other-table %d", &other_table_index))
8579         ;
8580       else if (unformat (i, "is-input %d", &is_input))
8581         ;
8582       else
8583         {
8584           clib_warning ("parse error '%U'", format_unformat_error, i);
8585           return -99;
8586         }
8587     }
8588
8589   if (sw_if_index_set == 0)
8590     {
8591       errmsg ("missing interface name or sw_if_index\n");
8592       return -99;
8593     }
8594
8595
8596   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8597
8598   mp->sw_if_index = ntohl (sw_if_index);
8599   mp->ip4_table_index = ntohl (ip4_table_index);
8600   mp->ip6_table_index = ntohl (ip6_table_index);
8601   mp->other_table_index = ntohl (other_table_index);
8602   mp->is_input = (u8) is_input;
8603
8604   S;
8605   W;
8606   /* NOTREACHED */
8607   return 0;
8608 }
8609
8610 static int
8611 api_set_ipfix_exporter (vat_main_t * vam)
8612 {
8613   unformat_input_t *i = vam->input;
8614   vl_api_set_ipfix_exporter_t *mp;
8615   ip4_address_t collector_address;
8616   u8 collector_address_set = 0;
8617   u32 collector_port = ~0;
8618   ip4_address_t src_address;
8619   u8 src_address_set = 0;
8620   u32 vrf_id = ~0;
8621   u32 path_mtu = ~0;
8622   u32 template_interval = ~0;
8623   u8 udp_checksum = 0;
8624   f64 timeout;
8625
8626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8627     {
8628       if (unformat (i, "collector_address %U", unformat_ip4_address,
8629                     &collector_address))
8630         collector_address_set = 1;
8631       else if (unformat (i, "collector_port %d", &collector_port))
8632         ;
8633       else if (unformat (i, "src_address %U", unformat_ip4_address,
8634                          &src_address))
8635         src_address_set = 1;
8636       else if (unformat (i, "vrf_id %d", &vrf_id))
8637         ;
8638       else if (unformat (i, "path_mtu %d", &path_mtu))
8639         ;
8640       else if (unformat (i, "template_interval %d", &template_interval))
8641         ;
8642       else if (unformat (i, "udp_checksum"))
8643         udp_checksum = 1;
8644       else
8645         break;
8646     }
8647
8648   if (collector_address_set == 0)
8649     {
8650       errmsg ("collector_address required\n");
8651       return -99;
8652     }
8653
8654   if (src_address_set == 0)
8655     {
8656       errmsg ("src_address required\n");
8657       return -99;
8658     }
8659
8660   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
8661
8662   memcpy (mp->collector_address, collector_address.data,
8663           sizeof (collector_address.data));
8664   mp->collector_port = htons ((u16) collector_port);
8665   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8666   mp->vrf_id = htonl (vrf_id);
8667   mp->path_mtu = htonl (path_mtu);
8668   mp->template_interval = htonl (template_interval);
8669   mp->udp_checksum = udp_checksum;
8670
8671   S;
8672   W;
8673   /* NOTREACHED */
8674 }
8675
8676 static int
8677 api_set_ipfix_classify_stream (vat_main_t * vam)
8678 {
8679   unformat_input_t *i = vam->input;
8680   vl_api_set_ipfix_classify_stream_t *mp;
8681   u32 domain_id = 0;
8682   u32 src_port = UDP_DST_PORT_ipfix;
8683   f64 timeout;
8684
8685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8686     {
8687       if (unformat (i, "domain %d", &domain_id))
8688         ;
8689       else if (unformat (i, "src_port %d", &src_port))
8690         ;
8691       else
8692         {
8693           errmsg ("unknown input `%U'", format_unformat_error, i);
8694           return -99;
8695         }
8696     }
8697
8698   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
8699
8700   mp->domain_id = htonl (domain_id);
8701   mp->src_port = htons ((u16) src_port);
8702
8703   S;
8704   W;
8705   /* NOTREACHED */
8706 }
8707
8708 static int
8709 api_ipfix_classify_table_add_del (vat_main_t * vam)
8710 {
8711   unformat_input_t *i = vam->input;
8712   vl_api_ipfix_classify_table_add_del_t *mp;
8713   int is_add = -1;
8714   u32 classify_table_index = ~0;
8715   u8 ip_version = 0;
8716   u8 transport_protocol = 255;
8717   f64 timeout;
8718
8719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8720     {
8721       if (unformat (i, "add"))
8722         is_add = 1;
8723       else if (unformat (i, "del"))
8724         is_add = 0;
8725       else if (unformat (i, "table %d", &classify_table_index))
8726         ;
8727       else if (unformat (i, "ip4"))
8728         ip_version = 4;
8729       else if (unformat (i, "ip6"))
8730         ip_version = 6;
8731       else if (unformat (i, "tcp"))
8732         transport_protocol = 6;
8733       else if (unformat (i, "udp"))
8734         transport_protocol = 17;
8735       else
8736         {
8737           errmsg ("unknown input `%U'", format_unformat_error, i);
8738           return -99;
8739         }
8740     }
8741
8742   if (is_add == -1)
8743     {
8744       errmsg ("expecting: add|del");
8745       return -99;
8746     }
8747   if (classify_table_index == ~0)
8748     {
8749       errmsg ("classifier table not specified");
8750       return -99;
8751     }
8752   if (ip_version == 0)
8753     {
8754       errmsg ("IP version not specified");
8755       return -99;
8756     }
8757
8758   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
8759
8760   mp->is_add = is_add;
8761   mp->table_id = htonl (classify_table_index);
8762   mp->ip_version = ip_version;
8763   mp->transport_protocol = transport_protocol;
8764
8765   S;
8766   W;
8767   /* NOTREACHED */
8768 }
8769
8770 static int
8771 api_get_node_index (vat_main_t * vam)
8772 {
8773   unformat_input_t *i = vam->input;
8774   vl_api_get_node_index_t *mp;
8775   f64 timeout;
8776   u8 *name = 0;
8777
8778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8779     {
8780       if (unformat (i, "node %s", &name))
8781         ;
8782       else
8783         break;
8784     }
8785   if (name == 0)
8786     {
8787       errmsg ("node name required\n");
8788       return -99;
8789     }
8790   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8791     {
8792       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8793       return -99;
8794     }
8795
8796   M (GET_NODE_INDEX, get_node_index);
8797   clib_memcpy (mp->node_name, name, vec_len (name));
8798   vec_free (name);
8799
8800   S;
8801   W;
8802   /* NOTREACHED */
8803   return 0;
8804 }
8805
8806 static int
8807 api_get_next_index (vat_main_t * vam)
8808 {
8809   unformat_input_t *i = vam->input;
8810   vl_api_get_next_index_t *mp;
8811   f64 timeout;
8812   u8 *node_name = 0, *next_node_name = 0;
8813
8814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8815     {
8816       if (unformat (i, "node-name %s", &node_name))
8817         ;
8818       else if (unformat (i, "next-node-name %s", &next_node_name))
8819         break;
8820     }
8821
8822   if (node_name == 0)
8823     {
8824       errmsg ("node name required\n");
8825       return -99;
8826     }
8827   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
8828     {
8829       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8830       return -99;
8831     }
8832
8833   if (next_node_name == 0)
8834     {
8835       errmsg ("next node name required\n");
8836       return -99;
8837     }
8838   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
8839     {
8840       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
8841       return -99;
8842     }
8843
8844   M (GET_NEXT_INDEX, get_next_index);
8845   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
8846   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
8847   vec_free (node_name);
8848   vec_free (next_node_name);
8849
8850   S;
8851   W;
8852   /* NOTREACHED */
8853   return 0;
8854 }
8855
8856 static int
8857 api_add_node_next (vat_main_t * vam)
8858 {
8859   unformat_input_t *i = vam->input;
8860   vl_api_add_node_next_t *mp;
8861   f64 timeout;
8862   u8 *name = 0;
8863   u8 *next = 0;
8864
8865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8866     {
8867       if (unformat (i, "node %s", &name))
8868         ;
8869       else if (unformat (i, "next %s", &next))
8870         ;
8871       else
8872         break;
8873     }
8874   if (name == 0)
8875     {
8876       errmsg ("node name required\n");
8877       return -99;
8878     }
8879   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8880     {
8881       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8882       return -99;
8883     }
8884   if (next == 0)
8885     {
8886       errmsg ("next node required\n");
8887       return -99;
8888     }
8889   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
8890     {
8891       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
8892       return -99;
8893     }
8894
8895   M (ADD_NODE_NEXT, add_node_next);
8896   clib_memcpy (mp->node_name, name, vec_len (name));
8897   clib_memcpy (mp->next_name, next, vec_len (next));
8898   vec_free (name);
8899   vec_free (next);
8900
8901   S;
8902   W;
8903   /* NOTREACHED */
8904   return 0;
8905 }
8906
8907 static int
8908 api_l2tpv3_create_tunnel (vat_main_t * vam)
8909 {
8910   unformat_input_t *i = vam->input;
8911   ip6_address_t client_address, our_address;
8912   int client_address_set = 0;
8913   int our_address_set = 0;
8914   u32 local_session_id = 0;
8915   u32 remote_session_id = 0;
8916   u64 local_cookie = 0;
8917   u64 remote_cookie = 0;
8918   u8 l2_sublayer_present = 0;
8919   vl_api_l2tpv3_create_tunnel_t *mp;
8920   f64 timeout;
8921
8922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8923     {
8924       if (unformat (i, "client_address %U", unformat_ip6_address,
8925                     &client_address))
8926         client_address_set = 1;
8927       else if (unformat (i, "our_address %U", unformat_ip6_address,
8928                          &our_address))
8929         our_address_set = 1;
8930       else if (unformat (i, "local_session_id %d", &local_session_id))
8931         ;
8932       else if (unformat (i, "remote_session_id %d", &remote_session_id))
8933         ;
8934       else if (unformat (i, "local_cookie %lld", &local_cookie))
8935         ;
8936       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
8937         ;
8938       else if (unformat (i, "l2-sublayer-present"))
8939         l2_sublayer_present = 1;
8940       else
8941         break;
8942     }
8943
8944   if (client_address_set == 0)
8945     {
8946       errmsg ("client_address required\n");
8947       return -99;
8948     }
8949
8950   if (our_address_set == 0)
8951     {
8952       errmsg ("our_address required\n");
8953       return -99;
8954     }
8955
8956   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
8957
8958   clib_memcpy (mp->client_address, client_address.as_u8,
8959                sizeof (mp->client_address));
8960
8961   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
8962
8963   mp->local_session_id = ntohl (local_session_id);
8964   mp->remote_session_id = ntohl (remote_session_id);
8965   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
8966   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
8967   mp->l2_sublayer_present = l2_sublayer_present;
8968   mp->is_ipv6 = 1;
8969
8970   S;
8971   W;
8972   /* NOTREACHED */
8973   return 0;
8974 }
8975
8976 static int
8977 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
8978 {
8979   unformat_input_t *i = vam->input;
8980   u32 sw_if_index;
8981   u8 sw_if_index_set = 0;
8982   u64 new_local_cookie = 0;
8983   u64 new_remote_cookie = 0;
8984   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
8985   f64 timeout;
8986
8987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8988     {
8989       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8990         sw_if_index_set = 1;
8991       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8992         sw_if_index_set = 1;
8993       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
8994         ;
8995       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
8996         ;
8997       else
8998         break;
8999     }
9000
9001   if (sw_if_index_set == 0)
9002     {
9003       errmsg ("missing interface name or sw_if_index\n");
9004       return -99;
9005     }
9006
9007   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9008
9009   mp->sw_if_index = ntohl (sw_if_index);
9010   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9011   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9012
9013   S;
9014   W;
9015   /* NOTREACHED */
9016   return 0;
9017 }
9018
9019 static int
9020 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9021 {
9022   unformat_input_t *i = vam->input;
9023   vl_api_l2tpv3_interface_enable_disable_t *mp;
9024   f64 timeout;
9025   u32 sw_if_index;
9026   u8 sw_if_index_set = 0;
9027   u8 enable_disable = 1;
9028
9029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9030     {
9031       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9032         sw_if_index_set = 1;
9033       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9034         sw_if_index_set = 1;
9035       else if (unformat (i, "enable"))
9036         enable_disable = 1;
9037       else if (unformat (i, "disable"))
9038         enable_disable = 0;
9039       else
9040         break;
9041     }
9042
9043   if (sw_if_index_set == 0)
9044     {
9045       errmsg ("missing interface name or sw_if_index\n");
9046       return -99;
9047     }
9048
9049   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9050
9051   mp->sw_if_index = ntohl (sw_if_index);
9052   mp->enable_disable = enable_disable;
9053
9054   S;
9055   W;
9056   /* NOTREACHED */
9057   return 0;
9058 }
9059
9060 static int
9061 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9062 {
9063   unformat_input_t *i = vam->input;
9064   vl_api_l2tpv3_set_lookup_key_t *mp;
9065   f64 timeout;
9066   u8 key = ~0;
9067
9068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9069     {
9070       if (unformat (i, "lookup_v6_src"))
9071         key = L2T_LOOKUP_SRC_ADDRESS;
9072       else if (unformat (i, "lookup_v6_dst"))
9073         key = L2T_LOOKUP_DST_ADDRESS;
9074       else if (unformat (i, "lookup_session_id"))
9075         key = L2T_LOOKUP_SESSION_ID;
9076       else
9077         break;
9078     }
9079
9080   if (key == (u8) ~ 0)
9081     {
9082       errmsg ("l2tp session lookup key unset\n");
9083       return -99;
9084     }
9085
9086   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9087
9088   mp->key = key;
9089
9090   S;
9091   W;
9092   /* NOTREACHED */
9093   return 0;
9094 }
9095
9096 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9097   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9098 {
9099   vat_main_t *vam = &vat_main;
9100
9101   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9102            format_ip6_address, mp->our_address,
9103            format_ip6_address, mp->client_address,
9104            clib_net_to_host_u32 (mp->sw_if_index));
9105
9106   fformat (vam->ofp,
9107            "   local cookies %016llx %016llx remote cookie %016llx\n",
9108            clib_net_to_host_u64 (mp->local_cookie[0]),
9109            clib_net_to_host_u64 (mp->local_cookie[1]),
9110            clib_net_to_host_u64 (mp->remote_cookie));
9111
9112   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9113            clib_net_to_host_u32 (mp->local_session_id),
9114            clib_net_to_host_u32 (mp->remote_session_id));
9115
9116   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9117            mp->l2_sublayer_present ? "preset" : "absent");
9118
9119 }
9120
9121 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9122   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9123 {
9124   vat_main_t *vam = &vat_main;
9125   vat_json_node_t *node = NULL;
9126   struct in6_addr addr;
9127
9128   if (VAT_JSON_ARRAY != vam->json_tree.type)
9129     {
9130       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9131       vat_json_init_array (&vam->json_tree);
9132     }
9133   node = vat_json_array_add (&vam->json_tree);
9134
9135   vat_json_init_object (node);
9136
9137   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9138   vat_json_object_add_ip6 (node, "our_address", addr);
9139   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9140   vat_json_object_add_ip6 (node, "client_address", addr);
9141
9142   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9143   vat_json_init_array (lc);
9144   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9145   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9146   vat_json_object_add_uint (node, "remote_cookie",
9147                             clib_net_to_host_u64 (mp->remote_cookie));
9148
9149   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9150   vat_json_object_add_uint (node, "local_session_id",
9151                             clib_net_to_host_u32 (mp->local_session_id));
9152   vat_json_object_add_uint (node, "remote_session_id",
9153                             clib_net_to_host_u32 (mp->remote_session_id));
9154   vat_json_object_add_string_copy (node, "l2_sublayer",
9155                                    mp->l2_sublayer_present ? (u8 *) "present"
9156                                    : (u8 *) "absent");
9157 }
9158
9159 static int
9160 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9161 {
9162   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9163   f64 timeout;
9164
9165   /* Get list of l2tpv3-tunnel interfaces */
9166   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9167   S;
9168
9169   /* Use a control ping for synchronization */
9170   {
9171     vl_api_control_ping_t *mp;
9172     M (CONTROL_PING, control_ping);
9173     S;
9174   }
9175   W;
9176 }
9177
9178
9179 static void vl_api_sw_interface_tap_details_t_handler
9180   (vl_api_sw_interface_tap_details_t * mp)
9181 {
9182   vat_main_t *vam = &vat_main;
9183
9184   fformat (vam->ofp, "%-16s %d\n",
9185            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9186 }
9187
9188 static void vl_api_sw_interface_tap_details_t_handler_json
9189   (vl_api_sw_interface_tap_details_t * mp)
9190 {
9191   vat_main_t *vam = &vat_main;
9192   vat_json_node_t *node = NULL;
9193
9194   if (VAT_JSON_ARRAY != vam->json_tree.type)
9195     {
9196       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9197       vat_json_init_array (&vam->json_tree);
9198     }
9199   node = vat_json_array_add (&vam->json_tree);
9200
9201   vat_json_init_object (node);
9202   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9203   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9204 }
9205
9206 static int
9207 api_sw_interface_tap_dump (vat_main_t * vam)
9208 {
9209   vl_api_sw_interface_tap_dump_t *mp;
9210   f64 timeout;
9211
9212   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9213   /* Get list of tap interfaces */
9214   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9215   S;
9216
9217   /* Use a control ping for synchronization */
9218   {
9219     vl_api_control_ping_t *mp;
9220     M (CONTROL_PING, control_ping);
9221     S;
9222   }
9223   W;
9224 }
9225
9226 static uword unformat_vxlan_decap_next
9227   (unformat_input_t * input, va_list * args)
9228 {
9229   u32 *result = va_arg (*args, u32 *);
9230   u32 tmp;
9231
9232   if (unformat (input, "drop"))
9233     *result = VXLAN_INPUT_NEXT_DROP;
9234   else if (unformat (input, "ip4"))
9235     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9236   else if (unformat (input, "ip6"))
9237     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9238   else if (unformat (input, "l2"))
9239     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9240   else if (unformat (input, "%d", &tmp))
9241     *result = tmp;
9242   else
9243     return 0;
9244   return 1;
9245 }
9246
9247 static int
9248 api_vxlan_add_del_tunnel (vat_main_t * vam)
9249 {
9250   unformat_input_t *line_input = vam->input;
9251   vl_api_vxlan_add_del_tunnel_t *mp;
9252   f64 timeout;
9253   ip4_address_t src4, dst4;
9254   ip6_address_t src6, dst6;
9255   u8 is_add = 1;
9256   u8 ipv4_set = 0, ipv6_set = 0;
9257   u8 src_set = 0;
9258   u8 dst_set = 0;
9259   u32 encap_vrf_id = 0;
9260   u32 decap_next_index = ~0;
9261   u32 vni = 0;
9262
9263   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9264     {
9265       if (unformat (line_input, "del"))
9266         is_add = 0;
9267       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9268         {
9269           ipv4_set = 1;
9270           src_set = 1;
9271         }
9272       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9273         {
9274           ipv4_set = 1;
9275           dst_set = 1;
9276         }
9277       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9278         {
9279           ipv6_set = 1;
9280           src_set = 1;
9281         }
9282       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9283         {
9284           ipv6_set = 1;
9285           dst_set = 1;
9286         }
9287       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9288         ;
9289       else if (unformat (line_input, "decap-next %U",
9290                          unformat_vxlan_decap_next, &decap_next_index))
9291         ;
9292       else if (unformat (line_input, "vni %d", &vni))
9293         ;
9294       else
9295         {
9296           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9297           return -99;
9298         }
9299     }
9300
9301   if (src_set == 0)
9302     {
9303       errmsg ("tunnel src address not specified\n");
9304       return -99;
9305     }
9306   if (dst_set == 0)
9307     {
9308       errmsg ("tunnel dst address not specified\n");
9309       return -99;
9310     }
9311
9312   if (ipv4_set && ipv6_set)
9313     {
9314       errmsg ("both IPv4 and IPv6 addresses specified");
9315       return -99;
9316     }
9317
9318   if ((vni == 0) || (vni >> 24))
9319     {
9320       errmsg ("vni not specified or out of range\n");
9321       return -99;
9322     }
9323
9324   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9325
9326   if (ipv6_set)
9327     {
9328       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9329       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9330     }
9331   else
9332     {
9333       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9334       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9335     }
9336   mp->encap_vrf_id = ntohl (encap_vrf_id);
9337   mp->decap_next_index = ntohl (decap_next_index);
9338   mp->vni = ntohl (vni);
9339   mp->is_add = is_add;
9340   mp->is_ipv6 = ipv6_set;
9341
9342   S;
9343   W;
9344   /* NOTREACHED */
9345   return 0;
9346 }
9347
9348 static void vl_api_vxlan_tunnel_details_t_handler
9349   (vl_api_vxlan_tunnel_details_t * mp)
9350 {
9351   vat_main_t *vam = &vat_main;
9352
9353   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9354            ntohl (mp->sw_if_index),
9355            format_ip46_address, &(mp->src_address[0]),
9356            IP46_TYPE_ANY,
9357            format_ip46_address, &(mp->dst_address[0]),
9358            IP46_TYPE_ANY,
9359            ntohl (mp->encap_vrf_id),
9360            ntohl (mp->decap_next_index), ntohl (mp->vni));
9361 }
9362
9363 static void vl_api_vxlan_tunnel_details_t_handler_json
9364   (vl_api_vxlan_tunnel_details_t * mp)
9365 {
9366   vat_main_t *vam = &vat_main;
9367   vat_json_node_t *node = NULL;
9368   struct in_addr ip4;
9369   struct in6_addr ip6;
9370
9371   if (VAT_JSON_ARRAY != vam->json_tree.type)
9372     {
9373       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9374       vat_json_init_array (&vam->json_tree);
9375     }
9376   node = vat_json_array_add (&vam->json_tree);
9377
9378   vat_json_init_object (node);
9379   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9380   if (mp->is_ipv6)
9381     {
9382       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9383       vat_json_object_add_ip6 (node, "src_address", ip6);
9384       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9385       vat_json_object_add_ip6 (node, "dst_address", ip6);
9386     }
9387   else
9388     {
9389       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9390       vat_json_object_add_ip4 (node, "src_address", ip4);
9391       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9392       vat_json_object_add_ip4 (node, "dst_address", ip4);
9393     }
9394   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9395   vat_json_object_add_uint (node, "decap_next_index",
9396                             ntohl (mp->decap_next_index));
9397   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9398   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9399 }
9400
9401 static int
9402 api_vxlan_tunnel_dump (vat_main_t * vam)
9403 {
9404   unformat_input_t *i = vam->input;
9405   vl_api_vxlan_tunnel_dump_t *mp;
9406   f64 timeout;
9407   u32 sw_if_index;
9408   u8 sw_if_index_set = 0;
9409
9410   /* Parse args required to build the message */
9411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9412     {
9413       if (unformat (i, "sw_if_index %d", &sw_if_index))
9414         sw_if_index_set = 1;
9415       else
9416         break;
9417     }
9418
9419   if (sw_if_index_set == 0)
9420     {
9421       sw_if_index = ~0;
9422     }
9423
9424   if (!vam->json_output)
9425     {
9426       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9427                "sw_if_index", "src_address", "dst_address",
9428                "encap_vrf_id", "decap_next_index", "vni");
9429     }
9430
9431   /* Get list of vxlan-tunnel interfaces */
9432   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9433
9434   mp->sw_if_index = htonl (sw_if_index);
9435
9436   S;
9437
9438   /* Use a control ping for synchronization */
9439   {
9440     vl_api_control_ping_t *mp;
9441     M (CONTROL_PING, control_ping);
9442     S;
9443   }
9444   W;
9445 }
9446
9447 static int
9448 api_gre_add_del_tunnel (vat_main_t * vam)
9449 {
9450   unformat_input_t *line_input = vam->input;
9451   vl_api_gre_add_del_tunnel_t *mp;
9452   f64 timeout;
9453   ip4_address_t src4, dst4;
9454   u8 is_add = 1;
9455   u8 teb = 0;
9456   u8 src_set = 0;
9457   u8 dst_set = 0;
9458   u32 outer_fib_id = 0;
9459
9460   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9461     {
9462       if (unformat (line_input, "del"))
9463         is_add = 0;
9464       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9465         src_set = 1;
9466       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9467         dst_set = 1;
9468       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9469         ;
9470       else if (unformat (line_input, "teb"))
9471         teb = 1;
9472       else
9473         {
9474           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9475           return -99;
9476         }
9477     }
9478
9479   if (src_set == 0)
9480     {
9481       errmsg ("tunnel src address not specified\n");
9482       return -99;
9483     }
9484   if (dst_set == 0)
9485     {
9486       errmsg ("tunnel dst address not specified\n");
9487       return -99;
9488     }
9489
9490
9491   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9492
9493   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9494   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9495   mp->outer_fib_id = ntohl (outer_fib_id);
9496   mp->is_add = is_add;
9497   mp->teb = teb;
9498
9499   S;
9500   W;
9501   /* NOTREACHED */
9502   return 0;
9503 }
9504
9505 static void vl_api_gre_tunnel_details_t_handler
9506   (vl_api_gre_tunnel_details_t * mp)
9507 {
9508   vat_main_t *vam = &vat_main;
9509
9510   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
9511            ntohl (mp->sw_if_index),
9512            format_ip4_address, &mp->src_address,
9513            format_ip4_address, &mp->dst_address,
9514            mp->teb, ntohl (mp->outer_fib_id));
9515 }
9516
9517 static void vl_api_gre_tunnel_details_t_handler_json
9518   (vl_api_gre_tunnel_details_t * mp)
9519 {
9520   vat_main_t *vam = &vat_main;
9521   vat_json_node_t *node = NULL;
9522   struct in_addr ip4;
9523
9524   if (VAT_JSON_ARRAY != vam->json_tree.type)
9525     {
9526       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9527       vat_json_init_array (&vam->json_tree);
9528     }
9529   node = vat_json_array_add (&vam->json_tree);
9530
9531   vat_json_init_object (node);
9532   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9533   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9534   vat_json_object_add_ip4 (node, "src_address", ip4);
9535   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9536   vat_json_object_add_ip4 (node, "dst_address", ip4);
9537   vat_json_object_add_uint (node, "teb", mp->teb);
9538   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9539 }
9540
9541 static int
9542 api_gre_tunnel_dump (vat_main_t * vam)
9543 {
9544   unformat_input_t *i = vam->input;
9545   vl_api_gre_tunnel_dump_t *mp;
9546   f64 timeout;
9547   u32 sw_if_index;
9548   u8 sw_if_index_set = 0;
9549
9550   /* Parse args required to build the message */
9551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9552     {
9553       if (unformat (i, "sw_if_index %d", &sw_if_index))
9554         sw_if_index_set = 1;
9555       else
9556         break;
9557     }
9558
9559   if (sw_if_index_set == 0)
9560     {
9561       sw_if_index = ~0;
9562     }
9563
9564   if (!vam->json_output)
9565     {
9566       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
9567                "sw_if_index", "src_address", "dst_address", "teb",
9568                "outer_fib_id");
9569     }
9570
9571   /* Get list of gre-tunnel interfaces */
9572   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9573
9574   mp->sw_if_index = htonl (sw_if_index);
9575
9576   S;
9577
9578   /* Use a control ping for synchronization */
9579   {
9580     vl_api_control_ping_t *mp;
9581     M (CONTROL_PING, control_ping);
9582     S;
9583   }
9584   W;
9585 }
9586
9587 static int
9588 api_l2_fib_clear_table (vat_main_t * vam)
9589 {
9590 //  unformat_input_t * i = vam->input;
9591   vl_api_l2_fib_clear_table_t *mp;
9592   f64 timeout;
9593
9594   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9595
9596   S;
9597   W;
9598   /* NOTREACHED */
9599   return 0;
9600 }
9601
9602 static int
9603 api_l2_interface_efp_filter (vat_main_t * vam)
9604 {
9605   unformat_input_t *i = vam->input;
9606   vl_api_l2_interface_efp_filter_t *mp;
9607   f64 timeout;
9608   u32 sw_if_index;
9609   u8 enable = 1;
9610   u8 sw_if_index_set = 0;
9611
9612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9613     {
9614       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9615         sw_if_index_set = 1;
9616       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9617         sw_if_index_set = 1;
9618       else if (unformat (i, "enable"))
9619         enable = 1;
9620       else if (unformat (i, "disable"))
9621         enable = 0;
9622       else
9623         {
9624           clib_warning ("parse error '%U'", format_unformat_error, i);
9625           return -99;
9626         }
9627     }
9628
9629   if (sw_if_index_set == 0)
9630     {
9631       errmsg ("missing sw_if_index\n");
9632       return -99;
9633     }
9634
9635   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9636
9637   mp->sw_if_index = ntohl (sw_if_index);
9638   mp->enable_disable = enable;
9639
9640   S;
9641   W;
9642   /* NOTREACHED */
9643   return 0;
9644 }
9645
9646 #define foreach_vtr_op                          \
9647 _("disable",  L2_VTR_DISABLED)                  \
9648 _("push-1",  L2_VTR_PUSH_1)                     \
9649 _("push-2",  L2_VTR_PUSH_2)                     \
9650 _("pop-1",  L2_VTR_POP_1)                       \
9651 _("pop-2",  L2_VTR_POP_2)                       \
9652 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9653 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9654 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9655 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9656
9657 static int
9658 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9659 {
9660   unformat_input_t *i = vam->input;
9661   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9662   f64 timeout;
9663   u32 sw_if_index;
9664   u8 sw_if_index_set = 0;
9665   u8 vtr_op_set = 0;
9666   u32 vtr_op = 0;
9667   u32 push_dot1q = 1;
9668   u32 tag1 = ~0;
9669   u32 tag2 = ~0;
9670
9671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9672     {
9673       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9674         sw_if_index_set = 1;
9675       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9676         sw_if_index_set = 1;
9677       else if (unformat (i, "vtr_op %d", &vtr_op))
9678         vtr_op_set = 1;
9679 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9680       foreach_vtr_op
9681 #undef _
9682         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9683         ;
9684       else if (unformat (i, "tag1 %d", &tag1))
9685         ;
9686       else if (unformat (i, "tag2 %d", &tag2))
9687         ;
9688       else
9689         {
9690           clib_warning ("parse error '%U'", format_unformat_error, i);
9691           return -99;
9692         }
9693     }
9694
9695   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9696     {
9697       errmsg ("missing vtr operation or sw_if_index\n");
9698       return -99;
9699     }
9700
9701   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
9702     mp->sw_if_index = ntohl (sw_if_index);
9703   mp->vtr_op = ntohl (vtr_op);
9704   mp->push_dot1q = ntohl (push_dot1q);
9705   mp->tag1 = ntohl (tag1);
9706   mp->tag2 = ntohl (tag2);
9707
9708   S;
9709   W;
9710   /* NOTREACHED */
9711   return 0;
9712 }
9713
9714 static int
9715 api_create_vhost_user_if (vat_main_t * vam)
9716 {
9717   unformat_input_t *i = vam->input;
9718   vl_api_create_vhost_user_if_t *mp;
9719   f64 timeout;
9720   u8 *file_name;
9721   u8 is_server = 0;
9722   u8 file_name_set = 0;
9723   u32 custom_dev_instance = ~0;
9724   u8 hwaddr[6];
9725   u8 use_custom_mac = 0;
9726
9727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9728     {
9729       if (unformat (i, "socket %s", &file_name))
9730         {
9731           file_name_set = 1;
9732         }
9733       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9734         ;
9735       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9736         use_custom_mac = 1;
9737       else if (unformat (i, "server"))
9738         is_server = 1;
9739       else
9740         break;
9741     }
9742
9743   if (file_name_set == 0)
9744     {
9745       errmsg ("missing socket file name\n");
9746       return -99;
9747     }
9748
9749   if (vec_len (file_name) > 255)
9750     {
9751       errmsg ("socket file name too long\n");
9752       return -99;
9753     }
9754   vec_add1 (file_name, 0);
9755
9756   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
9757
9758   mp->is_server = is_server;
9759   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9760   vec_free (file_name);
9761   if (custom_dev_instance != ~0)
9762     {
9763       mp->renumber = 1;
9764       mp->custom_dev_instance = ntohl (custom_dev_instance);
9765     }
9766   mp->use_custom_mac = use_custom_mac;
9767   clib_memcpy (mp->mac_address, hwaddr, 6);
9768
9769   S;
9770   W;
9771   /* NOTREACHED */
9772   return 0;
9773 }
9774
9775 static int
9776 api_modify_vhost_user_if (vat_main_t * vam)
9777 {
9778   unformat_input_t *i = vam->input;
9779   vl_api_modify_vhost_user_if_t *mp;
9780   f64 timeout;
9781   u8 *file_name;
9782   u8 is_server = 0;
9783   u8 file_name_set = 0;
9784   u32 custom_dev_instance = ~0;
9785   u8 sw_if_index_set = 0;
9786   u32 sw_if_index = (u32) ~ 0;
9787
9788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9789     {
9790       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9791         sw_if_index_set = 1;
9792       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9793         sw_if_index_set = 1;
9794       else if (unformat (i, "socket %s", &file_name))
9795         {
9796           file_name_set = 1;
9797         }
9798       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9799         ;
9800       else if (unformat (i, "server"))
9801         is_server = 1;
9802       else
9803         break;
9804     }
9805
9806   if (sw_if_index_set == 0)
9807     {
9808       errmsg ("missing sw_if_index or interface name\n");
9809       return -99;
9810     }
9811
9812   if (file_name_set == 0)
9813     {
9814       errmsg ("missing socket file name\n");
9815       return -99;
9816     }
9817
9818   if (vec_len (file_name) > 255)
9819     {
9820       errmsg ("socket file name too long\n");
9821       return -99;
9822     }
9823   vec_add1 (file_name, 0);
9824
9825   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
9826
9827   mp->sw_if_index = ntohl (sw_if_index);
9828   mp->is_server = is_server;
9829   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9830   vec_free (file_name);
9831   if (custom_dev_instance != ~0)
9832     {
9833       mp->renumber = 1;
9834       mp->custom_dev_instance = ntohl (custom_dev_instance);
9835     }
9836
9837   S;
9838   W;
9839   /* NOTREACHED */
9840   return 0;
9841 }
9842
9843 static int
9844 api_delete_vhost_user_if (vat_main_t * vam)
9845 {
9846   unformat_input_t *i = vam->input;
9847   vl_api_delete_vhost_user_if_t *mp;
9848   f64 timeout;
9849   u32 sw_if_index = ~0;
9850   u8 sw_if_index_set = 0;
9851
9852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9853     {
9854       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9855         sw_if_index_set = 1;
9856       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9857         sw_if_index_set = 1;
9858       else
9859         break;
9860     }
9861
9862   if (sw_if_index_set == 0)
9863     {
9864       errmsg ("missing sw_if_index or interface name\n");
9865       return -99;
9866     }
9867
9868
9869   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
9870
9871   mp->sw_if_index = ntohl (sw_if_index);
9872
9873   S;
9874   W;
9875   /* NOTREACHED */
9876   return 0;
9877 }
9878
9879 static void vl_api_sw_interface_vhost_user_details_t_handler
9880   (vl_api_sw_interface_vhost_user_details_t * mp)
9881 {
9882   vat_main_t *vam = &vat_main;
9883
9884   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
9885            (char *) mp->interface_name,
9886            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
9887            clib_net_to_host_u64 (mp->features), mp->is_server,
9888            ntohl (mp->num_regions), (char *) mp->sock_filename);
9889   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
9890 }
9891
9892 static void vl_api_sw_interface_vhost_user_details_t_handler_json
9893   (vl_api_sw_interface_vhost_user_details_t * mp)
9894 {
9895   vat_main_t *vam = &vat_main;
9896   vat_json_node_t *node = NULL;
9897
9898   if (VAT_JSON_ARRAY != vam->json_tree.type)
9899     {
9900       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9901       vat_json_init_array (&vam->json_tree);
9902     }
9903   node = vat_json_array_add (&vam->json_tree);
9904
9905   vat_json_init_object (node);
9906   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9907   vat_json_object_add_string_copy (node, "interface_name",
9908                                    mp->interface_name);
9909   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
9910                             ntohl (mp->virtio_net_hdr_sz));
9911   vat_json_object_add_uint (node, "features",
9912                             clib_net_to_host_u64 (mp->features));
9913   vat_json_object_add_uint (node, "is_server", mp->is_server);
9914   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
9915   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
9916   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
9917 }
9918
9919 static int
9920 api_sw_interface_vhost_user_dump (vat_main_t * vam)
9921 {
9922   vl_api_sw_interface_vhost_user_dump_t *mp;
9923   f64 timeout;
9924   fformat (vam->ofp,
9925            "Interface name           idx hdr_sz features server regions filename\n");
9926
9927   /* Get list of vhost-user interfaces */
9928   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
9929   S;
9930
9931   /* Use a control ping for synchronization */
9932   {
9933     vl_api_control_ping_t *mp;
9934     M (CONTROL_PING, control_ping);
9935     S;
9936   }
9937   W;
9938 }
9939
9940 static int
9941 api_show_version (vat_main_t * vam)
9942 {
9943   vl_api_show_version_t *mp;
9944   f64 timeout;
9945
9946   M (SHOW_VERSION, show_version);
9947
9948   S;
9949   W;
9950   /* NOTREACHED */
9951   return 0;
9952 }
9953
9954
9955 static int
9956 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
9957 {
9958   unformat_input_t *line_input = vam->input;
9959   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
9960   f64 timeout;
9961   ip4_address_t local4, remote4;
9962   ip6_address_t local6, remote6;
9963   u8 is_add = 1;
9964   u8 ipv4_set = 0, ipv6_set = 0;
9965   u8 local_set = 0;
9966   u8 remote_set = 0;
9967   u32 encap_vrf_id = 0;
9968   u32 decap_vrf_id = 0;
9969   u8 protocol = ~0;
9970   u32 vni;
9971   u8 vni_set = 0;
9972
9973   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9974     {
9975       if (unformat (line_input, "del"))
9976         is_add = 0;
9977       else if (unformat (line_input, "local %U",
9978                          unformat_ip4_address, &local4))
9979         {
9980           local_set = 1;
9981           ipv4_set = 1;
9982         }
9983       else if (unformat (line_input, "remote %U",
9984                          unformat_ip4_address, &remote4))
9985         {
9986           remote_set = 1;
9987           ipv4_set = 1;
9988         }
9989       else if (unformat (line_input, "local %U",
9990                          unformat_ip6_address, &local6))
9991         {
9992           local_set = 1;
9993           ipv6_set = 1;
9994         }
9995       else if (unformat (line_input, "remote %U",
9996                          unformat_ip6_address, &remote6))
9997         {
9998           remote_set = 1;
9999           ipv6_set = 1;
10000         }
10001       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10002         ;
10003       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10004         ;
10005       else if (unformat (line_input, "vni %d", &vni))
10006         vni_set = 1;
10007       else if (unformat (line_input, "next-ip4"))
10008         protocol = 1;
10009       else if (unformat (line_input, "next-ip6"))
10010         protocol = 2;
10011       else if (unformat (line_input, "next-ethernet"))
10012         protocol = 3;
10013       else if (unformat (line_input, "next-nsh"))
10014         protocol = 4;
10015       else
10016         {
10017           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10018           return -99;
10019         }
10020     }
10021
10022   if (local_set == 0)
10023     {
10024       errmsg ("tunnel local address not specified\n");
10025       return -99;
10026     }
10027   if (remote_set == 0)
10028     {
10029       errmsg ("tunnel remote address not specified\n");
10030       return -99;
10031     }
10032   if (ipv4_set && ipv6_set)
10033     {
10034       errmsg ("both IPv4 and IPv6 addresses specified");
10035       return -99;
10036     }
10037
10038   if (vni_set == 0)
10039     {
10040       errmsg ("vni not specified\n");
10041       return -99;
10042     }
10043
10044   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10045
10046
10047   if (ipv6_set)
10048     {
10049       clib_memcpy (&mp->local, &local6, sizeof (local6));
10050       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10051     }
10052   else
10053     {
10054       clib_memcpy (&mp->local, &local4, sizeof (local4));
10055       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10056     }
10057
10058   mp->encap_vrf_id = ntohl (encap_vrf_id);
10059   mp->decap_vrf_id = ntohl (decap_vrf_id);
10060   mp->protocol = ntohl (protocol);
10061   mp->vni = ntohl (vni);
10062   mp->is_add = is_add;
10063   mp->is_ipv6 = ipv6_set;
10064
10065   S;
10066   W;
10067   /* NOTREACHED */
10068   return 0;
10069 }
10070
10071 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10072   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10073 {
10074   vat_main_t *vam = &vat_main;
10075
10076   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10077            ntohl (mp->sw_if_index),
10078            format_ip46_address, &(mp->local[0]),
10079            format_ip46_address, &(mp->remote[0]),
10080            ntohl (mp->vni),
10081            ntohl (mp->protocol),
10082            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10083 }
10084
10085 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10086   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10087 {
10088   vat_main_t *vam = &vat_main;
10089   vat_json_node_t *node = NULL;
10090   struct in_addr ip4;
10091   struct in6_addr ip6;
10092
10093   if (VAT_JSON_ARRAY != vam->json_tree.type)
10094     {
10095       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10096       vat_json_init_array (&vam->json_tree);
10097     }
10098   node = vat_json_array_add (&vam->json_tree);
10099
10100   vat_json_init_object (node);
10101   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10102   if (mp->is_ipv6)
10103     {
10104       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10105       vat_json_object_add_ip6 (node, "local", ip6);
10106       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10107       vat_json_object_add_ip6 (node, "remote", ip6);
10108     }
10109   else
10110     {
10111       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10112       vat_json_object_add_ip4 (node, "local", ip4);
10113       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10114       vat_json_object_add_ip4 (node, "remote", ip4);
10115     }
10116   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10117   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10118   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10119   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10120   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10121 }
10122
10123 static int
10124 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10125 {
10126   unformat_input_t *i = vam->input;
10127   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10128   f64 timeout;
10129   u32 sw_if_index;
10130   u8 sw_if_index_set = 0;
10131
10132   /* Parse args required to build the message */
10133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10134     {
10135       if (unformat (i, "sw_if_index %d", &sw_if_index))
10136         sw_if_index_set = 1;
10137       else
10138         break;
10139     }
10140
10141   if (sw_if_index_set == 0)
10142     {
10143       sw_if_index = ~0;
10144     }
10145
10146   if (!vam->json_output)
10147     {
10148       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10149                "sw_if_index", "local", "remote", "vni",
10150                "protocol", "encap_vrf_id", "decap_vrf_id");
10151     }
10152
10153   /* Get list of vxlan-tunnel interfaces */
10154   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10155
10156   mp->sw_if_index = htonl (sw_if_index);
10157
10158   S;
10159
10160   /* Use a control ping for synchronization */
10161   {
10162     vl_api_control_ping_t *mp;
10163     M (CONTROL_PING, control_ping);
10164     S;
10165   }
10166   W;
10167 }
10168
10169 u8 *
10170 format_l2_fib_mac_address (u8 * s, va_list * args)
10171 {
10172   u8 *a = va_arg (*args, u8 *);
10173
10174   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10175                  a[2], a[3], a[4], a[5], a[6], a[7]);
10176 }
10177
10178 static void vl_api_l2_fib_table_entry_t_handler
10179   (vl_api_l2_fib_table_entry_t * mp)
10180 {
10181   vat_main_t *vam = &vat_main;
10182
10183   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10184            "       %d       %d     %d\n",
10185            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10186            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10187            mp->bvi_mac);
10188 }
10189
10190 static void vl_api_l2_fib_table_entry_t_handler_json
10191   (vl_api_l2_fib_table_entry_t * mp)
10192 {
10193   vat_main_t *vam = &vat_main;
10194   vat_json_node_t *node = NULL;
10195
10196   if (VAT_JSON_ARRAY != vam->json_tree.type)
10197     {
10198       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10199       vat_json_init_array (&vam->json_tree);
10200     }
10201   node = vat_json_array_add (&vam->json_tree);
10202
10203   vat_json_init_object (node);
10204   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10205   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10206   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10207   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10208   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10209   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10210 }
10211
10212 static int
10213 api_l2_fib_table_dump (vat_main_t * vam)
10214 {
10215   unformat_input_t *i = vam->input;
10216   vl_api_l2_fib_table_dump_t *mp;
10217   f64 timeout;
10218   u32 bd_id;
10219   u8 bd_id_set = 0;
10220
10221   /* Parse args required to build the message */
10222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10223     {
10224       if (unformat (i, "bd_id %d", &bd_id))
10225         bd_id_set = 1;
10226       else
10227         break;
10228     }
10229
10230   if (bd_id_set == 0)
10231     {
10232       errmsg ("missing bridge domain\n");
10233       return -99;
10234     }
10235
10236   fformat (vam->ofp,
10237            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10238
10239   /* Get list of l2 fib entries */
10240   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10241
10242   mp->bd_id = ntohl (bd_id);
10243   S;
10244
10245   /* Use a control ping for synchronization */
10246   {
10247     vl_api_control_ping_t *mp;
10248     M (CONTROL_PING, control_ping);
10249     S;
10250   }
10251   W;
10252 }
10253
10254
10255 static int
10256 api_interface_name_renumber (vat_main_t * vam)
10257 {
10258   unformat_input_t *line_input = vam->input;
10259   vl_api_interface_name_renumber_t *mp;
10260   u32 sw_if_index = ~0;
10261   f64 timeout;
10262   u32 new_show_dev_instance = ~0;
10263
10264   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10265     {
10266       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10267                     &sw_if_index))
10268         ;
10269       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10270         ;
10271       else if (unformat (line_input, "new_show_dev_instance %d",
10272                          &new_show_dev_instance))
10273         ;
10274       else
10275         break;
10276     }
10277
10278   if (sw_if_index == ~0)
10279     {
10280       errmsg ("missing interface name or sw_if_index\n");
10281       return -99;
10282     }
10283
10284   if (new_show_dev_instance == ~0)
10285     {
10286       errmsg ("missing new_show_dev_instance\n");
10287       return -99;
10288     }
10289
10290   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10291
10292   mp->sw_if_index = ntohl (sw_if_index);
10293   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10294
10295   S;
10296   W;
10297 }
10298
10299 static int
10300 api_want_ip4_arp_events (vat_main_t * vam)
10301 {
10302   unformat_input_t *line_input = vam->input;
10303   vl_api_want_ip4_arp_events_t *mp;
10304   f64 timeout;
10305   ip4_address_t address;
10306   int address_set = 0;
10307   u32 enable_disable = 1;
10308
10309   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10310     {
10311       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10312         address_set = 1;
10313       else if (unformat (line_input, "del"))
10314         enable_disable = 0;
10315       else
10316         break;
10317     }
10318
10319   if (address_set == 0)
10320     {
10321       errmsg ("missing addresses\n");
10322       return -99;
10323     }
10324
10325   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10326   mp->enable_disable = enable_disable;
10327   mp->pid = getpid ();
10328   mp->address = address.as_u32;
10329
10330   S;
10331   W;
10332 }
10333
10334 static int
10335 api_want_ip6_nd_events (vat_main_t * vam)
10336 {
10337   unformat_input_t *line_input = vam->input;
10338   vl_api_want_ip6_nd_events_t *mp;
10339   f64 timeout;
10340   ip6_address_t address;
10341   int address_set = 0;
10342   u32 enable_disable = 1;
10343
10344   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10345     {
10346       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
10347         address_set = 1;
10348       else if (unformat (line_input, "del"))
10349         enable_disable = 0;
10350       else
10351         break;
10352     }
10353
10354   if (address_set == 0)
10355     {
10356       errmsg ("missing addresses\n");
10357       return -99;
10358     }
10359
10360   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
10361   mp->enable_disable = enable_disable;
10362   mp->pid = getpid ();
10363   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
10364
10365   S;
10366   W;
10367 }
10368
10369 static int
10370 api_input_acl_set_interface (vat_main_t * vam)
10371 {
10372   unformat_input_t *i = vam->input;
10373   vl_api_input_acl_set_interface_t *mp;
10374   f64 timeout;
10375   u32 sw_if_index;
10376   int sw_if_index_set;
10377   u32 ip4_table_index = ~0;
10378   u32 ip6_table_index = ~0;
10379   u32 l2_table_index = ~0;
10380   u8 is_add = 1;
10381
10382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10383     {
10384       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10385         sw_if_index_set = 1;
10386       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10387         sw_if_index_set = 1;
10388       else if (unformat (i, "del"))
10389         is_add = 0;
10390       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10391         ;
10392       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10393         ;
10394       else if (unformat (i, "l2-table %d", &l2_table_index))
10395         ;
10396       else
10397         {
10398           clib_warning ("parse error '%U'", format_unformat_error, i);
10399           return -99;
10400         }
10401     }
10402
10403   if (sw_if_index_set == 0)
10404     {
10405       errmsg ("missing interface name or sw_if_index\n");
10406       return -99;
10407     }
10408
10409   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10410
10411   mp->sw_if_index = ntohl (sw_if_index);
10412   mp->ip4_table_index = ntohl (ip4_table_index);
10413   mp->ip6_table_index = ntohl (ip6_table_index);
10414   mp->l2_table_index = ntohl (l2_table_index);
10415   mp->is_add = is_add;
10416
10417   S;
10418   W;
10419   /* NOTREACHED */
10420   return 0;
10421 }
10422
10423 static int
10424 api_ip_address_dump (vat_main_t * vam)
10425 {
10426   unformat_input_t *i = vam->input;
10427   vl_api_ip_address_dump_t *mp;
10428   u32 sw_if_index = ~0;
10429   u8 sw_if_index_set = 0;
10430   u8 ipv4_set = 0;
10431   u8 ipv6_set = 0;
10432   f64 timeout;
10433
10434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10435     {
10436       if (unformat (i, "sw_if_index %d", &sw_if_index))
10437         sw_if_index_set = 1;
10438       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10439         sw_if_index_set = 1;
10440       else if (unformat (i, "ipv4"))
10441         ipv4_set = 1;
10442       else if (unformat (i, "ipv6"))
10443         ipv6_set = 1;
10444       else
10445         break;
10446     }
10447
10448   if (ipv4_set && ipv6_set)
10449     {
10450       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10451       return -99;
10452     }
10453
10454   if ((!ipv4_set) && (!ipv6_set))
10455     {
10456       errmsg ("no ipv4 nor ipv6 flag set\n");
10457       return -99;
10458     }
10459
10460   if (sw_if_index_set == 0)
10461     {
10462       errmsg ("missing interface name or sw_if_index\n");
10463       return -99;
10464     }
10465
10466   vam->current_sw_if_index = sw_if_index;
10467   vam->is_ipv6 = ipv6_set;
10468
10469   M (IP_ADDRESS_DUMP, ip_address_dump);
10470   mp->sw_if_index = ntohl (sw_if_index);
10471   mp->is_ipv6 = ipv6_set;
10472   S;
10473
10474   /* Use a control ping for synchronization */
10475   {
10476     vl_api_control_ping_t *mp;
10477     M (CONTROL_PING, control_ping);
10478     S;
10479   }
10480   W;
10481 }
10482
10483 static int
10484 api_ip_dump (vat_main_t * vam)
10485 {
10486   vl_api_ip_dump_t *mp;
10487   unformat_input_t *in = vam->input;
10488   int ipv4_set = 0;
10489   int ipv6_set = 0;
10490   int is_ipv6;
10491   f64 timeout;
10492   int i;
10493
10494   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10495     {
10496       if (unformat (in, "ipv4"))
10497         ipv4_set = 1;
10498       else if (unformat (in, "ipv6"))
10499         ipv6_set = 1;
10500       else
10501         break;
10502     }
10503
10504   if (ipv4_set && ipv6_set)
10505     {
10506       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10507       return -99;
10508     }
10509
10510   if ((!ipv4_set) && (!ipv6_set))
10511     {
10512       errmsg ("no ipv4 nor ipv6 flag set\n");
10513       return -99;
10514     }
10515
10516   is_ipv6 = ipv6_set;
10517   vam->is_ipv6 = is_ipv6;
10518
10519   /* free old data */
10520   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10521     {
10522       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10523     }
10524   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10525
10526   M (IP_DUMP, ip_dump);
10527   mp->is_ipv6 = ipv6_set;
10528   S;
10529
10530   /* Use a control ping for synchronization */
10531   {
10532     vl_api_control_ping_t *mp;
10533     M (CONTROL_PING, control_ping);
10534     S;
10535   }
10536   W;
10537 }
10538
10539 static int
10540 api_ipsec_spd_add_del (vat_main_t * vam)
10541 {
10542 #if DPDK > 0
10543   unformat_input_t *i = vam->input;
10544   vl_api_ipsec_spd_add_del_t *mp;
10545   f64 timeout;
10546   u32 spd_id = ~0;
10547   u8 is_add = 1;
10548
10549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10550     {
10551       if (unformat (i, "spd_id %d", &spd_id))
10552         ;
10553       else if (unformat (i, "del"))
10554         is_add = 0;
10555       else
10556         {
10557           clib_warning ("parse error '%U'", format_unformat_error, i);
10558           return -99;
10559         }
10560     }
10561   if (spd_id == ~0)
10562     {
10563       errmsg ("spd_id must be set\n");
10564       return -99;
10565     }
10566
10567   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10568
10569   mp->spd_id = ntohl (spd_id);
10570   mp->is_add = is_add;
10571
10572   S;
10573   W;
10574   /* NOTREACHED */
10575   return 0;
10576 #else
10577   clib_warning ("unsupported (no dpdk)");
10578   return -99;
10579 #endif
10580 }
10581
10582 static int
10583 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10584 {
10585 #if DPDK > 0
10586   unformat_input_t *i = vam->input;
10587   vl_api_ipsec_interface_add_del_spd_t *mp;
10588   f64 timeout;
10589   u32 sw_if_index;
10590   u8 sw_if_index_set = 0;
10591   u32 spd_id = (u32) ~ 0;
10592   u8 is_add = 1;
10593
10594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10595     {
10596       if (unformat (i, "del"))
10597         is_add = 0;
10598       else if (unformat (i, "spd_id %d", &spd_id))
10599         ;
10600       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10601         sw_if_index_set = 1;
10602       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10603         sw_if_index_set = 1;
10604       else
10605         {
10606           clib_warning ("parse error '%U'", format_unformat_error, i);
10607           return -99;
10608         }
10609
10610     }
10611
10612   if (spd_id == (u32) ~ 0)
10613     {
10614       errmsg ("spd_id must be set\n");
10615       return -99;
10616     }
10617
10618   if (sw_if_index_set == 0)
10619     {
10620       errmsg ("missing interface name or sw_if_index\n");
10621       return -99;
10622     }
10623
10624   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10625
10626   mp->spd_id = ntohl (spd_id);
10627   mp->sw_if_index = ntohl (sw_if_index);
10628   mp->is_add = is_add;
10629
10630   S;
10631   W;
10632   /* NOTREACHED */
10633   return 0;
10634 #else
10635   clib_warning ("unsupported (no dpdk)");
10636   return -99;
10637 #endif
10638 }
10639
10640 static int
10641 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10642 {
10643 #if DPDK > 0
10644   unformat_input_t *i = vam->input;
10645   vl_api_ipsec_spd_add_del_entry_t *mp;
10646   f64 timeout;
10647   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10648   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10649   i32 priority = 0;
10650   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10651   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10652   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10653   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10654
10655   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10656   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10657   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10658   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10659   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10660   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10661
10662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10663     {
10664       if (unformat (i, "del"))
10665         is_add = 0;
10666       if (unformat (i, "outbound"))
10667         is_outbound = 1;
10668       if (unformat (i, "inbound"))
10669         is_outbound = 0;
10670       else if (unformat (i, "spd_id %d", &spd_id))
10671         ;
10672       else if (unformat (i, "sa_id %d", &sa_id))
10673         ;
10674       else if (unformat (i, "priority %d", &priority))
10675         ;
10676       else if (unformat (i, "protocol %d", &protocol))
10677         ;
10678       else if (unformat (i, "lport_start %d", &lport_start))
10679         ;
10680       else if (unformat (i, "lport_stop %d", &lport_stop))
10681         ;
10682       else if (unformat (i, "rport_start %d", &rport_start))
10683         ;
10684       else if (unformat (i, "rport_stop %d", &rport_stop))
10685         ;
10686       else
10687         if (unformat
10688             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10689         {
10690           is_ipv6 = 0;
10691           is_ip_any = 0;
10692         }
10693       else
10694         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10695         {
10696           is_ipv6 = 0;
10697           is_ip_any = 0;
10698         }
10699       else
10700         if (unformat
10701             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
10702         {
10703           is_ipv6 = 0;
10704           is_ip_any = 0;
10705         }
10706       else
10707         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
10708         {
10709           is_ipv6 = 0;
10710           is_ip_any = 0;
10711         }
10712       else
10713         if (unformat
10714             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
10715         {
10716           is_ipv6 = 1;
10717           is_ip_any = 0;
10718         }
10719       else
10720         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
10721         {
10722           is_ipv6 = 1;
10723           is_ip_any = 0;
10724         }
10725       else
10726         if (unformat
10727             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
10728         {
10729           is_ipv6 = 1;
10730           is_ip_any = 0;
10731         }
10732       else
10733         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
10734         {
10735           is_ipv6 = 1;
10736           is_ip_any = 0;
10737         }
10738       else
10739         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10740         {
10741           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10742             {
10743               clib_warning ("unsupported action: 'resolve'");
10744               return -99;
10745             }
10746         }
10747       else
10748         {
10749           clib_warning ("parse error '%U'", format_unformat_error, i);
10750           return -99;
10751         }
10752
10753     }
10754
10755   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
10756
10757   mp->spd_id = ntohl (spd_id);
10758   mp->priority = ntohl (priority);
10759   mp->is_outbound = is_outbound;
10760
10761   mp->is_ipv6 = is_ipv6;
10762   if (is_ipv6 || is_ip_any)
10763     {
10764       clib_memcpy (mp->remote_address_start, &raddr6_start,
10765                    sizeof (ip6_address_t));
10766       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
10767                    sizeof (ip6_address_t));
10768       clib_memcpy (mp->local_address_start, &laddr6_start,
10769                    sizeof (ip6_address_t));
10770       clib_memcpy (mp->local_address_stop, &laddr6_stop,
10771                    sizeof (ip6_address_t));
10772     }
10773   else
10774     {
10775       clib_memcpy (mp->remote_address_start, &raddr4_start,
10776                    sizeof (ip4_address_t));
10777       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
10778                    sizeof (ip4_address_t));
10779       clib_memcpy (mp->local_address_start, &laddr4_start,
10780                    sizeof (ip4_address_t));
10781       clib_memcpy (mp->local_address_stop, &laddr4_stop,
10782                    sizeof (ip4_address_t));
10783     }
10784   mp->protocol = (u8) protocol;
10785   mp->local_port_start = ntohs ((u16) lport_start);
10786   mp->local_port_stop = ntohs ((u16) lport_stop);
10787   mp->remote_port_start = ntohs ((u16) rport_start);
10788   mp->remote_port_stop = ntohs ((u16) rport_stop);
10789   mp->policy = (u8) policy;
10790   mp->sa_id = ntohl (sa_id);
10791   mp->is_add = is_add;
10792   mp->is_ip_any = is_ip_any;
10793   S;
10794   W;
10795   /* NOTREACHED */
10796   return 0;
10797 #else
10798   clib_warning ("unsupported (no dpdk)");
10799   return -99;
10800 #endif
10801 }
10802
10803 static int
10804 api_ipsec_sad_add_del_entry (vat_main_t * vam)
10805 {
10806 #if DPDK > 0
10807   unformat_input_t *i = vam->input;
10808   vl_api_ipsec_sad_add_del_entry_t *mp;
10809   f64 timeout;
10810   u32 sad_id = 0, spi = 0;
10811   u8 *ck = 0, *ik = 0;
10812   u8 is_add = 1;
10813
10814   u8 protocol = IPSEC_PROTOCOL_AH;
10815   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
10816   u32 crypto_alg = 0, integ_alg = 0;
10817   ip4_address_t tun_src4;
10818   ip4_address_t tun_dst4;
10819   ip6_address_t tun_src6;
10820   ip6_address_t tun_dst6;
10821
10822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10823     {
10824       if (unformat (i, "del"))
10825         is_add = 0;
10826       else if (unformat (i, "sad_id %d", &sad_id))
10827         ;
10828       else if (unformat (i, "spi %d", &spi))
10829         ;
10830       else if (unformat (i, "esp"))
10831         protocol = IPSEC_PROTOCOL_ESP;
10832       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
10833         {
10834           is_tunnel = 1;
10835           is_tunnel_ipv6 = 0;
10836         }
10837       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
10838         {
10839           is_tunnel = 1;
10840           is_tunnel_ipv6 = 0;
10841         }
10842       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
10843         {
10844           is_tunnel = 1;
10845           is_tunnel_ipv6 = 1;
10846         }
10847       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
10848         {
10849           is_tunnel = 1;
10850           is_tunnel_ipv6 = 1;
10851         }
10852       else
10853         if (unformat
10854             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
10855         {
10856           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
10857               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
10858             {
10859               clib_warning ("unsupported crypto-alg: '%U'",
10860                             format_ipsec_crypto_alg, crypto_alg);
10861               return -99;
10862             }
10863         }
10864       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10865         ;
10866       else
10867         if (unformat
10868             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
10869         {
10870           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
10871               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
10872             {
10873               clib_warning ("unsupported integ-alg: '%U'",
10874                             format_ipsec_integ_alg, integ_alg);
10875               return -99;
10876             }
10877         }
10878       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10879         ;
10880       else
10881         {
10882           clib_warning ("parse error '%U'", format_unformat_error, i);
10883           return -99;
10884         }
10885
10886     }
10887
10888   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
10889
10890   mp->sad_id = ntohl (sad_id);
10891   mp->is_add = is_add;
10892   mp->protocol = protocol;
10893   mp->spi = ntohl (spi);
10894   mp->is_tunnel = is_tunnel;
10895   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
10896   mp->crypto_algorithm = crypto_alg;
10897   mp->integrity_algorithm = integ_alg;
10898   mp->crypto_key_length = vec_len (ck);
10899   mp->integrity_key_length = vec_len (ik);
10900
10901   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10902     mp->crypto_key_length = sizeof (mp->crypto_key);
10903
10904   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10905     mp->integrity_key_length = sizeof (mp->integrity_key);
10906
10907   if (ck)
10908     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10909   if (ik)
10910     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10911
10912   if (is_tunnel)
10913     {
10914       if (is_tunnel_ipv6)
10915         {
10916           clib_memcpy (mp->tunnel_src_address, &tun_src6,
10917                        sizeof (ip6_address_t));
10918           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
10919                        sizeof (ip6_address_t));
10920         }
10921       else
10922         {
10923           clib_memcpy (mp->tunnel_src_address, &tun_src4,
10924                        sizeof (ip4_address_t));
10925           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
10926                        sizeof (ip4_address_t));
10927         }
10928     }
10929
10930   S;
10931   W;
10932   /* NOTREACHED */
10933   return 0;
10934 #else
10935   clib_warning ("unsupported (no dpdk)");
10936   return -99;
10937 #endif
10938 }
10939
10940 static int
10941 api_ipsec_sa_set_key (vat_main_t * vam)
10942 {
10943 #if DPDK > 0
10944   unformat_input_t *i = vam->input;
10945   vl_api_ipsec_sa_set_key_t *mp;
10946   f64 timeout;
10947   u32 sa_id;
10948   u8 *ck = 0, *ik = 0;
10949
10950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10951     {
10952       if (unformat (i, "sa_id %d", &sa_id))
10953         ;
10954       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10955         ;
10956       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10957         ;
10958       else
10959         {
10960           clib_warning ("parse error '%U'", format_unformat_error, i);
10961           return -99;
10962         }
10963     }
10964
10965   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
10966
10967   mp->sa_id = ntohl (sa_id);
10968   mp->crypto_key_length = vec_len (ck);
10969   mp->integrity_key_length = vec_len (ik);
10970
10971   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10972     mp->crypto_key_length = sizeof (mp->crypto_key);
10973
10974   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10975     mp->integrity_key_length = sizeof (mp->integrity_key);
10976
10977   if (ck)
10978     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10979   if (ik)
10980     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10981
10982   S;
10983   W;
10984   /* NOTREACHED */
10985   return 0;
10986 #else
10987   clib_warning ("unsupported (no dpdk)");
10988   return -99;
10989 #endif
10990 }
10991
10992 static int
10993 api_ikev2_profile_add_del (vat_main_t * vam)
10994 {
10995 #if DPDK > 0
10996   unformat_input_t *i = vam->input;
10997   vl_api_ikev2_profile_add_del_t *mp;
10998   f64 timeout;
10999   u8 is_add = 1;
11000   u8 *name = 0;
11001
11002   const char *valid_chars = "a-zA-Z0-9_";
11003
11004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11005     {
11006       if (unformat (i, "del"))
11007         is_add = 0;
11008       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11009         vec_add1 (name, 0);
11010       else
11011         {
11012           errmsg ("parse error '%U'", format_unformat_error, i);
11013           return -99;
11014         }
11015     }
11016
11017   if (!vec_len (name))
11018     {
11019       errmsg ("profile name must be specified");
11020       return -99;
11021     }
11022
11023   if (vec_len (name) > 64)
11024     {
11025       errmsg ("profile name too long");
11026       return -99;
11027     }
11028
11029   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11030
11031   clib_memcpy (mp->name, name, vec_len (name));
11032   mp->is_add = is_add;
11033   vec_free (name);
11034
11035   S;
11036   W;
11037   /* NOTREACHED */
11038   return 0;
11039 #else
11040   clib_warning ("unsupported (no dpdk)");
11041   return -99;
11042 #endif
11043 }
11044
11045 static int
11046 api_ikev2_profile_set_auth (vat_main_t * vam)
11047 {
11048 #if DPDK > 0
11049   unformat_input_t *i = vam->input;
11050   vl_api_ikev2_profile_set_auth_t *mp;
11051   f64 timeout;
11052   u8 *name = 0;
11053   u8 *data = 0;
11054   u32 auth_method = 0;
11055   u8 is_hex = 0;
11056
11057   const char *valid_chars = "a-zA-Z0-9_";
11058
11059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11060     {
11061       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11062         vec_add1 (name, 0);
11063       else if (unformat (i, "auth_method %U",
11064                          unformat_ikev2_auth_method, &auth_method))
11065         ;
11066       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11067         is_hex = 1;
11068       else if (unformat (i, "auth_data %v", &data))
11069         ;
11070       else
11071         {
11072           errmsg ("parse error '%U'", format_unformat_error, i);
11073           return -99;
11074         }
11075     }
11076
11077   if (!vec_len (name))
11078     {
11079       errmsg ("profile name must be specified");
11080       return -99;
11081     }
11082
11083   if (vec_len (name) > 64)
11084     {
11085       errmsg ("profile name too long");
11086       return -99;
11087     }
11088
11089   if (!vec_len (data))
11090     {
11091       errmsg ("auth_data must be specified");
11092       return -99;
11093     }
11094
11095   if (!auth_method)
11096     {
11097       errmsg ("auth_method must be specified");
11098       return -99;
11099     }
11100
11101   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11102
11103   mp->is_hex = is_hex;
11104   mp->auth_method = (u8) auth_method;
11105   mp->data_len = vec_len (data);
11106   clib_memcpy (mp->name, name, vec_len (name));
11107   clib_memcpy (mp->data, data, vec_len (data));
11108   vec_free (name);
11109   vec_free (data);
11110
11111   S;
11112   W;
11113   /* NOTREACHED */
11114   return 0;
11115 #else
11116   clib_warning ("unsupported (no dpdk)");
11117   return -99;
11118 #endif
11119 }
11120
11121 static int
11122 api_ikev2_profile_set_id (vat_main_t * vam)
11123 {
11124 #if DPDK > 0
11125   unformat_input_t *i = vam->input;
11126   vl_api_ikev2_profile_set_id_t *mp;
11127   f64 timeout;
11128   u8 *name = 0;
11129   u8 *data = 0;
11130   u8 is_local = 0;
11131   u32 id_type = 0;
11132   ip4_address_t ip4;
11133
11134   const char *valid_chars = "a-zA-Z0-9_";
11135
11136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11137     {
11138       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11139         vec_add1 (name, 0);
11140       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11141         ;
11142       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11143         {
11144           data = vec_new (u8, 4);
11145           clib_memcpy (data, ip4.as_u8, 4);
11146         }
11147       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11148         ;
11149       else if (unformat (i, "id_data %v", &data))
11150         ;
11151       else if (unformat (i, "local"))
11152         is_local = 1;
11153       else if (unformat (i, "remote"))
11154         is_local = 0;
11155       else
11156         {
11157           errmsg ("parse error '%U'", format_unformat_error, i);
11158           return -99;
11159         }
11160     }
11161
11162   if (!vec_len (name))
11163     {
11164       errmsg ("profile name must be specified");
11165       return -99;
11166     }
11167
11168   if (vec_len (name) > 64)
11169     {
11170       errmsg ("profile name too long");
11171       return -99;
11172     }
11173
11174   if (!vec_len (data))
11175     {
11176       errmsg ("id_data must be specified");
11177       return -99;
11178     }
11179
11180   if (!id_type)
11181     {
11182       errmsg ("id_type must be specified");
11183       return -99;
11184     }
11185
11186   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11187
11188   mp->is_local = is_local;
11189   mp->id_type = (u8) id_type;
11190   mp->data_len = vec_len (data);
11191   clib_memcpy (mp->name, name, vec_len (name));
11192   clib_memcpy (mp->data, data, vec_len (data));
11193   vec_free (name);
11194   vec_free (data);
11195
11196   S;
11197   W;
11198   /* NOTREACHED */
11199   return 0;
11200 #else
11201   clib_warning ("unsupported (no dpdk)");
11202   return -99;
11203 #endif
11204 }
11205
11206 static int
11207 api_ikev2_profile_set_ts (vat_main_t * vam)
11208 {
11209 #if DPDK > 0
11210   unformat_input_t *i = vam->input;
11211   vl_api_ikev2_profile_set_ts_t *mp;
11212   f64 timeout;
11213   u8 *name = 0;
11214   u8 is_local = 0;
11215   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11216   ip4_address_t start_addr, end_addr;
11217
11218   const char *valid_chars = "a-zA-Z0-9_";
11219
11220   start_addr.as_u32 = 0;
11221   end_addr.as_u32 = (u32) ~ 0;
11222
11223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11224     {
11225       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11226         vec_add1 (name, 0);
11227       else if (unformat (i, "protocol %d", &proto))
11228         ;
11229       else if (unformat (i, "start_port %d", &start_port))
11230         ;
11231       else if (unformat (i, "end_port %d", &end_port))
11232         ;
11233       else
11234         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11235         ;
11236       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11237         ;
11238       else if (unformat (i, "local"))
11239         is_local = 1;
11240       else if (unformat (i, "remote"))
11241         is_local = 0;
11242       else
11243         {
11244           errmsg ("parse error '%U'", format_unformat_error, i);
11245           return -99;
11246         }
11247     }
11248
11249   if (!vec_len (name))
11250     {
11251       errmsg ("profile name must be specified");
11252       return -99;
11253     }
11254
11255   if (vec_len (name) > 64)
11256     {
11257       errmsg ("profile name too long");
11258       return -99;
11259     }
11260
11261   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11262
11263   mp->is_local = is_local;
11264   mp->proto = (u8) proto;
11265   mp->start_port = (u16) start_port;
11266   mp->end_port = (u16) end_port;
11267   mp->start_addr = start_addr.as_u32;
11268   mp->end_addr = end_addr.as_u32;
11269   clib_memcpy (mp->name, name, vec_len (name));
11270   vec_free (name);
11271
11272   S;
11273   W;
11274   /* NOTREACHED */
11275   return 0;
11276 #else
11277   clib_warning ("unsupported (no dpdk)");
11278   return -99;
11279 #endif
11280 }
11281
11282 static int
11283 api_ikev2_set_local_key (vat_main_t * vam)
11284 {
11285 #if DPDK > 0
11286   unformat_input_t *i = vam->input;
11287   vl_api_ikev2_set_local_key_t *mp;
11288   f64 timeout;
11289   u8 *file = 0;
11290
11291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11292     {
11293       if (unformat (i, "file %v", &file))
11294         vec_add1 (file, 0);
11295       else
11296         {
11297           errmsg ("parse error '%U'", format_unformat_error, i);
11298           return -99;
11299         }
11300     }
11301
11302   if (!vec_len (file))
11303     {
11304       errmsg ("RSA key file must be specified");
11305       return -99;
11306     }
11307
11308   if (vec_len (file) > 256)
11309     {
11310       errmsg ("file name too long");
11311       return -99;
11312     }
11313
11314   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11315
11316   clib_memcpy (mp->key_file, file, vec_len (file));
11317   vec_free (file);
11318
11319   S;
11320   W;
11321   /* NOTREACHED */
11322   return 0;
11323 #else
11324   clib_warning ("unsupported (no dpdk)");
11325   return -99;
11326 #endif
11327 }
11328
11329 /*
11330  * MAP
11331  */
11332 static int
11333 api_map_add_domain (vat_main_t * vam)
11334 {
11335   unformat_input_t *i = vam->input;
11336   vl_api_map_add_domain_t *mp;
11337   f64 timeout;
11338
11339   ip4_address_t ip4_prefix;
11340   ip6_address_t ip6_prefix;
11341   ip6_address_t ip6_src;
11342   u32 num_m_args = 0;
11343   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11344     0, psid_length = 0;
11345   u8 is_translation = 0;
11346   u32 mtu = 0;
11347   u32 ip6_src_len = 128;
11348
11349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11350     {
11351       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11352                     &ip4_prefix, &ip4_prefix_len))
11353         num_m_args++;
11354       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11355                          &ip6_prefix, &ip6_prefix_len))
11356         num_m_args++;
11357       else
11358         if (unformat
11359             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11360              &ip6_src_len))
11361         num_m_args++;
11362       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11363         num_m_args++;
11364       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11365         num_m_args++;
11366       else if (unformat (i, "psid-offset %d", &psid_offset))
11367         num_m_args++;
11368       else if (unformat (i, "psid-len %d", &psid_length))
11369         num_m_args++;
11370       else if (unformat (i, "mtu %d", &mtu))
11371         num_m_args++;
11372       else if (unformat (i, "map-t"))
11373         is_translation = 1;
11374       else
11375         {
11376           clib_warning ("parse error '%U'", format_unformat_error, i);
11377           return -99;
11378         }
11379     }
11380
11381   if (num_m_args < 3)
11382     {
11383       errmsg ("mandatory argument(s) missing\n");
11384       return -99;
11385     }
11386
11387   /* Construct the API message */
11388   M (MAP_ADD_DOMAIN, map_add_domain);
11389
11390   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11391   mp->ip4_prefix_len = ip4_prefix_len;
11392
11393   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11394   mp->ip6_prefix_len = ip6_prefix_len;
11395
11396   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11397   mp->ip6_src_prefix_len = ip6_src_len;
11398
11399   mp->ea_bits_len = ea_bits_len;
11400   mp->psid_offset = psid_offset;
11401   mp->psid_length = psid_length;
11402   mp->is_translation = is_translation;
11403   mp->mtu = htons (mtu);
11404
11405   /* send it... */
11406   S;
11407
11408   /* Wait for a reply, return good/bad news  */
11409   W;
11410 }
11411
11412 static int
11413 api_map_del_domain (vat_main_t * vam)
11414 {
11415   unformat_input_t *i = vam->input;
11416   vl_api_map_del_domain_t *mp;
11417   f64 timeout;
11418
11419   u32 num_m_args = 0;
11420   u32 index;
11421
11422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11423     {
11424       if (unformat (i, "index %d", &index))
11425         num_m_args++;
11426       else
11427         {
11428           clib_warning ("parse error '%U'", format_unformat_error, i);
11429           return -99;
11430         }
11431     }
11432
11433   if (num_m_args != 1)
11434     {
11435       errmsg ("mandatory argument(s) missing\n");
11436       return -99;
11437     }
11438
11439   /* Construct the API message */
11440   M (MAP_DEL_DOMAIN, map_del_domain);
11441
11442   mp->index = ntohl (index);
11443
11444   /* send it... */
11445   S;
11446
11447   /* Wait for a reply, return good/bad news  */
11448   W;
11449 }
11450
11451 static int
11452 api_map_add_del_rule (vat_main_t * vam)
11453 {
11454   unformat_input_t *i = vam->input;
11455   vl_api_map_add_del_rule_t *mp;
11456   f64 timeout;
11457   u8 is_add = 1;
11458   ip6_address_t ip6_dst;
11459   u32 num_m_args = 0, index, psid = 0;
11460
11461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11462     {
11463       if (unformat (i, "index %d", &index))
11464         num_m_args++;
11465       else if (unformat (i, "psid %d", &psid))
11466         num_m_args++;
11467       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11468         num_m_args++;
11469       else if (unformat (i, "del"))
11470         {
11471           is_add = 0;
11472         }
11473       else
11474         {
11475           clib_warning ("parse error '%U'", format_unformat_error, i);
11476           return -99;
11477         }
11478     }
11479
11480   /* Construct the API message */
11481   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11482
11483   mp->index = ntohl (index);
11484   mp->is_add = is_add;
11485   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11486   mp->psid = ntohs (psid);
11487
11488   /* send it... */
11489   S;
11490
11491   /* Wait for a reply, return good/bad news  */
11492   W;
11493 }
11494
11495 static int
11496 api_map_domain_dump (vat_main_t * vam)
11497 {
11498   vl_api_map_domain_dump_t *mp;
11499   f64 timeout;
11500
11501   /* Construct the API message */
11502   M (MAP_DOMAIN_DUMP, map_domain_dump);
11503
11504   /* send it... */
11505   S;
11506
11507   /* Use a control ping for synchronization */
11508   {
11509     vl_api_control_ping_t *mp;
11510     M (CONTROL_PING, control_ping);
11511     S;
11512   }
11513   W;
11514 }
11515
11516 static int
11517 api_map_rule_dump (vat_main_t * vam)
11518 {
11519   unformat_input_t *i = vam->input;
11520   vl_api_map_rule_dump_t *mp;
11521   f64 timeout;
11522   u32 domain_index = ~0;
11523
11524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11525     {
11526       if (unformat (i, "index %u", &domain_index))
11527         ;
11528       else
11529         break;
11530     }
11531
11532   if (domain_index == ~0)
11533     {
11534       clib_warning ("parse error: domain index expected");
11535       return -99;
11536     }
11537
11538   /* Construct the API message */
11539   M (MAP_RULE_DUMP, map_rule_dump);
11540
11541   mp->domain_index = htonl (domain_index);
11542
11543   /* send it... */
11544   S;
11545
11546   /* Use a control ping for synchronization */
11547   {
11548     vl_api_control_ping_t *mp;
11549     M (CONTROL_PING, control_ping);
11550     S;
11551   }
11552   W;
11553 }
11554
11555 static void vl_api_map_add_domain_reply_t_handler
11556   (vl_api_map_add_domain_reply_t * mp)
11557 {
11558   vat_main_t *vam = &vat_main;
11559   i32 retval = ntohl (mp->retval);
11560
11561   if (vam->async_mode)
11562     {
11563       vam->async_errors += (retval < 0);
11564     }
11565   else
11566     {
11567       vam->retval = retval;
11568       vam->result_ready = 1;
11569     }
11570 }
11571
11572 static void vl_api_map_add_domain_reply_t_handler_json
11573   (vl_api_map_add_domain_reply_t * mp)
11574 {
11575   vat_main_t *vam = &vat_main;
11576   vat_json_node_t node;
11577
11578   vat_json_init_object (&node);
11579   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11580   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11581
11582   vat_json_print (vam->ofp, &node);
11583   vat_json_free (&node);
11584
11585   vam->retval = ntohl (mp->retval);
11586   vam->result_ready = 1;
11587 }
11588
11589 static int
11590 api_get_first_msg_id (vat_main_t * vam)
11591 {
11592   vl_api_get_first_msg_id_t *mp;
11593   f64 timeout;
11594   unformat_input_t *i = vam->input;
11595   u8 *name;
11596   u8 name_set = 0;
11597
11598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11599     {
11600       if (unformat (i, "client %s", &name))
11601         name_set = 1;
11602       else
11603         break;
11604     }
11605
11606   if (name_set == 0)
11607     {
11608       errmsg ("missing client name\n");
11609       return -99;
11610     }
11611   vec_add1 (name, 0);
11612
11613   if (vec_len (name) > 63)
11614     {
11615       errmsg ("client name too long\n");
11616       return -99;
11617     }
11618
11619   M (GET_FIRST_MSG_ID, get_first_msg_id);
11620   clib_memcpy (mp->name, name, vec_len (name));
11621   S;
11622   W;
11623   /* NOTREACHED */
11624   return 0;
11625 }
11626
11627 static int
11628 api_cop_interface_enable_disable (vat_main_t * vam)
11629 {
11630   unformat_input_t *line_input = vam->input;
11631   vl_api_cop_interface_enable_disable_t *mp;
11632   f64 timeout;
11633   u32 sw_if_index = ~0;
11634   u8 enable_disable = 1;
11635
11636   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11637     {
11638       if (unformat (line_input, "disable"))
11639         enable_disable = 0;
11640       if (unformat (line_input, "enable"))
11641         enable_disable = 1;
11642       else if (unformat (line_input, "%U", unformat_sw_if_index,
11643                          vam, &sw_if_index))
11644         ;
11645       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11646         ;
11647       else
11648         break;
11649     }
11650
11651   if (sw_if_index == ~0)
11652     {
11653       errmsg ("missing interface name or sw_if_index\n");
11654       return -99;
11655     }
11656
11657   /* Construct the API message */
11658   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11659   mp->sw_if_index = ntohl (sw_if_index);
11660   mp->enable_disable = enable_disable;
11661
11662   /* send it... */
11663   S;
11664   /* Wait for the reply */
11665   W;
11666 }
11667
11668 static int
11669 api_cop_whitelist_enable_disable (vat_main_t * vam)
11670 {
11671   unformat_input_t *line_input = vam->input;
11672   vl_api_cop_whitelist_enable_disable_t *mp;
11673   f64 timeout;
11674   u32 sw_if_index = ~0;
11675   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11676   u32 fib_id = 0;
11677
11678   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11679     {
11680       if (unformat (line_input, "ip4"))
11681         ip4 = 1;
11682       else if (unformat (line_input, "ip6"))
11683         ip6 = 1;
11684       else if (unformat (line_input, "default"))
11685         default_cop = 1;
11686       else if (unformat (line_input, "%U", unformat_sw_if_index,
11687                          vam, &sw_if_index))
11688         ;
11689       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11690         ;
11691       else if (unformat (line_input, "fib-id %d", &fib_id))
11692         ;
11693       else
11694         break;
11695     }
11696
11697   if (sw_if_index == ~0)
11698     {
11699       errmsg ("missing interface name or sw_if_index\n");
11700       return -99;
11701     }
11702
11703   /* Construct the API message */
11704   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
11705   mp->sw_if_index = ntohl (sw_if_index);
11706   mp->fib_id = ntohl (fib_id);
11707   mp->ip4 = ip4;
11708   mp->ip6 = ip6;
11709   mp->default_cop = default_cop;
11710
11711   /* send it... */
11712   S;
11713   /* Wait for the reply */
11714   W;
11715 }
11716
11717 static int
11718 api_get_node_graph (vat_main_t * vam)
11719 {
11720   vl_api_get_node_graph_t *mp;
11721   f64 timeout;
11722
11723   M (GET_NODE_GRAPH, get_node_graph);
11724
11725   /* send it... */
11726   S;
11727   /* Wait for the reply */
11728   W;
11729 }
11730
11731 /* *INDENT-OFF* */
11732 /** Used for parsing LISP eids */
11733 typedef CLIB_PACKED(struct{
11734   u8 addr[16];   /**< eid address */
11735   u32 len;       /**< prefix length if IP */
11736   u8 type;      /**< type of eid */
11737 }) lisp_eid_vat_t;
11738 /* *INDENT-ON* */
11739
11740 static uword
11741 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
11742 {
11743   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
11744
11745   memset (a, 0, sizeof (a[0]));
11746
11747   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
11748     {
11749       a->type = 0;              /* ipv4 type */
11750     }
11751   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
11752     {
11753       a->type = 1;              /* ipv6 type */
11754     }
11755   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
11756     {
11757       a->type = 2;              /* mac type */
11758     }
11759   else
11760     {
11761       return 0;
11762     }
11763
11764   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
11765     {
11766       return 0;
11767     }
11768
11769   return 1;
11770 }
11771
11772 static int
11773 lisp_eid_size_vat (u8 type)
11774 {
11775   switch (type)
11776     {
11777     case 0:
11778       return 4;
11779     case 1:
11780       return 16;
11781     case 2:
11782       return 6;
11783     }
11784   return 0;
11785 }
11786
11787 static void
11788 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
11789 {
11790   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
11791 }
11792
11793 /* *INDENT-OFF* */
11794 /** Used for transferring locators via VPP API */
11795 typedef CLIB_PACKED(struct
11796 {
11797   u32 sw_if_index; /**< locator sw_if_index */
11798   u8 priority; /**< locator priority */
11799   u8 weight;   /**< locator weight */
11800 }) ls_locator_t;
11801 /* *INDENT-ON* */
11802
11803 static int
11804 api_lisp_add_del_locator_set (vat_main_t * vam)
11805 {
11806   unformat_input_t *input = vam->input;
11807   vl_api_lisp_add_del_locator_set_t *mp;
11808   f64 timeout = ~0;
11809   u8 is_add = 1;
11810   u8 *locator_set_name = NULL;
11811   u8 locator_set_name_set = 0;
11812   ls_locator_t locator, *locators = 0;
11813   u32 sw_if_index, priority, weight;
11814
11815   /* Parse args required to build the message */
11816   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11817     {
11818       if (unformat (input, "del"))
11819         {
11820           is_add = 0;
11821         }
11822       else if (unformat (input, "locator-set %s", &locator_set_name))
11823         {
11824           locator_set_name_set = 1;
11825         }
11826       else if (unformat (input, "sw_if_index %u p %u w %u",
11827                          &sw_if_index, &priority, &weight))
11828         {
11829           locator.sw_if_index = htonl (sw_if_index);
11830           locator.priority = priority;
11831           locator.weight = weight;
11832           vec_add1 (locators, locator);
11833         }
11834       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
11835                          vam, &sw_if_index, &priority, &weight))
11836         {
11837           locator.sw_if_index = htonl (sw_if_index);
11838           locator.priority = priority;
11839           locator.weight = weight;
11840           vec_add1 (locators, locator);
11841         }
11842       else
11843         break;
11844     }
11845
11846   if (locator_set_name_set == 0)
11847     {
11848       errmsg ("missing locator-set name");
11849       vec_free (locators);
11850       return -99;
11851     }
11852
11853   if (vec_len (locator_set_name) > 64)
11854     {
11855       errmsg ("locator-set name too long\n");
11856       vec_free (locator_set_name);
11857       vec_free (locators);
11858       return -99;
11859     }
11860   vec_add1 (locator_set_name, 0);
11861
11862   /* Construct the API message */
11863   M (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
11864
11865   mp->is_add = is_add;
11866   clib_memcpy (mp->locator_set_name, locator_set_name,
11867                vec_len (locator_set_name));
11868   vec_free (locator_set_name);
11869
11870   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
11871   if (locators)
11872     clib_memcpy (mp->locators, locators,
11873                  (sizeof (ls_locator_t) * vec_len (locators)));
11874   vec_free (locators);
11875
11876   /* send it... */
11877   S;
11878
11879   /* Wait for a reply... */
11880   W;
11881
11882   /* NOTREACHED */
11883   return 0;
11884 }
11885
11886 static int
11887 api_lisp_add_del_locator (vat_main_t * vam)
11888 {
11889   unformat_input_t *input = vam->input;
11890   vl_api_lisp_add_del_locator_t *mp;
11891   f64 timeout = ~0;
11892   u32 tmp_if_index = ~0;
11893   u32 sw_if_index = ~0;
11894   u8 sw_if_index_set = 0;
11895   u8 sw_if_index_if_name_set = 0;
11896   u32 priority = ~0;
11897   u8 priority_set = 0;
11898   u32 weight = ~0;
11899   u8 weight_set = 0;
11900   u8 is_add = 1;
11901   u8 *locator_set_name = NULL;
11902   u8 locator_set_name_set = 0;
11903
11904   /* Parse args required to build the message */
11905   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11906     {
11907       if (unformat (input, "del"))
11908         {
11909           is_add = 0;
11910         }
11911       else if (unformat (input, "locator-set %s", &locator_set_name))
11912         {
11913           locator_set_name_set = 1;
11914         }
11915       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
11916                          &tmp_if_index))
11917         {
11918           sw_if_index_if_name_set = 1;
11919           sw_if_index = tmp_if_index;
11920         }
11921       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
11922         {
11923           sw_if_index_set = 1;
11924           sw_if_index = tmp_if_index;
11925         }
11926       else if (unformat (input, "p %d", &priority))
11927         {
11928           priority_set = 1;
11929         }
11930       else if (unformat (input, "w %d", &weight))
11931         {
11932           weight_set = 1;
11933         }
11934       else
11935         break;
11936     }
11937
11938   if (locator_set_name_set == 0)
11939     {
11940       errmsg ("missing locator-set name");
11941       return -99;
11942     }
11943
11944   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
11945     {
11946       errmsg ("missing sw_if_index");
11947       vec_free (locator_set_name);
11948       return -99;
11949     }
11950
11951   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
11952     {
11953       errmsg ("cannot use both params interface name and sw_if_index");
11954       vec_free (locator_set_name);
11955       return -99;
11956     }
11957
11958   if (priority_set == 0)
11959     {
11960       errmsg ("missing locator-set priority\n");
11961       vec_free (locator_set_name);
11962       return -99;
11963     }
11964
11965   if (weight_set == 0)
11966     {
11967       errmsg ("missing locator-set weight\n");
11968       vec_free (locator_set_name);
11969       return -99;
11970     }
11971
11972   if (vec_len (locator_set_name) > 64)
11973     {
11974       errmsg ("locator-set name too long\n");
11975       vec_free (locator_set_name);
11976       return -99;
11977     }
11978   vec_add1 (locator_set_name, 0);
11979
11980   /* Construct the API message */
11981   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
11982
11983   mp->is_add = is_add;
11984   mp->sw_if_index = ntohl (sw_if_index);
11985   mp->priority = priority;
11986   mp->weight = weight;
11987   clib_memcpy (mp->locator_set_name, locator_set_name,
11988                vec_len (locator_set_name));
11989   vec_free (locator_set_name);
11990
11991   /* send it... */
11992   S;
11993
11994   /* Wait for a reply... */
11995   W;
11996
11997   /* NOTREACHED */
11998   return 0;
11999 }
12000
12001 static int
12002 api_lisp_add_del_local_eid (vat_main_t * vam)
12003 {
12004   unformat_input_t *input = vam->input;
12005   vl_api_lisp_add_del_local_eid_t *mp;
12006   f64 timeout = ~0;
12007   u8 is_add = 1;
12008   u8 eid_set = 0;
12009   lisp_eid_vat_t _eid, *eid = &_eid;
12010   u8 *locator_set_name = 0;
12011   u8 locator_set_name_set = 0;
12012   u32 vni = 0;
12013
12014   /* Parse args required to build the message */
12015   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12016     {
12017       if (unformat (input, "del"))
12018         {
12019           is_add = 0;
12020         }
12021       else if (unformat (input, "vni %d", &vni))
12022         {
12023           ;
12024         }
12025       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12026         {
12027           eid_set = 1;
12028         }
12029       else if (unformat (input, "locator-set %s", &locator_set_name))
12030         {
12031           locator_set_name_set = 1;
12032         }
12033       else
12034         break;
12035     }
12036
12037   if (locator_set_name_set == 0)
12038     {
12039       errmsg ("missing locator-set name\n");
12040       return -99;
12041     }
12042
12043   if (0 == eid_set)
12044     {
12045       errmsg ("EID address not set!");
12046       vec_free (locator_set_name);
12047       return -99;
12048     }
12049
12050   if (vec_len (locator_set_name) > 64)
12051     {
12052       errmsg ("locator-set name too long\n");
12053       vec_free (locator_set_name);
12054       return -99;
12055     }
12056   vec_add1 (locator_set_name, 0);
12057
12058   /* Construct the API message */
12059   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12060
12061   mp->is_add = is_add;
12062   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12063   mp->eid_type = eid->type;
12064   mp->prefix_len = eid->len;
12065   mp->vni = clib_host_to_net_u32 (vni);
12066   clib_memcpy (mp->locator_set_name, locator_set_name,
12067                vec_len (locator_set_name));
12068
12069   vec_free (locator_set_name);
12070
12071   /* send it... */
12072   S;
12073
12074   /* Wait for a reply... */
12075   W;
12076
12077   /* NOTREACHED */
12078   return 0;
12079 }
12080
12081 /* *INDENT-OFF* */
12082 /** Used for transferring locators via VPP API */
12083 typedef CLIB_PACKED(struct
12084 {
12085   u8 is_ip4; /**< is locator an IPv4 address? */
12086   u8 priority; /**< locator priority */
12087   u8 weight;   /**< locator weight */
12088   u8 addr[16]; /**< IPv4/IPv6 address */
12089 }) rloc_t;
12090 /* *INDENT-ON* */
12091
12092 static int
12093 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12094 {
12095   unformat_input_t *input = vam->input;
12096   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12097   f64 timeout = ~0;
12098   u8 is_add = 1;
12099   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12100   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12101   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12102   u32 action = ~0, p, w;
12103   ip4_address_t rmt_rloc4, lcl_rloc4;
12104   ip6_address_t rmt_rloc6, lcl_rloc6;
12105   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12106
12107   memset (&rloc, 0, sizeof (rloc));
12108
12109   /* Parse args required to build the message */
12110   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12111     {
12112       if (unformat (input, "del"))
12113         {
12114           is_add = 0;
12115         }
12116       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12117         {
12118           rmt_eid_set = 1;
12119         }
12120       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12121         {
12122           lcl_eid_set = 1;
12123         }
12124       else if (unformat (input, "p %d w %d", &p, &w))
12125         {
12126           if (!curr_rloc)
12127             {
12128               errmsg ("No RLOC configured for setting priority/weight!");
12129               return -99;
12130             }
12131           curr_rloc->priority = p;
12132           curr_rloc->weight = w;
12133         }
12134       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12135                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12136         {
12137           rloc.is_ip4 = 1;
12138
12139           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12140           rloc.priority = rloc.weight = 0;
12141           vec_add1 (lcl_locs, rloc);
12142
12143           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12144           vec_add1 (rmt_locs, rloc);
12145           /* priority and weight saved in rmt loc */
12146           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12147         }
12148       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12149                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12150         {
12151           rloc.is_ip4 = 0;
12152           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12153           rloc.priority = rloc.weight = 0;
12154           vec_add1 (lcl_locs, rloc);
12155
12156           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12157           vec_add1 (rmt_locs, rloc);
12158           /* priority and weight saved in rmt loc */
12159           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12160         }
12161       else if (unformat (input, "action %d", &action))
12162         {
12163           ;
12164         }
12165       else
12166         {
12167           clib_warning ("parse error '%U'", format_unformat_error, input);
12168           return -99;
12169         }
12170     }
12171
12172   if (!rmt_eid_set)
12173     {
12174       errmsg ("remote eid addresses not set\n");
12175       return -99;
12176     }
12177
12178   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12179     {
12180       errmsg ("eid types don't match\n");
12181       return -99;
12182     }
12183
12184   if (0 == rmt_locs && (u32) ~ 0 == action)
12185     {
12186       errmsg ("action not set for negative mapping\n");
12187       return -99;
12188     }
12189
12190   /* Construct the API message */
12191   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12192
12193   mp->is_add = is_add;
12194   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12195   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12196   mp->eid_type = rmt_eid->type;
12197   mp->rmt_len = rmt_eid->len;
12198   mp->lcl_len = lcl_eid->len;
12199   mp->action = action;
12200
12201   if (0 != rmt_locs && 0 != lcl_locs)
12202     {
12203       mp->loc_num = vec_len (rmt_locs);
12204       clib_memcpy (mp->lcl_locs, lcl_locs,
12205                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12206       clib_memcpy (mp->rmt_locs, rmt_locs,
12207                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12208     }
12209   vec_free (lcl_locs);
12210   vec_free (rmt_locs);
12211
12212   /* send it... */
12213   S;
12214
12215   /* Wait for a reply... */
12216   W;
12217
12218   /* NOTREACHED */
12219   return 0;
12220 }
12221
12222 static int
12223 api_lisp_add_del_map_resolver (vat_main_t * vam)
12224 {
12225   unformat_input_t *input = vam->input;
12226   vl_api_lisp_add_del_map_resolver_t *mp;
12227   f64 timeout = ~0;
12228   u8 is_add = 1;
12229   u8 ipv4_set = 0;
12230   u8 ipv6_set = 0;
12231   ip4_address_t ipv4;
12232   ip6_address_t ipv6;
12233
12234   /* Parse args required to build the message */
12235   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12236     {
12237       if (unformat (input, "del"))
12238         {
12239           is_add = 0;
12240         }
12241       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12242         {
12243           ipv4_set = 1;
12244         }
12245       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12246         {
12247           ipv6_set = 1;
12248         }
12249       else
12250         break;
12251     }
12252
12253   if (ipv4_set && ipv6_set)
12254     {
12255       errmsg ("both eid v4 and v6 addresses set\n");
12256       return -99;
12257     }
12258
12259   if (!ipv4_set && !ipv6_set)
12260     {
12261       errmsg ("eid addresses not set\n");
12262       return -99;
12263     }
12264
12265   /* Construct the API message */
12266   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12267
12268   mp->is_add = is_add;
12269   if (ipv6_set)
12270     {
12271       mp->is_ipv6 = 1;
12272       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12273     }
12274   else
12275     {
12276       mp->is_ipv6 = 0;
12277       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12278     }
12279
12280   /* send it... */
12281   S;
12282
12283   /* Wait for a reply... */
12284   W;
12285
12286   /* NOTREACHED */
12287   return 0;
12288 }
12289
12290 static int
12291 api_lisp_gpe_enable_disable (vat_main_t * vam)
12292 {
12293   unformat_input_t *input = vam->input;
12294   vl_api_lisp_gpe_enable_disable_t *mp;
12295   f64 timeout = ~0;
12296   u8 is_set = 0;
12297   u8 is_en = 1;
12298
12299   /* Parse args required to build the message */
12300   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12301     {
12302       if (unformat (input, "enable"))
12303         {
12304           is_set = 1;
12305           is_en = 1;
12306         }
12307       else if (unformat (input, "disable"))
12308         {
12309           is_set = 1;
12310           is_en = 0;
12311         }
12312       else
12313         break;
12314     }
12315
12316   if (is_set == 0)
12317     {
12318       errmsg ("Value not set\n");
12319       return -99;
12320     }
12321
12322   /* Construct the API message */
12323   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12324
12325   mp->is_en = is_en;
12326
12327   /* send it... */
12328   S;
12329
12330   /* Wait for a reply... */
12331   W;
12332
12333   /* NOTREACHED */
12334   return 0;
12335 }
12336
12337 static int
12338 api_lisp_enable_disable (vat_main_t * vam)
12339 {
12340   unformat_input_t *input = vam->input;
12341   vl_api_lisp_enable_disable_t *mp;
12342   f64 timeout = ~0;
12343   u8 is_set = 0;
12344   u8 is_en = 0;
12345
12346   /* Parse args required to build the message */
12347   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12348     {
12349       if (unformat (input, "enable"))
12350         {
12351           is_set = 1;
12352           is_en = 1;
12353         }
12354       else if (unformat (input, "disable"))
12355         {
12356           is_set = 1;
12357         }
12358       else
12359         break;
12360     }
12361
12362   if (!is_set)
12363     {
12364       errmsg ("Value not set\n");
12365       return -99;
12366     }
12367
12368   /* Construct the API message */
12369   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12370
12371   mp->is_en = is_en;
12372
12373   /* send it... */
12374   S;
12375
12376   /* Wait for a reply... */
12377   W;
12378
12379   /* NOTREACHED */
12380   return 0;
12381 }
12382
12383 /**
12384  * Enable/disable LISP proxy ITR.
12385  *
12386  * @param vam vpp API test context
12387  * @return return code
12388  */
12389 static int
12390 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12391 {
12392   f64 timeout = ~0;
12393   u8 ls_name_set = 0;
12394   unformat_input_t *input = vam->input;
12395   vl_api_lisp_pitr_set_locator_set_t *mp;
12396   u8 is_add = 1;
12397   u8 *ls_name = 0;
12398
12399   /* Parse args required to build the message */
12400   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12401     {
12402       if (unformat (input, "del"))
12403         is_add = 0;
12404       else if (unformat (input, "locator-set %s", &ls_name))
12405         ls_name_set = 1;
12406       else
12407         {
12408           errmsg ("parse error '%U'", format_unformat_error, input);
12409           return -99;
12410         }
12411     }
12412
12413   if (!ls_name_set)
12414     {
12415       errmsg ("locator-set name not set!");
12416       return -99;
12417     }
12418
12419   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12420
12421   mp->is_add = is_add;
12422   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12423   vec_free (ls_name);
12424
12425   /* send */
12426   S;
12427
12428   /* wait for reply */
12429   W;
12430
12431   /* notreached */
12432   return 0;
12433 }
12434
12435 static int
12436 api_show_lisp_pitr (vat_main_t * vam)
12437 {
12438   vl_api_show_lisp_pitr_t *mp;
12439   f64 timeout = ~0;
12440
12441   if (!vam->json_output)
12442     {
12443       fformat (vam->ofp, "%=20s\n", "lisp status:");
12444     }
12445
12446   M (SHOW_LISP_PITR, show_lisp_pitr);
12447   /* send it... */
12448   S;
12449
12450   /* Wait for a reply... */
12451   W;
12452
12453   /* NOTREACHED */
12454   return 0;
12455 }
12456
12457 /**
12458  * Add/delete mapping between vni and vrf
12459  */
12460 static int
12461 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12462 {
12463   f64 timeout = ~0;
12464   unformat_input_t *input = vam->input;
12465   vl_api_lisp_eid_table_add_del_map_t *mp;
12466   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12467   u32 vni, vrf, bd_index;
12468
12469   /* Parse args required to build the message */
12470   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12471     {
12472       if (unformat (input, "del"))
12473         is_add = 0;
12474       else if (unformat (input, "vrf %d", &vrf))
12475         vrf_set = 1;
12476       else if (unformat (input, "bd_index %d", &bd_index))
12477         bd_index_set = 1;
12478       else if (unformat (input, "vni %d", &vni))
12479         vni_set = 1;
12480       else
12481         break;
12482     }
12483
12484   if (!vni_set || (!vrf_set && !bd_index_set))
12485     {
12486       errmsg ("missing arguments!");
12487       return -99;
12488     }
12489
12490   if (vrf_set && bd_index_set)
12491     {
12492       errmsg ("error: both vrf and bd entered!");
12493       return -99;
12494     }
12495
12496   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12497
12498   mp->is_add = is_add;
12499   mp->vni = htonl (vni);
12500   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
12501   mp->is_l2 = bd_index_set;
12502
12503   /* send */
12504   S;
12505
12506   /* wait for reply */
12507   W;
12508
12509   /* notreached */
12510   return 0;
12511 }
12512
12513 uword
12514 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
12515 {
12516   u32 *action = va_arg (*args, u32 *);
12517   u8 *s = 0;
12518
12519   if (unformat (input, "%s", &s))
12520     {
12521       if (!strcmp ((char *) s, "no-action"))
12522         action[0] = 0;
12523       else if (!strcmp ((char *) s, "natively-forward"))
12524         action[0] = 1;
12525       else if (!strcmp ((char *) s, "send-map-request"))
12526         action[0] = 2;
12527       else if (!strcmp ((char *) s, "drop"))
12528         action[0] = 3;
12529       else
12530         {
12531           clib_warning ("invalid action: '%s'", s);
12532           action[0] = 3;
12533         }
12534     }
12535   else
12536     return 0;
12537
12538   vec_free (s);
12539   return 1;
12540 }
12541
12542 /**
12543  * Add/del remote mapping to/from LISP control plane
12544  *
12545  * @param vam vpp API test context
12546  * @return return code
12547  */
12548 static int
12549 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12550 {
12551   unformat_input_t *input = vam->input;
12552   vl_api_lisp_add_del_remote_mapping_t *mp;
12553   f64 timeout = ~0;
12554   u32 vni = 0;
12555   lisp_eid_vat_t _eid, *eid = &_eid;
12556   lisp_eid_vat_t _seid, *seid = &_seid;
12557   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
12558   u32 action = ~0, p, w;
12559   ip4_address_t rloc4;
12560   ip6_address_t rloc6;
12561   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12562
12563   memset (&rloc, 0, sizeof (rloc));
12564
12565   /* Parse args required to build the message */
12566   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12567     {
12568       if (unformat (input, "del-all"))
12569         {
12570           del_all = 1;
12571         }
12572       else if (unformat (input, "del"))
12573         {
12574           is_add = 0;
12575         }
12576       else if (unformat (input, "add"))
12577         {
12578           is_add = 1;
12579         }
12580       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12581         {
12582           eid_set = 1;
12583         }
12584       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
12585         {
12586           seid_set = 1;
12587         }
12588       else if (unformat (input, "vni %d", &vni))
12589         {
12590           ;
12591         }
12592       else if (unformat (input, "p %d w %d", &p, &w))
12593         {
12594           if (!curr_rloc)
12595             {
12596               errmsg ("No RLOC configured for setting priority/weight!");
12597               return -99;
12598             }
12599           curr_rloc->priority = p;
12600           curr_rloc->weight = w;
12601         }
12602       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12603         {
12604           rloc.is_ip4 = 1;
12605           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12606           vec_add1 (rlocs, rloc);
12607           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12608         }
12609       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12610         {
12611           rloc.is_ip4 = 0;
12612           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12613           vec_add1 (rlocs, rloc);
12614           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12615         }
12616       else if (unformat (input, "action %U",
12617                          unformat_negative_mapping_action, &action))
12618         {
12619           ;
12620         }
12621       else
12622         {
12623           clib_warning ("parse error '%U'", format_unformat_error, input);
12624           return -99;
12625         }
12626     }
12627
12628   if (0 == eid_set)
12629     {
12630       errmsg ("missing params!");
12631       return -99;
12632     }
12633
12634   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12635     {
12636       errmsg ("no action set for negative map-reply!");
12637       return -99;
12638     }
12639
12640   M (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
12641   mp->is_add = is_add;
12642   mp->vni = htonl (vni);
12643   mp->action = (u8) action;
12644   mp->is_src_dst = seid_set;
12645   mp->eid_len = eid->len;
12646   mp->seid_len = seid->len;
12647   mp->del_all = del_all;
12648   mp->eid_type = eid->type;
12649   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12650   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
12651
12652   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
12653   clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
12654   vec_free (rlocs);
12655
12656   /* send it... */
12657   S;
12658
12659   /* Wait for a reply... */
12660   W;
12661
12662   /* NOTREACHED */
12663   return 0;
12664 }
12665
12666 /**
12667  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
12668  * forwarding entries in data-plane accordingly.
12669  *
12670  * @param vam vpp API test context
12671  * @return return code
12672  */
12673 static int
12674 api_lisp_add_del_adjacency (vat_main_t * vam)
12675 {
12676   unformat_input_t *input = vam->input;
12677   vl_api_lisp_add_del_adjacency_t *mp;
12678   f64 timeout = ~0;
12679   u32 vni = 0;
12680   ip4_address_t seid4, deid4;
12681   ip6_address_t seid6, deid6;
12682   u8 deid_mac[6] = { 0 };
12683   u8 seid_mac[6] = { 0 };
12684   u8 deid_type, seid_type;
12685   u32 seid_len = 0, deid_len = 0, len;
12686   u8 is_add = 1;
12687
12688   seid_type = deid_type = (u8) ~ 0;
12689
12690   /* Parse args required to build the message */
12691   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12692     {
12693       if (unformat (input, "del"))
12694         {
12695           is_add = 0;
12696         }
12697       else if (unformat (input, "add"))
12698         {
12699           is_add = 1;
12700         }
12701       else if (unformat (input, "deid %U/%d", unformat_ip4_address,
12702                          &deid4, &len))
12703         {
12704           deid_type = 0;        /* ipv4 */
12705           deid_len = len;
12706         }
12707       else if (unformat (input, "deid %U/%d", unformat_ip6_address,
12708                          &deid6, &len))
12709         {
12710           deid_type = 1;        /* ipv6 */
12711           deid_len = len;
12712         }
12713       else if (unformat (input, "deid %U", unformat_ethernet_address,
12714                          deid_mac))
12715         {
12716           deid_type = 2;        /* mac */
12717         }
12718       else if (unformat (input, "seid %U/%d", unformat_ip4_address,
12719                          &seid4, &len))
12720         {
12721           seid_type = 0;        /* ipv4 */
12722           seid_len = len;
12723         }
12724       else if (unformat (input, "seid %U/%d", unformat_ip6_address,
12725                          &seid6, &len))
12726         {
12727           seid_type = 1;        /* ipv6 */
12728           seid_len = len;
12729         }
12730       else if (unformat (input, "seid %U", unformat_ethernet_address,
12731                          seid_mac))
12732         {
12733           seid_type = 2;        /* mac */
12734         }
12735       else if (unformat (input, "vni %d", &vni))
12736         {
12737           ;
12738         }
12739       else
12740         {
12741           errmsg ("parse error '%U'", format_unformat_error, input);
12742           return -99;
12743         }
12744     }
12745
12746   if ((u8) ~ 0 == deid_type)
12747     {
12748       errmsg ("missing params!");
12749       return -99;
12750     }
12751
12752   if (seid_type != deid_type)
12753     {
12754       errmsg ("source and destination EIDs are of different types!");
12755       return -99;
12756     }
12757
12758   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
12759   mp->is_add = is_add;
12760   mp->vni = htonl (vni);
12761   mp->seid_len = seid_len;
12762   mp->deid_len = deid_len;
12763   mp->eid_type = deid_type;
12764
12765   switch (mp->eid_type)
12766     {
12767     case 0:
12768       clib_memcpy (mp->seid, &seid4, sizeof (seid4));
12769       clib_memcpy (mp->deid, &deid4, sizeof (deid4));
12770       break;
12771     case 1:
12772       clib_memcpy (mp->seid, &seid6, sizeof (seid6));
12773       clib_memcpy (mp->deid, &deid6, sizeof (deid6));
12774       break;
12775     case 2:
12776       clib_memcpy (mp->seid, seid_mac, 6);
12777       clib_memcpy (mp->deid, deid_mac, 6);
12778       break;
12779     default:
12780       errmsg ("unknown EID type %d!", mp->eid_type);
12781       return 0;
12782     }
12783
12784   /* send it... */
12785   S;
12786
12787   /* Wait for a reply... */
12788   W;
12789
12790   /* NOTREACHED */
12791   return 0;
12792 }
12793
12794 static int
12795 api_lisp_gpe_add_del_iface (vat_main_t * vam)
12796 {
12797   unformat_input_t *input = vam->input;
12798   vl_api_lisp_gpe_add_del_iface_t *mp;
12799   f64 timeout = ~0;
12800   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
12801   u32 dp_table = 0, vni = 0;
12802
12803   /* Parse args required to build the message */
12804   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12805     {
12806       if (unformat (input, "up"))
12807         {
12808           action_set = 1;
12809           is_add = 1;
12810         }
12811       else if (unformat (input, "down"))
12812         {
12813           action_set = 1;
12814           is_add = 0;
12815         }
12816       else if (unformat (input, "table_id %d", &dp_table))
12817         {
12818           dp_table_set = 1;
12819         }
12820       else if (unformat (input, "bd_id %d", &dp_table))
12821         {
12822           dp_table_set = 1;
12823           is_l2 = 1;
12824         }
12825       else if (unformat (input, "vni %d", &vni))
12826         {
12827           vni_set = 1;
12828         }
12829       else
12830         break;
12831     }
12832
12833   if (action_set == 0)
12834     {
12835       errmsg ("Action not set\n");
12836       return -99;
12837     }
12838   if (dp_table_set == 0 || vni_set == 0)
12839     {
12840       errmsg ("vni and dp_table must be set\n");
12841       return -99;
12842     }
12843
12844   /* Construct the API message */
12845   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
12846
12847   mp->is_add = is_add;
12848   mp->dp_table = dp_table;
12849   mp->is_l2 = is_l2;
12850   mp->vni = vni;
12851
12852   /* send it... */
12853   S;
12854
12855   /* Wait for a reply... */
12856   W;
12857
12858   /* NOTREACHED */
12859   return 0;
12860 }
12861
12862 /**
12863  * Add/del map request itr rlocs from LISP control plane and updates
12864  *
12865  * @param vam vpp API test context
12866  * @return return code
12867  */
12868 static int
12869 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
12870 {
12871   unformat_input_t *input = vam->input;
12872   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
12873   f64 timeout = ~0;
12874   u8 *locator_set_name = 0;
12875   u8 locator_set_name_set = 0;
12876   u8 is_add = 1;
12877
12878   /* Parse args required to build the message */
12879   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12880     {
12881       if (unformat (input, "del"))
12882         {
12883           is_add = 0;
12884         }
12885       else if (unformat (input, "%_%v%_", &locator_set_name))
12886         {
12887           locator_set_name_set = 1;
12888         }
12889       else
12890         {
12891           clib_warning ("parse error '%U'", format_unformat_error, input);
12892           return -99;
12893         }
12894     }
12895
12896   if (is_add && !locator_set_name_set)
12897     {
12898       errmsg ("itr-rloc is not set!");
12899       return -99;
12900     }
12901
12902   if (is_add && vec_len (locator_set_name) > 64)
12903     {
12904       errmsg ("itr-rloc locator-set name too long\n");
12905       vec_free (locator_set_name);
12906       return -99;
12907     }
12908
12909   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
12910   mp->is_add = is_add;
12911   if (is_add)
12912     {
12913       clib_memcpy (mp->locator_set_name, locator_set_name,
12914                    vec_len (locator_set_name));
12915     }
12916   else
12917     {
12918       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
12919     }
12920   vec_free (locator_set_name);
12921
12922   /* send it... */
12923   S;
12924
12925   /* Wait for a reply... */
12926   W;
12927
12928   /* NOTREACHED */
12929   return 0;
12930 }
12931
12932 static int
12933 api_lisp_locator_dump (vat_main_t * vam)
12934 {
12935   unformat_input_t *input = vam->input;
12936   vl_api_lisp_locator_dump_t *mp;
12937   f64 timeout = ~0;
12938   u8 is_index_set = 0, is_name_set = 0;
12939   u8 *ls_name = 0;
12940   u32 ls_index = ~0;
12941
12942   /* Parse args required to build the message */
12943   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12944     {
12945       if (unformat (input, "ls_name %_%v%_", &ls_name))
12946         {
12947           is_name_set = 1;
12948         }
12949       else if (unformat (input, "ls_index %d", &ls_index))
12950         {
12951           is_index_set = 1;
12952         }
12953       else
12954         {
12955           errmsg ("parse error '%U'", format_unformat_error, input);
12956           return -99;
12957         }
12958     }
12959
12960   if (!is_index_set && !is_name_set)
12961     {
12962       errmsg ("error: expected one of index or name!\n");
12963       return -99;
12964     }
12965
12966   if (is_index_set && is_name_set)
12967     {
12968       errmsg ("error: only one param expected!\n");
12969       return -99;
12970     }
12971
12972   if (vec_len (ls_name) > 63)
12973     {
12974       errmsg ("error: locator set name too long!");
12975       return -99;
12976     }
12977
12978   if (!vam->json_output)
12979     {
12980       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
12981                "weight");
12982     }
12983
12984   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
12985   mp->is_index_set = is_index_set;
12986
12987   if (is_index_set)
12988     mp->ls_index = clib_host_to_net_u32 (ls_index);
12989   else
12990     {
12991       vec_add1 (ls_name, 0);
12992       strncpy ((char *) mp->ls_name, (char *) ls_name, sizeof (mp->ls_name));
12993     }
12994
12995   /* send it... */
12996   S;
12997
12998   /* Use a control ping for synchronization */
12999   {
13000     vl_api_control_ping_t *mp;
13001     M (CONTROL_PING, control_ping);
13002     S;
13003   }
13004   /* Wait for a reply... */
13005   W;
13006
13007   /* NOTREACHED */
13008   return 0;
13009 }
13010
13011 static int
13012 api_lisp_locator_set_dump (vat_main_t * vam)
13013 {
13014   vl_api_lisp_locator_set_dump_t *mp;
13015   unformat_input_t *input = vam->input;
13016   f64 timeout = ~0;
13017   u8 filter = 0;
13018
13019   /* Parse args required to build the message */
13020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13021     {
13022       if (unformat (input, "local"))
13023         {
13024           filter = 1;
13025         }
13026       else if (unformat (input, "remote"))
13027         {
13028           filter = 2;
13029         }
13030       else
13031         {
13032           errmsg ("parse error '%U'", format_unformat_error, input);
13033           return -99;
13034         }
13035     }
13036
13037   if (!vam->json_output)
13038     {
13039       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13040     }
13041
13042   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13043
13044   mp->filter = filter;
13045
13046   /* send it... */
13047   S;
13048
13049   /* Use a control ping for synchronization */
13050   {
13051     vl_api_control_ping_t *mp;
13052     M (CONTROL_PING, control_ping);
13053     S;
13054   }
13055   /* Wait for a reply... */
13056   W;
13057
13058   /* NOTREACHED */
13059   return 0;
13060 }
13061
13062 static int
13063 api_lisp_eid_table_map_dump (vat_main_t * vam)
13064 {
13065   u8 is_l2 = 0;
13066   u8 mode_set = 0;
13067   unformat_input_t *input = vam->input;
13068   vl_api_lisp_eid_table_map_dump_t *mp;
13069   f64 timeout = ~0;
13070
13071   /* Parse args required to build the message */
13072   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13073     {
13074       if (unformat (input, "l2"))
13075         {
13076           is_l2 = 1;
13077           mode_set = 1;
13078         }
13079       else if (unformat (input, "l3"))
13080         {
13081           is_l2 = 0;
13082           mode_set = 1;
13083         }
13084       else
13085         {
13086           errmsg ("parse error '%U'", format_unformat_error, input);
13087           return -99;
13088         }
13089     }
13090
13091   if (!mode_set)
13092     {
13093       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13094       return -99;
13095     }
13096
13097   if (!vam->json_output)
13098     {
13099       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13100     }
13101
13102   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13103   mp->is_l2 = is_l2;
13104
13105   /* send it... */
13106   S;
13107
13108   /* Use a control ping for synchronization */
13109   {
13110     vl_api_control_ping_t *mp;
13111     M (CONTROL_PING, control_ping);
13112     S;
13113   }
13114   /* Wait for a reply... */
13115   W;
13116
13117   /* NOTREACHED */
13118   return 0;
13119 }
13120
13121 static int
13122 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13123 {
13124   vl_api_lisp_eid_table_vni_dump_t *mp;
13125   f64 timeout = ~0;
13126
13127   if (!vam->json_output)
13128     {
13129       fformat (vam->ofp, "VNI\n");
13130     }
13131
13132   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13133
13134   /* send it... */
13135   S;
13136
13137   /* Use a control ping for synchronization */
13138   {
13139     vl_api_control_ping_t *mp;
13140     M (CONTROL_PING, control_ping);
13141     S;
13142   }
13143   /* Wait for a reply... */
13144   W;
13145
13146   /* NOTREACHED */
13147   return 0;
13148 }
13149
13150 static int
13151 api_lisp_eid_table_dump (vat_main_t * vam)
13152 {
13153   unformat_input_t *i = vam->input;
13154   vl_api_lisp_eid_table_dump_t *mp;
13155   f64 timeout = ~0;
13156   struct in_addr ip4;
13157   struct in6_addr ip6;
13158   u8 mac[6];
13159   u8 eid_type = ~0, eid_set = 0;
13160   u32 prefix_length = ~0, t, vni = 0;
13161   u8 filter = 0;
13162
13163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13164     {
13165       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13166         {
13167           eid_set = 1;
13168           eid_type = 0;
13169           prefix_length = t;
13170         }
13171       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13172         {
13173           eid_set = 1;
13174           eid_type = 1;
13175           prefix_length = t;
13176         }
13177       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13178         {
13179           eid_set = 1;
13180           eid_type = 2;
13181         }
13182       else if (unformat (i, "vni %d", &t))
13183         {
13184           vni = t;
13185         }
13186       else if (unformat (i, "local"))
13187         {
13188           filter = 1;
13189         }
13190       else if (unformat (i, "remote"))
13191         {
13192           filter = 2;
13193         }
13194       else
13195         {
13196           errmsg ("parse error '%U'", format_unformat_error, i);
13197           return -99;
13198         }
13199     }
13200
13201   if (!vam->json_output)
13202     {
13203       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
13204                "ls_index", "ttl", "authoritative");
13205     }
13206
13207   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13208
13209   mp->filter = filter;
13210   if (eid_set)
13211     {
13212       mp->eid_set = 1;
13213       mp->vni = htonl (vni);
13214       mp->eid_type = eid_type;
13215       switch (eid_type)
13216         {
13217         case 0:
13218           mp->prefix_length = prefix_length;
13219           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13220           break;
13221         case 1:
13222           mp->prefix_length = prefix_length;
13223           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13224           break;
13225         case 2:
13226           clib_memcpy (mp->eid, mac, sizeof (mac));
13227           break;
13228         default:
13229           errmsg ("unknown EID type %d!", eid_type);
13230           return -99;
13231         }
13232     }
13233
13234   /* send it... */
13235   S;
13236
13237   /* Use a control ping for synchronization */
13238   {
13239     vl_api_control_ping_t *mp;
13240     M (CONTROL_PING, control_ping);
13241     S;
13242   }
13243
13244   /* Wait for a reply... */
13245   W;
13246
13247   /* NOTREACHED */
13248   return 0;
13249 }
13250
13251 static int
13252 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13253 {
13254   vl_api_lisp_gpe_tunnel_dump_t *mp;
13255   f64 timeout = ~0;
13256
13257   if (!vam->json_output)
13258     {
13259       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13260                "%=16s%=16s%=16s%=16s%=16s\n",
13261                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13262                "Decap next", "Lisp version", "Flags", "Next protocol",
13263                "ver_res", "res", "iid");
13264     }
13265
13266   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13267   /* send it... */
13268   S;
13269
13270   /* Use a control ping for synchronization */
13271   {
13272     vl_api_control_ping_t *mp;
13273     M (CONTROL_PING, control_ping);
13274     S;
13275   }
13276   /* Wait for a reply... */
13277   W;
13278
13279   /* NOTREACHED */
13280   return 0;
13281 }
13282
13283 static int
13284 api_lisp_map_resolver_dump (vat_main_t * vam)
13285 {
13286   vl_api_lisp_map_resolver_dump_t *mp;
13287   f64 timeout = ~0;
13288
13289   if (!vam->json_output)
13290     {
13291       fformat (vam->ofp, "%=20s\n", "Map resolver");
13292     }
13293
13294   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13295   /* send it... */
13296   S;
13297
13298   /* Use a control ping for synchronization */
13299   {
13300     vl_api_control_ping_t *mp;
13301     M (CONTROL_PING, control_ping);
13302     S;
13303   }
13304   /* Wait for a reply... */
13305   W;
13306
13307   /* NOTREACHED */
13308   return 0;
13309 }
13310
13311 static int
13312 api_show_lisp_status (vat_main_t * vam)
13313 {
13314   vl_api_show_lisp_status_t *mp;
13315   f64 timeout = ~0;
13316
13317   if (!vam->json_output)
13318     {
13319       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13320     }
13321
13322   M (SHOW_LISP_STATUS, show_lisp_status);
13323   /* send it... */
13324   S;
13325   /* Wait for a reply... */
13326   W;
13327
13328   /* NOTREACHED */
13329   return 0;
13330 }
13331
13332 static int
13333 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13334 {
13335   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13336   f64 timeout = ~0;
13337
13338   if (!vam->json_output)
13339     {
13340       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13341     }
13342
13343   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13344   /* send it... */
13345   S;
13346   /* Wait for a reply... */
13347   W;
13348
13349   /* NOTREACHED */
13350   return 0;
13351 }
13352
13353 static int
13354 api_af_packet_create (vat_main_t * vam)
13355 {
13356   unformat_input_t *i = vam->input;
13357   vl_api_af_packet_create_t *mp;
13358   f64 timeout;
13359   u8 *host_if_name = 0;
13360   u8 hw_addr[6];
13361   u8 random_hw_addr = 1;
13362
13363   memset (hw_addr, 0, sizeof (hw_addr));
13364
13365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13366     {
13367       if (unformat (i, "name %s", &host_if_name))
13368         vec_add1 (host_if_name, 0);
13369       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13370         random_hw_addr = 0;
13371       else
13372         break;
13373     }
13374
13375   if (!vec_len (host_if_name))
13376     {
13377       errmsg ("host-interface name must be specified");
13378       return -99;
13379     }
13380
13381   if (vec_len (host_if_name) > 64)
13382     {
13383       errmsg ("host-interface name too long");
13384       return -99;
13385     }
13386
13387   M (AF_PACKET_CREATE, af_packet_create);
13388
13389   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13390   clib_memcpy (mp->hw_addr, hw_addr, 6);
13391   mp->use_random_hw_addr = random_hw_addr;
13392   vec_free (host_if_name);
13393
13394   S;
13395   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
13396   /* NOTREACHED */
13397   return 0;
13398 }
13399
13400 static int
13401 api_af_packet_delete (vat_main_t * vam)
13402 {
13403   unformat_input_t *i = vam->input;
13404   vl_api_af_packet_delete_t *mp;
13405   f64 timeout;
13406   u8 *host_if_name = 0;
13407
13408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13409     {
13410       if (unformat (i, "name %s", &host_if_name))
13411         vec_add1 (host_if_name, 0);
13412       else
13413         break;
13414     }
13415
13416   if (!vec_len (host_if_name))
13417     {
13418       errmsg ("host-interface name must be specified");
13419       return -99;
13420     }
13421
13422   if (vec_len (host_if_name) > 64)
13423     {
13424       errmsg ("host-interface name too long");
13425       return -99;
13426     }
13427
13428   M (AF_PACKET_DELETE, af_packet_delete);
13429
13430   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13431   vec_free (host_if_name);
13432
13433   S;
13434   W;
13435   /* NOTREACHED */
13436   return 0;
13437 }
13438
13439 static int
13440 api_policer_add_del (vat_main_t * vam)
13441 {
13442   unformat_input_t *i = vam->input;
13443   vl_api_policer_add_del_t *mp;
13444   f64 timeout;
13445   u8 is_add = 1;
13446   u8 *name = 0;
13447   u32 cir = 0;
13448   u32 eir = 0;
13449   u64 cb = 0;
13450   u64 eb = 0;
13451   u8 rate_type = 0;
13452   u8 round_type = 0;
13453   u8 type = 0;
13454   u8 color_aware = 0;
13455   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
13456
13457   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
13458   conform_action.dscp = 0;
13459   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
13460   exceed_action.dscp = 0;
13461   violate_action.action_type = SSE2_QOS_ACTION_DROP;
13462   violate_action.dscp = 0;
13463
13464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13465     {
13466       if (unformat (i, "del"))
13467         is_add = 0;
13468       else if (unformat (i, "name %s", &name))
13469         vec_add1 (name, 0);
13470       else if (unformat (i, "cir %u", &cir))
13471         ;
13472       else if (unformat (i, "eir %u", &eir))
13473         ;
13474       else if (unformat (i, "cb %u", &cb))
13475         ;
13476       else if (unformat (i, "eb %u", &eb))
13477         ;
13478       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
13479                          &rate_type))
13480         ;
13481       else if (unformat (i, "round_type %U", unformat_policer_round_type,
13482                          &round_type))
13483         ;
13484       else if (unformat (i, "type %U", unformat_policer_type, &type))
13485         ;
13486       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
13487                          &conform_action))
13488         ;
13489       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
13490                          &exceed_action))
13491         ;
13492       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
13493                          &violate_action))
13494         ;
13495       else if (unformat (i, "color-aware"))
13496         color_aware = 1;
13497       else
13498         break;
13499     }
13500
13501   if (!vec_len (name))
13502     {
13503       errmsg ("policer name must be specified");
13504       return -99;
13505     }
13506
13507   if (vec_len (name) > 64)
13508     {
13509       errmsg ("policer name too long");
13510       return -99;
13511     }
13512
13513   M (POLICER_ADD_DEL, policer_add_del);
13514
13515   clib_memcpy (mp->name, name, vec_len (name));
13516   vec_free (name);
13517   mp->is_add = is_add;
13518   mp->cir = cir;
13519   mp->eir = eir;
13520   mp->cb = cb;
13521   mp->eb = eb;
13522   mp->rate_type = rate_type;
13523   mp->round_type = round_type;
13524   mp->type = type;
13525   mp->conform_action_type = conform_action.action_type;
13526   mp->conform_dscp = conform_action.dscp;
13527   mp->exceed_action_type = exceed_action.action_type;
13528   mp->exceed_dscp = exceed_action.dscp;
13529   mp->violate_action_type = violate_action.action_type;
13530   mp->violate_dscp = violate_action.dscp;
13531   mp->color_aware = color_aware;
13532
13533   S;
13534   W;
13535   /* NOTREACHED */
13536   return 0;
13537 }
13538
13539 static int
13540 api_policer_dump (vat_main_t * vam)
13541 {
13542   unformat_input_t *i = vam->input;
13543   vl_api_policer_dump_t *mp;
13544   f64 timeout = ~0;
13545   u8 *match_name = 0;
13546   u8 match_name_valid = 0;
13547
13548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13549     {
13550       if (unformat (i, "name %s", &match_name))
13551         {
13552           vec_add1 (match_name, 0);
13553           match_name_valid = 1;
13554         }
13555       else
13556         break;
13557     }
13558
13559   M (POLICER_DUMP, policer_dump);
13560   mp->match_name_valid = match_name_valid;
13561   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
13562   vec_free (match_name);
13563   /* send it... */
13564   S;
13565
13566   /* Use a control ping for synchronization */
13567   {
13568     vl_api_control_ping_t *mp;
13569     M (CONTROL_PING, control_ping);
13570     S;
13571   }
13572   /* Wait for a reply... */
13573   W;
13574
13575   /* NOTREACHED */
13576   return 0;
13577 }
13578
13579 static int
13580 api_policer_classify_set_interface (vat_main_t * vam)
13581 {
13582   unformat_input_t *i = vam->input;
13583   vl_api_policer_classify_set_interface_t *mp;
13584   f64 timeout;
13585   u32 sw_if_index;
13586   int sw_if_index_set;
13587   u32 ip4_table_index = ~0;
13588   u32 ip6_table_index = ~0;
13589   u32 l2_table_index = ~0;
13590   u8 is_add = 1;
13591
13592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13593     {
13594       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
13595         sw_if_index_set = 1;
13596       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13597         sw_if_index_set = 1;
13598       else if (unformat (i, "del"))
13599         is_add = 0;
13600       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13601         ;
13602       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13603         ;
13604       else if (unformat (i, "l2-table %d", &l2_table_index))
13605         ;
13606       else
13607         {
13608           clib_warning ("parse error '%U'", format_unformat_error, i);
13609           return -99;
13610         }
13611     }
13612
13613   if (sw_if_index_set == 0)
13614     {
13615       errmsg ("missing interface name or sw_if_index\n");
13616       return -99;
13617     }
13618
13619   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
13620
13621   mp->sw_if_index = ntohl (sw_if_index);
13622   mp->ip4_table_index = ntohl (ip4_table_index);
13623   mp->ip6_table_index = ntohl (ip6_table_index);
13624   mp->l2_table_index = ntohl (l2_table_index);
13625   mp->is_add = is_add;
13626
13627   S;
13628   W;
13629   /* NOTREACHED */
13630   return 0;
13631 }
13632
13633 static int
13634 api_policer_classify_dump (vat_main_t * vam)
13635 {
13636   unformat_input_t *i = vam->input;
13637   vl_api_policer_classify_dump_t *mp;
13638   f64 timeout = ~0;
13639   u8 type = POLICER_CLASSIFY_N_TABLES;
13640
13641   if (unformat (i, "type %U", unformat_classify_table_type, &type))
13642     ;
13643   else
13644     {
13645       errmsg ("classify table type must be specified\n");
13646       return -99;
13647     }
13648
13649   if (!vam->json_output)
13650     {
13651       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
13652     }
13653
13654   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
13655   mp->type = type;
13656   /* send it... */
13657   S;
13658
13659   /* Use a control ping for synchronization */
13660   {
13661     vl_api_control_ping_t *mp;
13662     M (CONTROL_PING, control_ping);
13663     S;
13664   }
13665   /* Wait for a reply... */
13666   W;
13667
13668   /* NOTREACHED */
13669   return 0;
13670 }
13671
13672 static int
13673 api_netmap_create (vat_main_t * vam)
13674 {
13675   unformat_input_t *i = vam->input;
13676   vl_api_netmap_create_t *mp;
13677   f64 timeout;
13678   u8 *if_name = 0;
13679   u8 hw_addr[6];
13680   u8 random_hw_addr = 1;
13681   u8 is_pipe = 0;
13682   u8 is_master = 0;
13683
13684   memset (hw_addr, 0, sizeof (hw_addr));
13685
13686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13687     {
13688       if (unformat (i, "name %s", &if_name))
13689         vec_add1 (if_name, 0);
13690       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13691         random_hw_addr = 0;
13692       else if (unformat (i, "pipe"))
13693         is_pipe = 1;
13694       else if (unformat (i, "master"))
13695         is_master = 1;
13696       else if (unformat (i, "slave"))
13697         is_master = 0;
13698       else
13699         break;
13700     }
13701
13702   if (!vec_len (if_name))
13703     {
13704       errmsg ("interface name must be specified");
13705       return -99;
13706     }
13707
13708   if (vec_len (if_name) > 64)
13709     {
13710       errmsg ("interface name too long");
13711       return -99;
13712     }
13713
13714   M (NETMAP_CREATE, netmap_create);
13715
13716   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
13717   clib_memcpy (mp->hw_addr, hw_addr, 6);
13718   mp->use_random_hw_addr = random_hw_addr;
13719   mp->is_pipe = is_pipe;
13720   mp->is_master = is_master;
13721   vec_free (if_name);
13722
13723   S;
13724   W;
13725   /* NOTREACHED */
13726   return 0;
13727 }
13728
13729 static int
13730 api_netmap_delete (vat_main_t * vam)
13731 {
13732   unformat_input_t *i = vam->input;
13733   vl_api_netmap_delete_t *mp;
13734   f64 timeout;
13735   u8 *if_name = 0;
13736
13737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13738     {
13739       if (unformat (i, "name %s", &if_name))
13740         vec_add1 (if_name, 0);
13741       else
13742         break;
13743     }
13744
13745   if (!vec_len (if_name))
13746     {
13747       errmsg ("interface name must be specified");
13748       return -99;
13749     }
13750
13751   if (vec_len (if_name) > 64)
13752     {
13753       errmsg ("interface name too long");
13754       return -99;
13755     }
13756
13757   M (NETMAP_DELETE, netmap_delete);
13758
13759   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
13760   vec_free (if_name);
13761
13762   S;
13763   W;
13764   /* NOTREACHED */
13765   return 0;
13766 }
13767
13768 static void vl_api_mpls_gre_tunnel_details_t_handler
13769   (vl_api_mpls_gre_tunnel_details_t * mp)
13770 {
13771   vat_main_t *vam = &vat_main;
13772   i32 i;
13773   i32 len = ntohl (mp->nlabels);
13774
13775   if (mp->l2_only == 0)
13776     {
13777       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
13778                ntohl (mp->tunnel_index),
13779                format_ip4_address, &mp->tunnel_src,
13780                format_ip4_address, &mp->tunnel_dst,
13781                format_ip4_address, &mp->intfc_address,
13782                ntohl (mp->mask_width));
13783       for (i = 0; i < len; i++)
13784         {
13785           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
13786         }
13787       fformat (vam->ofp, "\n");
13788       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
13789                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
13790     }
13791   else
13792     {
13793       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
13794                ntohl (mp->tunnel_index),
13795                format_ip4_address, &mp->tunnel_src,
13796                format_ip4_address, &mp->tunnel_dst,
13797                format_ip4_address, &mp->intfc_address);
13798       for (i = 0; i < len; i++)
13799         {
13800           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
13801         }
13802       fformat (vam->ofp, "\n");
13803       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
13804                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
13805     }
13806 }
13807
13808 static void vl_api_mpls_gre_tunnel_details_t_handler_json
13809   (vl_api_mpls_gre_tunnel_details_t * mp)
13810 {
13811   vat_main_t *vam = &vat_main;
13812   vat_json_node_t *node = NULL;
13813   struct in_addr ip4;
13814   i32 i;
13815   i32 len = ntohl (mp->nlabels);
13816
13817   if (VAT_JSON_ARRAY != vam->json_tree.type)
13818     {
13819       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13820       vat_json_init_array (&vam->json_tree);
13821     }
13822   node = vat_json_array_add (&vam->json_tree);
13823
13824   vat_json_init_object (node);
13825   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
13826   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
13827   vat_json_object_add_ip4 (node, "intfc_address", ip4);
13828   vat_json_object_add_uint (node, "inner_fib_index",
13829                             ntohl (mp->inner_fib_index));
13830   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
13831   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
13832   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
13833   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
13834   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
13835   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
13836   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
13837   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
13838   vat_json_object_add_uint (node, "outer_fib_index",
13839                             ntohl (mp->outer_fib_index));
13840   vat_json_object_add_uint (node, "label_count", len);
13841   for (i = 0; i < len; i++)
13842     {
13843       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
13844     }
13845 }
13846
13847 static int
13848 api_mpls_gre_tunnel_dump (vat_main_t * vam)
13849 {
13850   vl_api_mpls_gre_tunnel_dump_t *mp;
13851   f64 timeout;
13852   i32 index = -1;
13853
13854   /* Parse args required to build the message */
13855   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
13856     {
13857       if (!unformat (vam->input, "tunnel_index %d", &index))
13858         {
13859           index = -1;
13860           break;
13861         }
13862     }
13863
13864   fformat (vam->ofp, "  tunnel_index %d\n", index);
13865
13866   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
13867   mp->tunnel_index = htonl (index);
13868   S;
13869
13870   /* Use a control ping for synchronization */
13871   {
13872     vl_api_control_ping_t *mp;
13873     M (CONTROL_PING, control_ping);
13874     S;
13875   }
13876   W;
13877 }
13878
13879 static void vl_api_mpls_eth_tunnel_details_t_handler
13880   (vl_api_mpls_eth_tunnel_details_t * mp)
13881 {
13882   vat_main_t *vam = &vat_main;
13883   i32 i;
13884   i32 len = ntohl (mp->nlabels);
13885
13886   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
13887            ntohl (mp->tunnel_index),
13888            format_ethernet_address, &mp->tunnel_dst_mac,
13889            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
13890   for (i = 0; i < len; i++)
13891     {
13892       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
13893     }
13894   fformat (vam->ofp, "\n");
13895   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
13896            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
13897 }
13898
13899 static void vl_api_mpls_eth_tunnel_details_t_handler_json
13900   (vl_api_mpls_eth_tunnel_details_t * mp)
13901 {
13902   vat_main_t *vam = &vat_main;
13903   vat_json_node_t *node = NULL;
13904   struct in_addr ip4;
13905   i32 i;
13906   i32 len = ntohl (mp->nlabels);
13907
13908   if (VAT_JSON_ARRAY != vam->json_tree.type)
13909     {
13910       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13911       vat_json_init_array (&vam->json_tree);
13912     }
13913   node = vat_json_array_add (&vam->json_tree);
13914
13915   vat_json_init_object (node);
13916   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
13917   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
13918   vat_json_object_add_ip4 (node, "intfc_address", ip4);
13919   vat_json_object_add_uint (node, "inner_fib_index",
13920                             ntohl (mp->inner_fib_index));
13921   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
13922   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
13923   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
13924   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
13925   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
13926                                    format (0, "%U", format_ethernet_address,
13927                                            &mp->tunnel_dst_mac));
13928   vat_json_object_add_uint (node, "tx_sw_if_index",
13929                             ntohl (mp->tx_sw_if_index));
13930   vat_json_object_add_uint (node, "label_count", len);
13931   for (i = 0; i < len; i++)
13932     {
13933       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
13934     }
13935 }
13936
13937 static int
13938 api_mpls_eth_tunnel_dump (vat_main_t * vam)
13939 {
13940   vl_api_mpls_eth_tunnel_dump_t *mp;
13941   f64 timeout;
13942   i32 index = -1;
13943
13944   /* Parse args required to build the message */
13945   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
13946     {
13947       if (!unformat (vam->input, "tunnel_index %d", &index))
13948         {
13949           index = -1;
13950           break;
13951         }
13952     }
13953
13954   fformat (vam->ofp, "  tunnel_index %d\n", index);
13955
13956   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
13957   mp->tunnel_index = htonl (index);
13958   S;
13959
13960   /* Use a control ping for synchronization */
13961   {
13962     vl_api_control_ping_t *mp;
13963     M (CONTROL_PING, control_ping);
13964     S;
13965   }
13966   W;
13967 }
13968
13969 static void vl_api_mpls_fib_encap_details_t_handler
13970   (vl_api_mpls_fib_encap_details_t * mp)
13971 {
13972   vat_main_t *vam = &vat_main;
13973   i32 i;
13974   i32 len = ntohl (mp->nlabels);
13975
13976   fformat (vam->ofp, "table %d, dest %U, label ",
13977            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
13978   for (i = 0; i < len; i++)
13979     {
13980       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
13981     }
13982   fformat (vam->ofp, "\n");
13983 }
13984
13985 static void vl_api_mpls_fib_encap_details_t_handler_json
13986   (vl_api_mpls_fib_encap_details_t * mp)
13987 {
13988   vat_main_t *vam = &vat_main;
13989   vat_json_node_t *node = NULL;
13990   i32 i;
13991   i32 len = ntohl (mp->nlabels);
13992   struct in_addr ip4;
13993
13994   if (VAT_JSON_ARRAY != vam->json_tree.type)
13995     {
13996       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13997       vat_json_init_array (&vam->json_tree);
13998     }
13999   node = vat_json_array_add (&vam->json_tree);
14000
14001   vat_json_init_object (node);
14002   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14003   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14004   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14005   vat_json_object_add_ip4 (node, "dest", ip4);
14006   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14007   vat_json_object_add_uint (node, "label_count", len);
14008   for (i = 0; i < len; i++)
14009     {
14010       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14011     }
14012 }
14013
14014 static int
14015 api_mpls_fib_encap_dump (vat_main_t * vam)
14016 {
14017   vl_api_mpls_fib_encap_dump_t *mp;
14018   f64 timeout;
14019
14020   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14021   S;
14022
14023   /* Use a control ping for synchronization */
14024   {
14025     vl_api_control_ping_t *mp;
14026     M (CONTROL_PING, control_ping);
14027     S;
14028   }
14029   W;
14030 }
14031
14032 static void vl_api_mpls_fib_decap_details_t_handler
14033   (vl_api_mpls_fib_decap_details_t * mp)
14034 {
14035   vat_main_t *vam = &vat_main;
14036
14037   fformat (vam->ofp,
14038            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14039            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14040            ntohl (mp->label), ntohl (mp->s_bit));
14041 }
14042
14043 static void vl_api_mpls_fib_decap_details_t_handler_json
14044   (vl_api_mpls_fib_decap_details_t * mp)
14045 {
14046   vat_main_t *vam = &vat_main;
14047   vat_json_node_t *node = NULL;
14048   struct in_addr ip4;
14049
14050   if (VAT_JSON_ARRAY != vam->json_tree.type)
14051     {
14052       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14053       vat_json_init_array (&vam->json_tree);
14054     }
14055   node = vat_json_array_add (&vam->json_tree);
14056
14057   vat_json_init_object (node);
14058   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14059   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14060   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14061   vat_json_object_add_ip4 (node, "dest", ip4);
14062   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14063   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14064   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14065   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14066   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14067 }
14068
14069 static int
14070 api_mpls_fib_decap_dump (vat_main_t * vam)
14071 {
14072   vl_api_mpls_fib_decap_dump_t *mp;
14073   f64 timeout;
14074
14075   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14076   S;
14077
14078   /* Use a control ping for synchronization */
14079   {
14080     vl_api_control_ping_t *mp;
14081     M (CONTROL_PING, control_ping);
14082     S;
14083   }
14084   W;
14085 }
14086
14087 int
14088 api_classify_table_ids (vat_main_t * vam)
14089 {
14090   vl_api_classify_table_ids_t *mp;
14091   f64 timeout;
14092
14093   /* Construct the API message */
14094   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14095   mp->context = 0;
14096
14097   S;
14098   W;
14099   /* NOTREACHED */
14100   return 0;
14101 }
14102
14103 int
14104 api_classify_table_by_interface (vat_main_t * vam)
14105 {
14106   unformat_input_t *input = vam->input;
14107   vl_api_classify_table_by_interface_t *mp;
14108   f64 timeout;
14109
14110   u32 sw_if_index = ~0;
14111   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14112     {
14113       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14114         ;
14115       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14116         ;
14117       else
14118         break;
14119     }
14120   if (sw_if_index == ~0)
14121     {
14122       errmsg ("missing interface name or sw_if_index\n");
14123       return -99;
14124     }
14125
14126   /* Construct the API message */
14127   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14128   mp->context = 0;
14129   mp->sw_if_index = ntohl (sw_if_index);
14130
14131   S;
14132   W;
14133   /* NOTREACHED */
14134   return 0;
14135 }
14136
14137 int
14138 api_classify_table_info (vat_main_t * vam)
14139 {
14140   unformat_input_t *input = vam->input;
14141   vl_api_classify_table_info_t *mp;
14142   f64 timeout;
14143
14144   u32 table_id = ~0;
14145   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14146     {
14147       if (unformat (input, "table_id %d", &table_id))
14148         ;
14149       else
14150         break;
14151     }
14152   if (table_id == ~0)
14153     {
14154       errmsg ("missing table id\n");
14155       return -99;
14156     }
14157
14158   /* Construct the API message */
14159   M (CLASSIFY_TABLE_INFO, classify_table_info);
14160   mp->context = 0;
14161   mp->table_id = ntohl (table_id);
14162
14163   S;
14164   W;
14165   /* NOTREACHED */
14166   return 0;
14167 }
14168
14169 int
14170 api_classify_session_dump (vat_main_t * vam)
14171 {
14172   unformat_input_t *input = vam->input;
14173   vl_api_classify_session_dump_t *mp;
14174   f64 timeout;
14175
14176   u32 table_id = ~0;
14177   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14178     {
14179       if (unformat (input, "table_id %d", &table_id))
14180         ;
14181       else
14182         break;
14183     }
14184   if (table_id == ~0)
14185     {
14186       errmsg ("missing table id\n");
14187       return -99;
14188     }
14189
14190   /* Construct the API message */
14191   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14192   mp->context = 0;
14193   mp->table_id = ntohl (table_id);
14194   S;
14195
14196   /* Use a control ping for synchronization */
14197   {
14198     vl_api_control_ping_t *mp;
14199     M (CONTROL_PING, control_ping);
14200     S;
14201   }
14202   W;
14203   /* NOTREACHED */
14204   return 0;
14205 }
14206
14207 static void
14208 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
14209 {
14210   vat_main_t *vam = &vat_main;
14211
14212   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14213            "src_address %U, vrf_id %d, path_mtu %u, "
14214            "template_interval %u, udp_checksum %d\n",
14215            format_ip4_address, mp->collector_address,
14216            ntohs (mp->collector_port),
14217            format_ip4_address, mp->src_address,
14218            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
14219            ntohl (mp->template_interval), mp->udp_checksum);
14220
14221   vam->retval = 0;
14222   vam->result_ready = 1;
14223 }
14224
14225 static void
14226   vl_api_ipfix_exporter_details_t_handler_json
14227   (vl_api_ipfix_exporter_details_t * mp)
14228 {
14229   vat_main_t *vam = &vat_main;
14230   vat_json_node_t node;
14231   struct in_addr collector_address;
14232   struct in_addr src_address;
14233
14234   vat_json_init_object (&node);
14235   clib_memcpy (&collector_address, &mp->collector_address,
14236                sizeof (collector_address));
14237   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14238   vat_json_object_add_uint (&node, "collector_port",
14239                             ntohs (mp->collector_port));
14240   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14241   vat_json_object_add_ip4 (&node, "src_address", src_address);
14242   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
14243   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14244   vat_json_object_add_uint (&node, "template_interval",
14245                             ntohl (mp->template_interval));
14246   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
14247
14248   vat_json_print (vam->ofp, &node);
14249   vat_json_free (&node);
14250   vam->retval = 0;
14251   vam->result_ready = 1;
14252 }
14253
14254 int
14255 api_ipfix_exporter_dump (vat_main_t * vam)
14256 {
14257   vl_api_ipfix_exporter_dump_t *mp;
14258   f64 timeout;
14259
14260   /* Construct the API message */
14261   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
14262   mp->context = 0;
14263
14264   S;
14265   W;
14266   /* NOTREACHED */
14267   return 0;
14268 }
14269
14270 static int
14271 api_ipfix_classify_stream_dump (vat_main_t * vam)
14272 {
14273   vl_api_ipfix_classify_stream_dump_t *mp;
14274   f64 timeout;
14275
14276   /* Construct the API message */
14277   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
14278   mp->context = 0;
14279
14280   S;
14281   W;
14282   /* NOTREACHED */
14283   return 0;
14284 }
14285
14286 static void
14287   vl_api_ipfix_classify_stream_details_t_handler
14288   (vl_api_ipfix_classify_stream_details_t * mp)
14289 {
14290   vat_main_t *vam = &vat_main;
14291   fformat (vam->ofp, "domain_id %d, src_port %d\n",
14292            ntohl (mp->domain_id), ntohs (mp->src_port));
14293   vam->retval = 0;
14294   vam->result_ready = 1;
14295 }
14296
14297 static void
14298   vl_api_ipfix_classify_stream_details_t_handler_json
14299   (vl_api_ipfix_classify_stream_details_t * mp)
14300 {
14301   vat_main_t *vam = &vat_main;
14302   vat_json_node_t node;
14303
14304   vat_json_init_object (&node);
14305   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
14306   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
14307
14308   vat_json_print (vam->ofp, &node);
14309   vat_json_free (&node);
14310   vam->retval = 0;
14311   vam->result_ready = 1;
14312 }
14313
14314 static int
14315 api_ipfix_classify_table_dump (vat_main_t * vam)
14316 {
14317   vl_api_ipfix_classify_table_dump_t *mp;
14318   f64 timeout;
14319
14320   if (!vam->json_output)
14321     {
14322       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
14323                "transport_protocol");
14324     }
14325
14326   /* Construct the API message */
14327   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
14328
14329   /* send it... */
14330   S;
14331
14332   /* Use a control ping for synchronization */
14333   {
14334     vl_api_control_ping_t *mp;
14335     M (CONTROL_PING, control_ping);
14336     S;
14337   }
14338   W;
14339 }
14340
14341 static void
14342   vl_api_ipfix_classify_table_details_t_handler
14343   (vl_api_ipfix_classify_table_details_t * mp)
14344 {
14345   vat_main_t *vam = &vat_main;
14346   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
14347            mp->transport_protocol);
14348 }
14349
14350 static void
14351   vl_api_ipfix_classify_table_details_t_handler_json
14352   (vl_api_ipfix_classify_table_details_t * mp)
14353 {
14354   vat_json_node_t *node = NULL;
14355   vat_main_t *vam = &vat_main;
14356
14357   if (VAT_JSON_ARRAY != vam->json_tree.type)
14358     {
14359       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14360       vat_json_init_array (&vam->json_tree);
14361     }
14362
14363   node = vat_json_array_add (&vam->json_tree);
14364   vat_json_init_object (node);
14365
14366   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
14367   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
14368   vat_json_object_add_uint (node, "transport_protocol",
14369                             mp->transport_protocol);
14370 }
14371
14372 int
14373 api_pg_create_interface (vat_main_t * vam)
14374 {
14375   unformat_input_t *input = vam->input;
14376   vl_api_pg_create_interface_t *mp;
14377   f64 timeout;
14378
14379   u32 if_id = ~0;
14380   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14381     {
14382       if (unformat (input, "if_id %d", &if_id))
14383         ;
14384       else
14385         break;
14386     }
14387   if (if_id == ~0)
14388     {
14389       errmsg ("missing pg interface index\n");
14390       return -99;
14391     }
14392
14393   /* Construct the API message */
14394   M (PG_CREATE_INTERFACE, pg_create_interface);
14395   mp->context = 0;
14396   mp->interface_id = ntohl (if_id);
14397
14398   S;
14399   W;
14400   /* NOTREACHED */
14401   return 0;
14402 }
14403
14404 int
14405 api_pg_capture (vat_main_t * vam)
14406 {
14407   unformat_input_t *input = vam->input;
14408   vl_api_pg_capture_t *mp;
14409   f64 timeout;
14410
14411   u32 if_id = ~0;
14412   u8 enable = 1;
14413   u32 count = 1;
14414   u8 pcap_file_set = 0;
14415   u8 *pcap_file = 0;
14416   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14417     {
14418       if (unformat (input, "if_id %d", &if_id))
14419         ;
14420       else if (unformat (input, "pcap %s", &pcap_file))
14421         pcap_file_set = 1;
14422       else if (unformat (input, "count %d", &count))
14423         ;
14424       else if (unformat (input, "disable"))
14425         enable = 0;
14426       else
14427         break;
14428     }
14429   if (if_id == ~0)
14430     {
14431       errmsg ("missing pg interface index\n");
14432       return -99;
14433     }
14434   if (pcap_file_set > 0)
14435     {
14436       if (vec_len (pcap_file) > 255)
14437         {
14438           errmsg ("pcap file name is too long\n");
14439           return -99;
14440         }
14441     }
14442
14443   u32 name_len = vec_len (pcap_file);
14444   /* Construct the API message */
14445   M (PG_CAPTURE, pg_capture);
14446   mp->context = 0;
14447   mp->interface_id = ntohl (if_id);
14448   mp->is_enabled = enable;
14449   mp->count = ntohl (count);
14450   mp->pcap_name_length = ntohl (name_len);
14451   if (pcap_file_set != 0)
14452     {
14453       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
14454     }
14455   vec_free (pcap_file);
14456
14457   S;
14458   W;
14459   /* NOTREACHED */
14460   return 0;
14461 }
14462
14463 int
14464 api_pg_enable_disable (vat_main_t * vam)
14465 {
14466   unformat_input_t *input = vam->input;
14467   vl_api_pg_enable_disable_t *mp;
14468   f64 timeout;
14469
14470   u8 enable = 1;
14471   u8 stream_name_set = 0;
14472   u8 *stream_name = 0;
14473   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14474     {
14475       if (unformat (input, "stream %s", &stream_name))
14476         stream_name_set = 1;
14477       else if (unformat (input, "disable"))
14478         enable = 0;
14479       else
14480         break;
14481     }
14482
14483   if (stream_name_set > 0)
14484     {
14485       if (vec_len (stream_name) > 255)
14486         {
14487           errmsg ("stream name too long\n");
14488           return -99;
14489         }
14490     }
14491
14492   u32 name_len = vec_len (stream_name);
14493   /* Construct the API message */
14494   M (PG_ENABLE_DISABLE, pg_enable_disable);
14495   mp->context = 0;
14496   mp->is_enabled = enable;
14497   if (stream_name_set != 0)
14498     {
14499       mp->stream_name_length = ntohl (name_len);
14500       clib_memcpy (mp->stream_name, stream_name, name_len);
14501     }
14502   vec_free (stream_name);
14503
14504   S;
14505   W;
14506   /* NOTREACHED */
14507   return 0;
14508 }
14509
14510 int
14511 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
14512 {
14513   unformat_input_t *input = vam->input;
14514   vl_api_ip_source_and_port_range_check_add_del_t *mp;
14515   f64 timeout;
14516
14517   u16 *low_ports = 0;
14518   u16 *high_ports = 0;
14519   u16 this_low;
14520   u16 this_hi;
14521   ip4_address_t ip4_addr;
14522   ip6_address_t ip6_addr;
14523   u32 length;
14524   u32 tmp, tmp2;
14525   u8 prefix_set = 0;
14526   u32 vrf_id = ~0;
14527   u8 is_add = 1;
14528   u8 is_ipv6 = 0;
14529
14530   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14531     {
14532       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
14533         {
14534           prefix_set = 1;
14535         }
14536       else
14537         if (unformat
14538             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
14539         {
14540           prefix_set = 1;
14541           is_ipv6 = 1;
14542         }
14543       else if (unformat (input, "vrf %d", &vrf_id))
14544         ;
14545       else if (unformat (input, "del"))
14546         is_add = 0;
14547       else if (unformat (input, "port %d", &tmp))
14548         {
14549           if (tmp == 0 || tmp > 65535)
14550             {
14551               errmsg ("port %d out of range", tmp);
14552               return -99;
14553             }
14554           this_low = tmp;
14555           this_hi = this_low + 1;
14556           vec_add1 (low_ports, this_low);
14557           vec_add1 (high_ports, this_hi);
14558         }
14559       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
14560         {
14561           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
14562             {
14563               errmsg ("incorrect range parameters\n");
14564               return -99;
14565             }
14566           this_low = tmp;
14567           /* Note: in debug CLI +1 is added to high before
14568              passing to real fn that does "the work"
14569              (ip_source_and_port_range_check_add_del).
14570              This fn is a wrapper around the binary API fn a
14571              control plane will call, which expects this increment
14572              to have occurred. Hence letting the binary API control
14573              plane fn do the increment for consistency between VAT
14574              and other control planes.
14575            */
14576           this_hi = tmp2;
14577           vec_add1 (low_ports, this_low);
14578           vec_add1 (high_ports, this_hi);
14579         }
14580       else
14581         break;
14582     }
14583
14584   if (prefix_set == 0)
14585     {
14586       errmsg ("<address>/<mask> not specified\n");
14587       return -99;
14588     }
14589
14590   if (vrf_id == ~0)
14591     {
14592       errmsg ("VRF ID required, not specified\n");
14593       return -99;
14594     }
14595
14596   if (vrf_id == 0)
14597     {
14598       errmsg
14599         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
14600       return -99;
14601     }
14602
14603   if (vec_len (low_ports) == 0)
14604     {
14605       errmsg ("At least one port or port range required\n");
14606       return -99;
14607     }
14608
14609   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
14610      ip_source_and_port_range_check_add_del);
14611
14612   mp->is_add = is_add;
14613
14614   if (is_ipv6)
14615     {
14616       mp->is_ipv6 = 1;
14617       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
14618     }
14619   else
14620     {
14621       mp->is_ipv6 = 0;
14622       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
14623     }
14624
14625   mp->mask_length = length;
14626   mp->number_of_ranges = vec_len (low_ports);
14627
14628   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
14629   vec_free (low_ports);
14630
14631   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
14632   vec_free (high_ports);
14633
14634   mp->vrf_id = ntohl (vrf_id);
14635
14636   S;
14637   W;
14638   /* NOTREACHED */
14639   return 0;
14640 }
14641
14642 int
14643 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
14644 {
14645   unformat_input_t *input = vam->input;
14646   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
14647   f64 timeout;
14648   u32 sw_if_index = ~0;
14649   int vrf_set = 0;
14650   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
14651   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
14652   u8 is_add = 1;
14653
14654   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14655     {
14656       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14657         ;
14658       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14659         ;
14660       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
14661         vrf_set = 1;
14662       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
14663         vrf_set = 1;
14664       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
14665         vrf_set = 1;
14666       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
14667         vrf_set = 1;
14668       else if (unformat (input, "del"))
14669         is_add = 0;
14670       else
14671         break;
14672     }
14673
14674   if (sw_if_index == ~0)
14675     {
14676       errmsg ("Interface required but not specified\n");
14677       return -99;
14678     }
14679
14680   if (vrf_set == 0)
14681     {
14682       errmsg ("VRF ID required but not specified\n");
14683       return -99;
14684     }
14685
14686   if (tcp_out_vrf_id == 0
14687       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
14688     {
14689       errmsg
14690         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
14691       return -99;
14692     }
14693
14694   /* Construct the API message */
14695   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
14696      ip_source_and_port_range_check_interface_add_del);
14697
14698   mp->sw_if_index = ntohl (sw_if_index);
14699   mp->is_add = is_add;
14700   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
14701   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
14702   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
14703   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
14704
14705   /* send it... */
14706   S;
14707
14708   /* Wait for a reply... */
14709   W;
14710 }
14711
14712 static int
14713 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
14714 {
14715   unformat_input_t *i = vam->input;
14716   vl_api_ipsec_gre_add_del_tunnel_t *mp;
14717   f64 timeout;
14718   u32 local_sa_id = 0;
14719   u32 remote_sa_id = 0;
14720   ip4_address_t src_address;
14721   ip4_address_t dst_address;
14722   u8 is_add = 1;
14723
14724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14725     {
14726       if (unformat (i, "local_sa %d", &local_sa_id))
14727         ;
14728       else if (unformat (i, "remote_sa %d", &remote_sa_id))
14729         ;
14730       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
14731         ;
14732       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
14733         ;
14734       else if (unformat (i, "del"))
14735         is_add = 0;
14736       else
14737         {
14738           clib_warning ("parse error '%U'", format_unformat_error, i);
14739           return -99;
14740         }
14741     }
14742
14743   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
14744
14745   mp->local_sa_id = ntohl (local_sa_id);
14746   mp->remote_sa_id = ntohl (remote_sa_id);
14747   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
14748   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
14749   mp->is_add = is_add;
14750
14751   S;
14752   W;
14753   /* NOTREACHED */
14754   return 0;
14755 }
14756
14757 static void vl_api_ipsec_gre_tunnel_details_t_handler
14758   (vl_api_ipsec_gre_tunnel_details_t * mp)
14759 {
14760   vat_main_t *vam = &vat_main;
14761
14762   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
14763            ntohl (mp->sw_if_index),
14764            format_ip4_address, &mp->src_address,
14765            format_ip4_address, &mp->dst_address,
14766            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
14767 }
14768
14769 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
14770   (vl_api_ipsec_gre_tunnel_details_t * mp)
14771 {
14772   vat_main_t *vam = &vat_main;
14773   vat_json_node_t *node = NULL;
14774   struct in_addr ip4;
14775
14776   if (VAT_JSON_ARRAY != vam->json_tree.type)
14777     {
14778       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14779       vat_json_init_array (&vam->json_tree);
14780     }
14781   node = vat_json_array_add (&vam->json_tree);
14782
14783   vat_json_init_object (node);
14784   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14785   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
14786   vat_json_object_add_ip4 (node, "src_address", ip4);
14787   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
14788   vat_json_object_add_ip4 (node, "dst_address", ip4);
14789   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
14790   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
14791 }
14792
14793 static int
14794 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
14795 {
14796   unformat_input_t *i = vam->input;
14797   vl_api_ipsec_gre_tunnel_dump_t *mp;
14798   f64 timeout;
14799   u32 sw_if_index;
14800   u8 sw_if_index_set = 0;
14801
14802   /* Parse args required to build the message */
14803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14804     {
14805       if (unformat (i, "sw_if_index %d", &sw_if_index))
14806         sw_if_index_set = 1;
14807       else
14808         break;
14809     }
14810
14811   if (sw_if_index_set == 0)
14812     {
14813       sw_if_index = ~0;
14814     }
14815
14816   if (!vam->json_output)
14817     {
14818       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
14819                "sw_if_index", "src_address", "dst_address",
14820                "local_sa_id", "remote_sa_id");
14821     }
14822
14823   /* Get list of gre-tunnel interfaces */
14824   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
14825
14826   mp->sw_if_index = htonl (sw_if_index);
14827
14828   S;
14829
14830   /* Use a control ping for synchronization */
14831   {
14832     vl_api_control_ping_t *mp;
14833     M (CONTROL_PING, control_ping);
14834     S;
14835   }
14836   W;
14837 }
14838
14839 static int
14840 api_delete_subif (vat_main_t * vam)
14841 {
14842   unformat_input_t *i = vam->input;
14843   vl_api_delete_subif_t *mp;
14844   f64 timeout;
14845   u32 sw_if_index = ~0;
14846
14847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14848     {
14849       if (unformat (i, "sw_if_index %d", &sw_if_index))
14850         ;
14851       else
14852         break;
14853     }
14854
14855   if (sw_if_index == ~0)
14856     {
14857       errmsg ("missing sw_if_index\n");
14858       return -99;
14859     }
14860
14861   /* Construct the API message */
14862   M (DELETE_SUBIF, delete_subif);
14863   mp->sw_if_index = ntohl (sw_if_index);
14864
14865   S;
14866   W;
14867 }
14868
14869 static int
14870 q_or_quit (vat_main_t * vam)
14871 {
14872   longjmp (vam->jump_buf, 1);
14873   return 0;                     /* not so much */
14874 }
14875
14876 static int
14877 q (vat_main_t * vam)
14878 {
14879   return q_or_quit (vam);
14880 }
14881
14882 static int
14883 quit (vat_main_t * vam)
14884 {
14885   return q_or_quit (vam);
14886 }
14887
14888 static int
14889 comment (vat_main_t * vam)
14890 {
14891   return 0;
14892 }
14893
14894 static int
14895 cmd_cmp (void *a1, void *a2)
14896 {
14897   u8 **c1 = a1;
14898   u8 **c2 = a2;
14899
14900   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
14901 }
14902
14903 static int
14904 help (vat_main_t * vam)
14905 {
14906   u8 **cmds = 0;
14907   u8 *name = 0;
14908   hash_pair_t *p;
14909   unformat_input_t *i = vam->input;
14910   int j;
14911
14912   if (unformat (i, "%s", &name))
14913     {
14914       uword *hs;
14915
14916       vec_add1 (name, 0);
14917
14918       hs = hash_get_mem (vam->help_by_name, name);
14919       if (hs)
14920         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
14921       else
14922         fformat (vam->ofp, "No such msg / command '%s'\n", name);
14923       vec_free (name);
14924       return 0;
14925     }
14926
14927   fformat (vam->ofp, "Help is available for the following:\n");
14928
14929     /* *INDENT-OFF* */
14930     hash_foreach_pair (p, vam->function_by_name,
14931     ({
14932       vec_add1 (cmds, (u8 *)(p->key));
14933     }));
14934     /* *INDENT-ON* */
14935
14936   vec_sort_with_function (cmds, cmd_cmp);
14937
14938   for (j = 0; j < vec_len (cmds); j++)
14939     fformat (vam->ofp, "%s\n", cmds[j]);
14940
14941   vec_free (cmds);
14942   return 0;
14943 }
14944
14945 static int
14946 set (vat_main_t * vam)
14947 {
14948   u8 *name = 0, *value = 0;
14949   unformat_input_t *i = vam->input;
14950
14951   if (unformat (i, "%s", &name))
14952     {
14953       /* The input buffer is a vector, not a string. */
14954       value = vec_dup (i->buffer);
14955       vec_delete (value, i->index, 0);
14956       /* Almost certainly has a trailing newline */
14957       if (value[vec_len (value) - 1] == '\n')
14958         value[vec_len (value) - 1] = 0;
14959       /* Make sure it's a proper string, one way or the other */
14960       vec_add1 (value, 0);
14961       (void) clib_macro_set_value (&vam->macro_main,
14962                                    (char *) name, (char *) value);
14963     }
14964   else
14965     errmsg ("usage: set <name> <value>\n");
14966
14967   vec_free (name);
14968   vec_free (value);
14969   return 0;
14970 }
14971
14972 static int
14973 unset (vat_main_t * vam)
14974 {
14975   u8 *name = 0;
14976
14977   if (unformat (vam->input, "%s", &name))
14978     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
14979       errmsg ("unset: %s wasn't set\n", name);
14980   vec_free (name);
14981   return 0;
14982 }
14983
14984 typedef struct
14985 {
14986   u8 *name;
14987   u8 *value;
14988 } macro_sort_t;
14989
14990
14991 static int
14992 macro_sort_cmp (void *a1, void *a2)
14993 {
14994   macro_sort_t *s1 = a1;
14995   macro_sort_t *s2 = a2;
14996
14997   return strcmp ((char *) (s1->name), (char *) (s2->name));
14998 }
14999
15000 static int
15001 dump_macro_table (vat_main_t * vam)
15002 {
15003   macro_sort_t *sort_me = 0, *sm;
15004   int i;
15005   hash_pair_t *p;
15006
15007     /* *INDENT-OFF* */
15008     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15009     ({
15010       vec_add2 (sort_me, sm, 1);
15011       sm->name = (u8 *)(p->key);
15012       sm->value = (u8 *) (p->value[0]);
15013     }));
15014     /* *INDENT-ON* */
15015
15016   vec_sort_with_function (sort_me, macro_sort_cmp);
15017
15018   if (vec_len (sort_me))
15019     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15020   else
15021     fformat (vam->ofp, "The macro table is empty...\n");
15022
15023   for (i = 0; i < vec_len (sort_me); i++)
15024     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15025   return 0;
15026 }
15027
15028 static int
15029 dump_node_table (vat_main_t * vam)
15030 {
15031   int i, j;
15032   vlib_node_t *node, *next_node;
15033
15034   if (vec_len (vam->graph_nodes) == 0)
15035     {
15036       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15037       return 0;
15038     }
15039
15040   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15041     {
15042       node = vam->graph_nodes[i];
15043       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15044       for (j = 0; j < vec_len (node->next_nodes); j++)
15045         {
15046           if (node->next_nodes[j] != ~0)
15047             {
15048               next_node = vam->graph_nodes[node->next_nodes[j]];
15049               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15050             }
15051         }
15052     }
15053   return 0;
15054 }
15055
15056 static int
15057 search_node_table (vat_main_t * vam)
15058 {
15059   unformat_input_t *line_input = vam->input;
15060   u8 *node_to_find;
15061   int j;
15062   vlib_node_t *node, *next_node;
15063   uword *p;
15064
15065   if (vam->graph_node_index_by_name == 0)
15066     {
15067       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15068       return 0;
15069     }
15070
15071   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15072     {
15073       if (unformat (line_input, "%s", &node_to_find))
15074         {
15075           vec_add1 (node_to_find, 0);
15076           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15077           if (p == 0)
15078             {
15079               fformat (vam->ofp, "%s not found...\n", node_to_find);
15080               goto out;
15081             }
15082           node = vam->graph_nodes[p[0]];
15083           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15084           for (j = 0; j < vec_len (node->next_nodes); j++)
15085             {
15086               if (node->next_nodes[j] != ~0)
15087                 {
15088                   next_node = vam->graph_nodes[node->next_nodes[j]];
15089                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15090                 }
15091             }
15092         }
15093
15094       else
15095         {
15096           clib_warning ("parse error '%U'", format_unformat_error,
15097                         line_input);
15098           return -99;
15099         }
15100
15101     out:
15102       vec_free (node_to_find);
15103
15104     }
15105
15106   return 0;
15107 }
15108
15109
15110 static int
15111 script (vat_main_t * vam)
15112 {
15113   u8 *s = 0;
15114   char *save_current_file;
15115   unformat_input_t save_input;
15116   jmp_buf save_jump_buf;
15117   u32 save_line_number;
15118
15119   FILE *new_fp, *save_ifp;
15120
15121   if (unformat (vam->input, "%s", &s))
15122     {
15123       new_fp = fopen ((char *) s, "r");
15124       if (new_fp == 0)
15125         {
15126           errmsg ("Couldn't open script file %s\n", s);
15127           vec_free (s);
15128           return -99;
15129         }
15130     }
15131   else
15132     {
15133       errmsg ("Missing script name\n");
15134       return -99;
15135     }
15136
15137   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15138   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15139   save_ifp = vam->ifp;
15140   save_line_number = vam->input_line_number;
15141   save_current_file = (char *) vam->current_file;
15142
15143   vam->input_line_number = 0;
15144   vam->ifp = new_fp;
15145   vam->current_file = s;
15146   do_one_file (vam);
15147
15148   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15149   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15150   vam->ifp = save_ifp;
15151   vam->input_line_number = save_line_number;
15152   vam->current_file = (u8 *) save_current_file;
15153   vec_free (s);
15154
15155   return 0;
15156 }
15157
15158 static int
15159 echo (vat_main_t * vam)
15160 {
15161   fformat (vam->ofp, "%v", vam->input->buffer);
15162   return 0;
15163 }
15164
15165 /* List of API message constructors, CLI names map to api_xxx */
15166 #define foreach_vpe_api_msg                                             \
15167 _(create_loopback,"[mac <mac-addr>]")                                   \
15168 _(sw_interface_dump,"")                                                 \
15169 _(sw_interface_set_flags,                                               \
15170   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15171 _(sw_interface_add_del_address,                                         \
15172   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15173 _(sw_interface_set_table,                                               \
15174   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15175 _(sw_interface_set_vpath,                                               \
15176   "<intfc> | sw_if_index <id> enable | disable")                        \
15177 _(sw_interface_set_l2_xconnect,                                         \
15178   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15179   "enable | disable")                                                   \
15180 _(sw_interface_set_l2_bridge,                                           \
15181   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15182   "[shg <split-horizon-group>] [bvi]\n"                                 \
15183   "enable | disable")                                                   \
15184 _(bridge_domain_add_del,                                                \
15185   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15186 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15187 _(l2fib_add_del,                                                        \
15188   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15189 _(l2_flags,                                                             \
15190   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15191 _(bridge_flags,                                                         \
15192   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15193 _(tap_connect,                                                          \
15194   "tapname <name> mac <mac-addr> | random-mac")                         \
15195 _(tap_modify,                                                           \
15196   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15197 _(tap_delete,                                                           \
15198   "<vpp-if-name> | sw_if_index <id>")                                   \
15199 _(sw_interface_tap_dump, "")                                            \
15200 _(ip_add_del_route,                                                     \
15201   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15202   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15203   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15204   "[multipath] [count <n>]")                                            \
15205 _(proxy_arp_add_del,                                                    \
15206   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15207 _(proxy_arp_intfc_enable_disable,                                       \
15208   "<intfc> | sw_if_index <id> enable | disable")                        \
15209 _(mpls_add_del_encap,                                                   \
15210   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15211 _(mpls_add_del_decap,                                                   \
15212   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15213 _(mpls_gre_add_del_tunnel,                                              \
15214   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15215   "adj <ip4-address>/<mask-width> [del]")                               \
15216 _(sw_interface_set_unnumbered,                                          \
15217   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15218 _(ip_neighbor_add_del,                                                  \
15219   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15220   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15221 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15222 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15223 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15224   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15225   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15226   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15227 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15228 _(reset_fib, "vrf <n> [ipv6]")                                          \
15229 _(dhcp_proxy_config,                                                    \
15230   "svr <v46-address> src <v46-address>\n"                               \
15231    "insert-cid <n> [del]")                                              \
15232 _(dhcp_proxy_config_2,                                                  \
15233   "svr <v46-address> src <v46-address>\n"                               \
15234    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15235 _(dhcp_proxy_set_vss,                                                   \
15236   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15237 _(dhcp_client_config,                                                   \
15238   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15239 _(set_ip_flow_hash,                                                     \
15240   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15241 _(sw_interface_ip6_enable_disable,                                      \
15242   "<intfc> | sw_if_index <id> enable | disable")                        \
15243 _(sw_interface_ip6_set_link_local_address,                              \
15244   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15245 _(sw_interface_ip6nd_ra_prefix,                                         \
15246   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15247   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15248   "[nolink] [isno]")                                                    \
15249 _(sw_interface_ip6nd_ra_config,                                         \
15250   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15251   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15252   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15253 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15254 _(l2_patch_add_del,                                                     \
15255   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15256   "enable | disable")                                                   \
15257 _(mpls_ethernet_add_del_tunnel,                                         \
15258   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15259   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15260 _(mpls_ethernet_add_del_tunnel_2,                                       \
15261   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15262   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15263 _(sr_tunnel_add_del,                                                    \
15264   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15265   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15266   "[policy <policy_name>]")                                             \
15267 _(sr_policy_add_del,                                                    \
15268   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15269 _(sr_multicast_map_add_del,                                             \
15270   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15271 _(classify_add_del_table,                                               \
15272   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15273   "[del] mask <mask-value>\n"                                           \
15274   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15275 _(classify_add_del_session,                                             \
15276   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15277   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15278   "  [l3 [ip4|ip6]]")                                                   \
15279 _(classify_set_interface_ip_table,                                      \
15280   "<intfc> | sw_if_index <nn> table <nn>")                              \
15281 _(classify_set_interface_l2_tables,                                     \
15282   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15283   "  [other-table <nn>]")                                               \
15284 _(get_node_index, "node <node-name")                                    \
15285 _(add_node_next, "node <node-name> next <next-node-name>")              \
15286 _(l2tpv3_create_tunnel,                                                 \
15287   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15288   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15289   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15290 _(l2tpv3_set_tunnel_cookies,                                            \
15291   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15292   "[new_remote_cookie <nn>]\n")                                         \
15293 _(l2tpv3_interface_enable_disable,                                      \
15294   "<intfc> | sw_if_index <nn> enable | disable")                        \
15295 _(l2tpv3_set_lookup_key,                                                \
15296   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15297 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15298 _(vxlan_add_del_tunnel,                                                 \
15299   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15300   " [decap-next l2|ip4|ip6] [del]")                                     \
15301 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15302 _(gre_add_del_tunnel,                                                   \
15303   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
15304 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15305 _(l2_fib_clear_table, "")                                               \
15306 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15307 _(l2_interface_vlan_tag_rewrite,                                        \
15308   "<intfc> | sw_if_index <nn> \n"                                       \
15309   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15310   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15311 _(create_vhost_user_if,                                                 \
15312         "socket <filename> [server] [renumber <dev_instance>] "         \
15313         "[mac <mac_address>]")                                          \
15314 _(modify_vhost_user_if,                                                 \
15315         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15316         "[server] [renumber <dev_instance>]")                           \
15317 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15318 _(sw_interface_vhost_user_dump, "")                                     \
15319 _(show_version, "")                                                     \
15320 _(vxlan_gpe_add_del_tunnel,                                             \
15321   "local <addr> remote <addr> vni <nn>\n"                               \
15322     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15323   "[next-ethernet] [next-nsh]\n")                                       \
15324 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15325 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15326 _(interface_name_renumber,                                              \
15327   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15328 _(input_acl_set_interface,                                              \
15329   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15330   "  [l2-table <nn>] [del]")                                            \
15331 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15332 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
15333 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15334 _(ip_dump, "ipv4 | ipv6")                                               \
15335 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15336 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15337   "  spid_id <n> ")                                                     \
15338 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15339   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15340   "  integ_alg <alg> integ_key <hex>")                                  \
15341 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15342   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15343   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15344   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15345 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15346 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15347 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15348   "(auth_data 0x<data> | auth_data <data>)")                            \
15349 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15350   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15351 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15352   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15353   "(local|remote)")                                                     \
15354 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15355 _(delete_loopback,"sw_if_index <nn>")                                   \
15356 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15357 _(map_add_domain,                                                       \
15358   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
15359   "ip6-src <ip6addr> "                                                  \
15360   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
15361 _(map_del_domain, "index <n>")                                          \
15362 _(map_add_del_rule,                                                     \
15363   "index <n> psid <n> dst <ip6addr> [del]")                             \
15364 _(map_domain_dump, "")                                                  \
15365 _(map_rule_dump, "index <map-domain>")                                  \
15366 _(want_interface_events,  "enable|disable")                             \
15367 _(want_stats,"enable|disable")                                          \
15368 _(get_first_msg_id, "client <name>")                                    \
15369 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15370 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15371   "fib-id <nn> [ip4][ip6][default]")                                    \
15372 _(get_node_graph, " ")                                                  \
15373 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15374 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
15375 _(ioam_disable, "")                                                \
15376 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
15377                             " sw_if_index <sw_if_index> p <priority> "  \
15378                             "w <weight>] [del]")                        \
15379 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
15380                         "iface <intf> | sw_if_index <sw_if_index> "     \
15381                         "p <priority> w <weight> [del]")                \
15382 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
15383                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
15384                           "locator-set <locator_name> [del]")           \
15385 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
15386   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
15387 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
15388 _(lisp_gpe_enable_disable, "enable|disable")                            \
15389 _(lisp_enable_disable, "enable|disable")                                \
15390 _(lisp_gpe_add_del_iface, "up|down")                                    \
15391 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
15392                                "[seid <seid>] "                         \
15393                                "rloc <locator> p <prio> "               \
15394                                "w <weight> [rloc <loc> ... ] "          \
15395                                "action <action> [del-all]")             \
15396 _(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid "     \
15397                           "<src-eid> rloc <locator> p <prio> w <weight>"\
15398                           "[rloc <loc> ... ] action <action>")          \
15399 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
15400 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
15401 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
15402 _(lisp_locator_set_dump, "[local | remote]")                            \
15403 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
15404 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
15405                        "[local] | [remote]")                            \
15406 _(lisp_eid_table_vni_dump, "")                                          \
15407 _(lisp_eid_table_map_dump, "l2|l3")                                     \
15408 _(lisp_gpe_tunnel_dump, "")                                             \
15409 _(lisp_map_resolver_dump, "")                                           \
15410 _(show_lisp_status, "")                                                 \
15411 _(lisp_get_map_request_itr_rlocs, "")                                   \
15412 _(show_lisp_pitr, "")                                                   \
15413 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15414 _(af_packet_delete, "name <host interface name>")                       \
15415 _(policer_add_del, "name <policer name> <params> [del]")                \
15416 _(policer_dump, "[name <policer name>]")                                \
15417 _(policer_classify_set_interface,                                       \
15418   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15419   "  [l2-table <nn>] [del]")                                            \
15420 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15421 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
15422     "[master|slave]")                                                   \
15423 _(netmap_delete, "name <interface name>")                               \
15424 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15425 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15426 _(mpls_fib_encap_dump, "")                                              \
15427 _(mpls_fib_decap_dump, "")                                              \
15428 _(classify_table_ids, "")                                               \
15429 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15430 _(classify_table_info, "table_id <nn>")                                 \
15431 _(classify_session_dump, "table_id <nn>")                               \
15432 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
15433     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
15434     "[template_interval <nn>] [udp_checksum]")                          \
15435 _(ipfix_exporter_dump, "")                                              \
15436 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
15437 _(ipfix_classify_stream_dump, "")                                       \
15438 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
15439 _(ipfix_classify_table_dump, "")                                        \
15440 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15441 _(pg_create_interface, "if_id <nn>")                                    \
15442 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15443 _(pg_enable_disable, "[stream <id>] disable")                           \
15444 _(ip_source_and_port_range_check_add_del,                               \
15445   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15446 _(ip_source_and_port_range_check_interface_add_del,                     \
15447   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15448   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
15449 _(ipsec_gre_add_del_tunnel,                                             \
15450   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
15451 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
15452 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")
15453
15454 /* List of command functions, CLI names map directly to functions */
15455 #define foreach_cli_function                                    \
15456 _(comment, "usage: comment <ignore-rest-of-line>")              \
15457 _(dump_interface_table, "usage: dump_interface_table")          \
15458 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15459 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15460 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15461 _(dump_stats_table, "usage: dump_stats_table")                  \
15462 _(dump_macro_table, "usage: dump_macro_table ")                 \
15463 _(dump_node_table, "usage: dump_node_table")                    \
15464 _(echo, "usage: echo <message>")                                \
15465 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15466 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
15467 _(help, "usage: help")                                          \
15468 _(q, "usage: quit")                                             \
15469 _(quit, "usage: quit")                                          \
15470 _(search_node_table, "usage: search_node_table <name>...")      \
15471 _(set, "usage: set <variable-name> <value>")                    \
15472 _(script, "usage: script <file-name>")                          \
15473 _(unset, "usage: unset <variable-name>")
15474
15475 #define _(N,n)                                  \
15476     static void vl_api_##n##_t_handler_uni      \
15477     (vl_api_##n##_t * mp)                       \
15478     {                                           \
15479         vat_main_t * vam = &vat_main;           \
15480         if (vam->json_output) {                 \
15481             vl_api_##n##_t_handler_json(mp);    \
15482         } else {                                \
15483             vl_api_##n##_t_handler(mp);         \
15484         }                                       \
15485     }
15486 foreach_vpe_api_reply_msg;
15487 #undef _
15488
15489 void
15490 vat_api_hookup (vat_main_t * vam)
15491 {
15492 #define _(N,n)                                                  \
15493     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15494                            vl_api_##n##_t_handler_uni,          \
15495                            vl_noop_handler,                     \
15496                            vl_api_##n##_t_endian,               \
15497                            vl_api_##n##_t_print,                \
15498                            sizeof(vl_api_##n##_t), 1);
15499   foreach_vpe_api_reply_msg;
15500 #undef _
15501
15502   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
15503
15504   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15505
15506   vam->function_by_name = hash_create_string (0, sizeof (uword));
15507
15508   vam->help_by_name = hash_create_string (0, sizeof (uword));
15509
15510   /* API messages we can send */
15511 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15512   foreach_vpe_api_msg;
15513 #undef _
15514
15515   /* Help strings */
15516 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15517   foreach_vpe_api_msg;
15518 #undef _
15519
15520   /* CLI functions */
15521 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15522   foreach_cli_function;
15523 #undef _
15524
15525   /* Help strings */
15526 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15527   foreach_cli_function;
15528 #undef _
15529 }
15530
15531 #undef vl_api_version
15532 #define vl_api_version(n,v) static u32 vpe_api_version = v;
15533 #include <vpp-api/vpe.api.h>
15534 #undef vl_api_version
15535
15536 void
15537 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
15538 {
15539   /*
15540    * Send the main API signature in slot 0. This bit of code must
15541    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
15542    */
15543   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
15544 }
15545
15546 /*
15547  * fd.io coding-style-patch-verification: ON
15548  *
15549  * Local Variables:
15550  * eval: (c-set-style "gnu")
15551  * End:
15552  */