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